小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

分布式與集群的區(qū)別

 niefeng2011 2014-01-19
  • 222013-10

    簡單說,分布式是以縮短單個任務(wù)的執(zhí)行時間來提升效率的,而集群則是通過提高單位時間內(nèi)執(zhí)行的任務(wù)數(shù)來提升效率。

    例如:

    如果一個任務(wù)由10個子任務(wù)組成,每個子任務(wù)單獨執(zhí)行需1小時,則在一臺服務(wù)器上執(zhí)行改任務(wù)需10小時。

    采用分布式方案,提供10臺服務(wù)器,每臺服務(wù)器只負責處理一個子任務(wù),不考慮子任務(wù)間的依賴關(guān)系,執(zhí)行完這個任務(wù)只需一個小時。(這種工作模式的一個典型代表就是Hadoop的Map/Reduce分布式計算模型)

    而采用集群方案,同樣提供10臺服務(wù)器,每臺服務(wù)器都能獨立處理這個任務(wù)。假設(shè)有10個任務(wù)同時到達,10個服務(wù)器將同時工作,10小后,10個任務(wù)同時完成,這樣,整身來看,還是1小時內(nèi)完成一個任務(wù)!

     

    以下是摘抄自網(wǎng)絡(luò)文章:

    集群概念

    1. 兩大關(guān)鍵特性 
    集群是一組協(xié)同工作的服務(wù)實體,用以提供比單一服務(wù)實體更具擴展性與可用性的服務(wù)平臺。在客戶端看來,一個集群就象是一個服務(wù)實體,但事實上集群由一組服務(wù)實體組成。與單一服務(wù)實體相比較,集群提供了以下兩個關(guān)鍵特性:

    ·  可擴展性--集群的性能不限于單一的服務(wù)實體,新的服務(wù)實體可以動態(tài)地加入到集群,從而增強集群的性能。

    ·  高可用性--集群通過服務(wù)實體冗余使客戶端免于輕易遇到out of service的警告。在集群中,同樣的服務(wù)可以由多個服務(wù)實體提供。如果一個服務(wù)實體失敗了,另一個服務(wù)實體會接管失敗的服務(wù)實體。集群提供的從一個出 錯的服務(wù)實體恢復(fù)到另一個服務(wù)實體的功能增強了應(yīng)用的可用性。

    2. 兩大能力 
    為了具有可擴展性和高可用性特點,集群的必須具備以下兩大能力:

    ·  負載均衡--負載均衡能把任務(wù)比較均衡地分布到集群環(huán)境下的計算和網(wǎng)絡(luò)資源。

    ·  錯誤恢復(fù)--由于某種原因,執(zhí)行某個任務(wù)的資源出現(xiàn)故障,另一服務(wù)實體中執(zhí)行同一任務(wù)的資源接著完成任務(wù)。這種由于一個實體中的資源不能工作,另一個實體中的資源透明的繼續(xù)完成任務(wù)的過程叫錯誤恢復(fù)。

    負載均衡和錯誤恢復(fù)都要求各服務(wù)實體中有執(zhí)行同一任務(wù)的資源存在,而且對于同一任務(wù)的各個資源來說,執(zhí)行任務(wù)所需的信息視圖(信息上下文)必須是一樣的。

    3. 兩大技術(shù) 
    實現(xiàn)集群務(wù)必要有以下兩大技術(shù):

    ·  集群地址--集群由多個服務(wù)實體組成,集群客戶端通過訪問集群的集群地址獲取集群內(nèi)部各服務(wù)實體的功能。具有單一集群地址(也叫單一影像)是集群的一個基 本特征。維護集群地址的設(shè)置被稱為負載均衡器。負載均衡器內(nèi)部負責管理各個服務(wù)實體的加入和退出,外部負責集群地址向內(nèi)部服務(wù)實體地址的轉(zhuǎn)換。有的負載均 衡器實現(xiàn)真正的負載均衡算法,有的只支持任務(wù)的轉(zhuǎn)換。只實現(xiàn)任務(wù)轉(zhuǎn)換的負載均衡器適用于支持ACTIVE-STANDBY的集群環(huán)境,在那里,集群中只有 一個服務(wù)實體工作,當正在工作的服務(wù)實體發(fā)生故障時,負載均衡器把后來的任務(wù)轉(zhuǎn)向另外一個服務(wù)實體。

    ·  內(nèi)部通信--為了能協(xié)同工作、實現(xiàn)負載均衡和錯誤恢復(fù),集群各實體間必須時常通信,比如負載均衡器對服務(wù)實體心跳測試信息、服務(wù)實體間任務(wù)執(zhí)行上下文信息的通信。

    具有同一個集群地址使得客戶端能訪問集群提供的計算服務(wù),一個集群地址下隱藏了各個服務(wù)實體的內(nèi)部地址,使得客戶要求的計算服務(wù)能在各個服務(wù)實體之間分布。內(nèi)部通信是集群能正常運轉(zhuǎn)的基礎(chǔ),它使得集群具有均衡負載和錯誤恢復(fù)的能力。

    集群分類

    Linux集群主要分成三大類( 高可用集群, 負載均衡集群,科學計算集群)

    高可用集群( High Availability Cluster)
    負載均衡集群(Load Balance Cluster)
    科學計算集群(High Performance Computing Cluster)
    ================================================

    具體包括:

    Linux High Availability 高可用集群                                       
    (普通兩節(jié)點雙機熱備,多節(jié)點HA集群,RAC, shared, share-nothing集群等)

    Linux Load Balance 負載均衡集群                                      
     (LVS等....)

    Linux High Performance Computing 高性能科學計算集群     
     (Beowulf 類集群....)

    分布式存儲                                                                         
    其他類linux集群              
    (如Openmosix, rendering farm 等..)

    詳細介紹

    1. 高可用集群(High Availability Cluster)
    常見的就是2個節(jié)點做成的HA集群,有很多通俗的不科學的名稱,比如"雙機熱備", "雙機互備", "雙機".
    高可用集群解決的是保障用戶的應(yīng)用程序持續(xù)對外提供服務(wù)的能力。 (請注意高可用集群既不是用來保護業(yè)務(wù)數(shù)據(jù)的,保護的是用戶的業(yè)務(wù)程序?qū)ν獠婚g斷提供服務(wù),把因軟件/硬件/人為造成的故障對業(yè)務(wù)的影響降低到最小程度)。

    2. 負載均衡集群(Load Balance Cluster)

    負載均衡系統(tǒng):集群中所有的節(jié)點都處于活動狀態(tài),它們分攤系統(tǒng)的工作負載。一般Web服務(wù)器集群、數(shù)據(jù)庫集群和應(yīng)用服務(wù)器集群都屬于這種類型。

    負載均衡集群一般用于相應(yīng)網(wǎng)絡(luò)請求的網(wǎng)頁服務(wù)器,數(shù)據(jù)庫服務(wù)器。這種集群可以在接到請求時,檢查接受請求較少,不繁忙的服務(wù)器,并把請求轉(zhuǎn)到這些服務(wù)器上。從檢查其他服務(wù)器狀態(tài)這一點上看,負載均衡和容錯集群很接近,不同之處是數(shù)量上更多。

    3. 科學計算集群(High Performance Computing Cluster)

    高性能計算(High Perfermance Computing)集群,簡稱HPC集群。這類集群致力于提供單個計算機所不能提供的強大的計算能力。

    高性能計算分類  
     高吞吐計算(High-throughput Computing)
      有一類高性能計算,可以把它分成若干可以并行的子任務(wù),而且各個子任務(wù)彼此間沒有什么關(guān)聯(lián)。象在家搜尋外星人( SETI@HOME  -- Search for Extraterrestrial Intelligence at Home )就是這一類型應(yīng)用。這一項目是利用Internet上的閑置的計算資源來搜尋外星人。SETI項目的服務(wù)器將一組數(shù)據(jù)和數(shù)據(jù)模式發(fā)給Internet上 參加SETI的計算節(jié)點,計算節(jié)點在給定的數(shù)據(jù)上用給定的模式進行搜索,然后將搜索的結(jié)果發(fā)給服務(wù)器。服務(wù)器負責將從各個計算節(jié)點返回的數(shù)據(jù)匯集成完整的 數(shù)據(jù)。因為這種類型應(yīng)用的一個共同特征是在海量數(shù)據(jù)上搜索某些模式,所以把這類計算稱為高吞吐計算。所謂的Internet計算都屬于這一類。按照 Flynn的分類,高吞吐計算屬于SIMD(Single Instruction/Multiple Data)的范疇。

     分布計算(Distributed Computing)
      另一類計算剛好和高吞吐計算相反,它們雖然可以給分成若干并行的子任務(wù),但是子任務(wù)間聯(lián)系很緊密,需要大量的數(shù)據(jù)交換。按照Flynn的分類,分布式的高性能計算屬于MIMD(Multiple Instruction/Multiple Data)的范疇。

    4. 分布式(集群)與集群的聯(lián)系與區(qū)別 
    分布式是指將不同的業(yè)務(wù)分布在不同的地方。 
    而集群指的是將幾臺服務(wù)器集中在一起,實現(xiàn)同一業(yè)務(wù)。 
    分布式中的每一個節(jié)點,都可以做集群。 
    而集群并不一定就是分布式的。 
    舉例:就比如新浪網(wǎng),訪問的人多了,他可以做一個群集,前面放一個響應(yīng)服務(wù)器,后面幾臺服務(wù)器完成同一業(yè)務(wù),如果有業(yè)務(wù)訪問的時候,響應(yīng)服務(wù)器看哪臺服務(wù)器的負載不是很重,就將給哪一臺去完成。 
    而分布式,從窄意上理解,也跟集群差不多, 但是它的組織比較松散,不像集群,有一個組織性,一臺服務(wù)器垮了,其它的服務(wù)器可以頂上來。 
    分布式的每一個節(jié)點,都完成不同的業(yè)務(wù),一個節(jié)點垮了,哪這個業(yè)務(wù)就不可訪問了。

    發(fā)布于 2個月前, 閱讀(16) | 評論(0) | 投票(0) | 收藏(0) 閱讀全文...
  • 162013-10

    一致性hash和solr千萬級數(shù)據(jù)分布式搜索引擎中的應(yīng)用

    互聯(lián)網(wǎng)創(chuàng)業(yè)中大部分人都是草根創(chuàng)業(yè),這個時候沒有強勁的服務(wù)器,也沒有錢去買很昂貴的海量數(shù)據(jù)庫。在這樣嚴峻的條件下,一批又一批的創(chuàng)業(yè)者從創(chuàng)業(yè)中獲得成功,這個和當前的開源技術(shù)、海量數(shù)據(jù)架構(gòu)有著必不可分的關(guān)系。比如我們使用mysql、nginx等開源軟件,通過架構(gòu)和低成本服務(wù)器也可以搭建千萬級用戶訪問量的系統(tǒng)。新浪微博、淘寶網(wǎng)、騰訊等大型互聯(lián)網(wǎng)公司都使用了很多開源免費系統(tǒng)搭建了他們的平臺。所以,用什么沒關(guān)系,只要能夠在合理的情況下采用合理的解決方案。

    那怎么搭建一個好的系統(tǒng)架構(gòu)呢?這個話題太大,這里主要說一下數(shù)據(jù)分流的方式。比如我們的數(shù)據(jù)庫服務(wù)器只能存儲200個數(shù)據(jù),突然要搞一個活動預(yù)估達到600個數(shù)據(jù)。
    可以采用兩種方式:橫向擴展或者縱向擴展。
    縱向擴展是升級服務(wù)器的硬件資源。但是隨著機器的性能配置越高,價格越高,這個代價對于一般的小公司是承擔不起的。
    橫向擴展是采用多個廉價的機器提供服務(wù)。這樣一個機器只能處理200個數(shù)據(jù)、3個機器就可以處理600個數(shù)據(jù)了,如果以后業(yè)務(wù)量增加還可以快速配置增加。在大多數(shù)情況都選擇橫向擴展的方式。如下圖:
    圖1

    圖2

    現(xiàn)在有個問題了,這600個數(shù)據(jù)如何路由到對應(yīng)的機器。需要考慮如果均衡分配,假設(shè)我們600個數(shù)據(jù)都是統(tǒng)一的自增id數(shù)據(jù),從1~600,分成3堆可以采用 id mod 3的方式。其實在真實環(huán)境可能不是這種id是字符串。需要把字符串轉(zhuǎn)變?yōu)閔ashcode再進行取模。

    目前看起來是不是解決我們的問題了,所有數(shù)據(jù)都很好的分發(fā)并且沒有達到系統(tǒng)的負載。但如果我們的數(shù)據(jù)需要存儲、需要讀取就沒有這么容易了。業(yè)務(wù)增多怎么辦,大家按照上面的橫向擴展知道需要增加一臺服務(wù)器。但是就是因為增加這一臺服務(wù)器帶來了一些問題??聪旅孢@個例子,一共9個數(shù),需要放到2臺機器(1、2)上。各個機器存放為:1號機器存放1、3、5、7、9 ,2號機器存放 2、4、6、8。如果擴展一臺機器3如何,數(shù)據(jù)就要發(fā)生大遷移,1號機器存放1、4、7, 2號機器存放2、5、8, 3號機器存放3、6、9。如圖:

    圖3
    從圖中可以看出 1號機器的3、5、9遷移出去了、2好機器的4、6遷移出去了,按照新的秩序再重新分配了一遍。數(shù)據(jù)量小的話重新分配一遍代價并不大,但如果我們擁有上億、上T級的數(shù)據(jù)這個操作成本是相當?shù)母撸賱t幾個小時多則數(shù)天。并且遷移的時候原數(shù)據(jù)庫機器負載比較高,那大家就有疑問了,是不是這種水平擴展的架構(gòu)方式不太合理?

    —————————–華麗分割線—————————————

    一致性hash就是在這種應(yīng)用背景提出來的,現(xiàn)在被廣泛應(yīng)用于分布式緩存,比如memcached。下面簡單介紹下一致性hash的基本原理。最早的版本 http://dl./citation.cfm?id=258660。國內(nèi)網(wǎng)上有很多文章都寫的比較好。如: http://blog.csdn.net/x15594/article/details/6270242

    下面簡單舉個例子來說明一致性hash。

    準備:1、2、3 三臺機器
    還有待分配的9個數(shù) 1、2、3、4、5、6、7、8、9
    一致性hash算法架構(gòu)

    步驟
    一、構(gòu)造出來 2的32次方 個虛擬節(jié)點出來,因為計算機里面是01的世界,進行劃分時采用2的次方數(shù)據(jù)容易分配均衡。另 2的32次方是42億,我們就算有超大量的服務(wù)器也不可能超過42億臺吧,擴展和均衡性都保證了。
    一致性hash
    二、將三臺機器分別取IP進行hashcode計算(這里也可以取hostname,只要能夠唯一區(qū)別各個機器就可以了),然后映射到2的32次方上去。比如1號機器算出來的hashcode并且mod (2^32)為 123(這個是虛構(gòu)的),2號機器算出來的值為 2300420,3號機器算出來為 90203920。這樣三臺機器就映射到了這個虛擬的42億環(huán)形結(jié)構(gòu)的節(jié)點上了。
    圖5
    三、將數(shù)據(jù)(1-9)也用同樣的方法算出hashcode并對42億取模將其配置到環(huán)形節(jié)點上。假設(shè)這幾個節(jié)點算出來的值為 1:10,2:23564,3:57,4:6984,5:5689632,6:86546845,7:122,8:3300689,9:135468??梢钥闯?1、3、7小于123, 2、4、9 小于 2300420 大于 123, 5、6、8 大于 2300420 小于90203920。從數(shù)據(jù)映射到的位置開始順時針查找,將數(shù)據(jù)保存到找到的第一個Cache節(jié)點上。如果超過2^32仍然找不到Cache節(jié)點,就會保存到第一個Cache節(jié)點上。也就是1、3、7將分配到1號機器,2、4、9將分配到2號機器,5、6、8將分配到3號機器。
    圖6
    這個時候大家可能會問,我到現(xiàn)在沒有看見一致性hash帶來任何好處,比傳統(tǒng)的取模還增加了復(fù)雜度?,F(xiàn)在馬上來做一些關(guān)鍵性的處理,比如我們增加一臺機器。按照原來我們需要把所有的數(shù)據(jù)重新分配到四臺機器。一致性hash怎么做呢?現(xiàn)在4號機器加進來,他的hash值算出來取模后是12302012。 5、8 大于2300420 小于12302012 ,6 大于 12302012 小于90203920 。這樣調(diào)整的只是把5、8從3號機器刪除,4號機器中加入 5、6。
    圖7
    同理,刪除機器怎么做呢,假設(shè)2號機器掛掉,受影響的也只是2號機器上的數(shù)據(jù)被遷移到離它節(jié)點,上圖為4號機器。
    圖8
    大家應(yīng)該明白一致性hash的基本原理了吧。不過這種算法還是有缺陷,比如在機器節(jié)點比較少、數(shù)據(jù)量大的時候,數(shù)據(jù)的分布可能不是很均衡,就會導(dǎo)致其中一臺服務(wù)器的數(shù)據(jù)比其他機器多很多。為了解決這個問題,需要引入虛擬服務(wù)器節(jié)點的機制。如我們一共有只有三臺機器,1、2、3。但是實際又不可能有這么多機器怎么解決呢?把 這些機器各自虛擬化出來3臺機器,也就是 1a 1b 1c 2a 2b 2c 3a 3b 3c,這樣就變成了9臺機器。實際 1a 1b 1c 還是對應(yīng)1。但是實際分布到環(huán)形節(jié)點就變成了9臺機器。數(shù)據(jù)分布也就能夠更分散一點。如圖:
    圖91

    寫了這么多一致性hash,這個和分布式搜索有什么半點關(guān)系?我們現(xiàn)在使用solr4搭建了分布式搜索,測試了基于solrcloud的分布式平臺提交20條數(shù)據(jù)居然需要幾十秒,所以就廢棄了solrcloud。采用自己hack solr平臺,不用zookeeper做分布式一致性管理平臺,自己管理數(shù)據(jù)的分發(fā)機制。既然需要自己管理數(shù)據(jù)的分發(fā),就需要考慮到索引的創(chuàng)建,索引的更新。這樣我們的一致性hash也就用上了。整體架構(gòu)如下圖:

    圖10
    建立和更新需要維持機器的位置,能夠根據(jù)數(shù)據(jù)的key找到對應(yīng)的數(shù)據(jù)分發(fā)并更新。這里需要考慮的是如何高效、可靠的把數(shù)據(jù)建立、更新到索引里。
    備份服務(wù)器防止建立服務(wù)器掛掉,可以根據(jù)備份服務(wù)器快速恢復(fù)。
    讀服務(wù)器主要做讀寫分離使用,防止寫索引影響查詢數(shù)據(jù)。
    集群管理服務(wù)器管理整個集群內(nèi)的服務(wù)器狀態(tài)、告警。

    整個集群隨著業(yè)務(wù)增多還可以按照數(shù)據(jù)的類型劃分,比如用戶、微博等。每個類型按照上圖架構(gòu)搭建,就可以滿足一般性能的分布式搜索。對于solr和分布式搜索的話題后續(xù)再聊。

    擴展閱讀:
    java的hashmap隨著數(shù)據(jù)量的增加也會出現(xiàn)map調(diào)整的問題,必要的時候就初始化足夠大的size以防止容量不足對已有數(shù)據(jù)進行重新hash計算。

    疫苗:Java HashMap的死循環(huán) http:///articles/9606.html
    一致性哈希算法的優(yōu)化—-關(guān)于如何保正在環(huán)中增加新節(jié)點時,命中率不受影響 (原拍拍同事scott)http://scottina./blog/650380

    語言實現(xiàn):
    http://weblogs./blog/2007/11/27/consistent-hashing java 版本的例子
    http://blog.csdn.net/mayongzhan/archive/2009/06/25/4298834.aspx PHP 版的例子
    http://www./KB/recipes/lib-conhash.aspx C語言版本例子

    發(fā)布于 3個月前, 閱讀(150) | 評論(1) | 投票(0) | 收藏(21) 閱讀全文...
  • 162013-10

    1)首先在${tomcat目錄}/conf/Catalina/localhost 創(chuàng)建兩個solr的配置文件。

       可以命名為solr.xml(主服務(wù)器配置)內(nèi)容為:

     <Context docBase="F:/apache-solr-1.4.0/dist/apache-solr-1.4.0.war" reloadable="true" >  
         <Environment name="solr/home" type="java.lang.String" value="F:/apache-solr-1.4.0/example/solr" override="true" />  
     </Context> 

    slaver_solr.xml (從服務(wù)器配置)內(nèi)容為:

     <Context docBase="F:/apache-solr-1.4.0/dist/apache-solr-1.4.0.war" reloadable="true" >  
         <Environment name="solr/home" type="java.lang.String" value="F:/solr分布式/solr" override="true" />  
     </Context> 

     

    可以看到兩個配置所引用的后臺管理是同一個目錄的,但這個沒關(guān)系,只要solr/home的不一樣就行了,接著看主從服務(wù)器上solr/home的配置有什么不一樣。主要是在solr/home/conf/solrconfig.xml上配置不一樣的,其它配置可以互相拷貝。

     

    主要不同的地方為如下:

     

    從服務(wù)器的配置

     

    <requestHandler name="/replication" class="solr.ReplicationHandler" >
        <lst name="slave">

    <!--主服務(wù)器的url-->


          <str name="masterUrl">http://localhost:8080/solr/replication</str>

    <!--定時去請求主服務(wù)器,查看索引是否有改變-->
          <str name="pollInterval">00:00:60</str>
        </lst>
    </requestHandler>

     

    主服務(wù)器的配置

     


    <requestHandler name="/replication" class="solr.ReplicationHandler" >
        <lst name="master">
          <str name="replicateAfter">commit</str>
          <str name="replicateAfter">startup</str>
          <str name="confFiles">schema.xml,stopwords.txt</str>
        </lst>

    </requestHandler>

     

    大概這樣的。啟動 tomcat看看吧。。主服務(wù)器建立索引后,從服務(wù)器會請求將索引拷貝到從服務(wù)器中。

    發(fā)布于 3個月前, 閱讀(54) | 評論(0) | 投票(0) | 收藏(0) 閱讀全文...
  • 162013-04
    時間過得很快,來淘寶已經(jīng)兩個月了,在這兩個月的時間里,自己也感受頗深。下面就結(jié)合淘寶目前的一些底層技術(shù)框架以及自己的一些感觸來說說如何構(gòu)建一個可伸縮,高性能,高可用性的分布式互聯(lián)網(wǎng)應(yīng)用。

      一應(yīng)用無狀態(tài)淘寶session框架

      俗話說,一個系統(tǒng)的伸縮性的好壞取決于應(yīng)用的狀態(tài)如何管理。為什么這么說呢?咱們試想一下,假如我們在session中保存了大量與客戶端的狀態(tài)信息的話,那么當保存狀態(tài)信息的server宕機的時候,我們怎么辦?通常來說,我們都是通過集群來解決這個問題,而通常所說的集群,不僅有負載均衡,更重要的是要有失效恢復(fù)failover,比如tomcat采用的集群節(jié)點廣播復(fù)制,jboss采用的配對復(fù)制等session狀態(tài)復(fù)制策略,但是集群中的狀態(tài)恢復(fù)也有其缺點,那就是嚴重影響了系統(tǒng)的伸縮性,系統(tǒng)不能通過增加更多的機器來達到良好的水平伸縮,因為集群節(jié)點間session的通信會隨著節(jié)點的增多而開銷增大,因此要想做到應(yīng)用本身的伸縮性,我們需要保證應(yīng)用的無狀態(tài)性,這樣集群中的各個節(jié)點來說都是相同的,從而是的系統(tǒng)更好的水平伸縮。

      OK,上面說了無狀態(tài)的重要性,那么具體如何實現(xiàn)無狀態(tài)呢?此時一個session框架就會發(fā)揮作用了。幸運的是淘寶已經(jīng)具有了此類框架。淘寶的session框架采用的是client cookie實現(xiàn),主要將狀態(tài)保存到了cookie里面,這樣就使得應(yīng)用節(jié)點本身不需要保存任何狀態(tài)信息,這樣在系統(tǒng)用戶變多的時候,就可以通過增加更多的應(yīng)用節(jié)點來達到水平擴展的目的.但是采用客戶端cookie的方式來保存狀態(tài)也會遇到限制,比如每個cookie一般不能超過4K的大小,同時很多瀏覽器都限制一個站點最多保存20個cookie.淘寶cookie框架采用的是“多值cookie”,就是一個組合鍵對應(yīng)多個cookie的值,這樣不僅可以防止cookie數(shù)量超過20,同時還節(jié)省了cookie存儲有效信息的空間,因為默認每個cookie都會有大約50個字節(jié)的元信息來描述cookie。

      除了淘寶目前的session框架的實現(xiàn)方式以外,其實集中式session管理來完成,說具體點就是多個無狀態(tài)的應(yīng)用節(jié)點連接一個session服務(wù)器,session服務(wù)器將session保存到緩存中,session服務(wù)器后端再配有底層持久性數(shù)據(jù)源,比如數(shù)據(jù)庫,文件系統(tǒng)等等。

      二有效使用緩存Tair

      做互聯(lián)網(wǎng)應(yīng)用的兄弟應(yīng)該都清楚,緩存對于一個互聯(lián)網(wǎng)應(yīng)用是多么的重要,從瀏覽器緩存,反向代理緩存,頁面緩存,局部頁面緩存,對象緩存等等都是緩存應(yīng)用的場景。

      一般來說緩存根據(jù)與應(yīng)用程序的遠近程度不同可以分為:local cache和remote cache。一般系統(tǒng)中要么采用local cache,要么采用remote cache,兩者混合使用的話對于local cache和remote cache的數(shù)據(jù)一致性處理會變大比較麻煩.

      在大部分情況下,我們所說到的緩存都是讀緩存,緩存還有另外一個類型:寫緩存.對于一些讀寫比不高,同時對數(shù)據(jù)安全性需求不高的數(shù)據(jù),我們可以將其緩存起來從而減少對底層數(shù)據(jù)庫的訪問,比如統(tǒng)計商品的訪問次數(shù),統(tǒng)計API的調(diào)用量等等,可以采用先寫內(nèi)存緩存然后延遲持久化到數(shù)據(jù)庫,這樣可以大大減少對數(shù)據(jù)庫的寫壓力。

      OK,我以店鋪線的系統(tǒng)為例,在用戶瀏覽店鋪的時候,比如店鋪介紹,店鋪交流區(qū)頁,店鋪服務(wù)條款頁面,店鋪試衣間頁面,以及店鋪內(nèi)搜索界面這些界面更新不是非常頻繁,因此適合放到緩存中,這樣可以大大減低DB的負載。另外寶貝詳情頁面相對也更新比較少,因此也適合放到緩存中來減低DB負載。

      三應(yīng)用拆分HSF

      首先,在說明應(yīng)用拆分之前,我們先來回顧一下一個系統(tǒng)從小變大的過程中遇到的一些問題,通過這些問題我們會發(fā)現(xiàn)拆分對于構(gòu)建一個大型系統(tǒng)是如何的重要。

      系統(tǒng)剛上線初期,用戶數(shù)并不多,所有的邏輯也許都是放在一個系統(tǒng)中的,所有邏輯跑到一個進程或者一個應(yīng)用當中,這個時候因為比較用戶少,系統(tǒng)訪問量低,因此將全部的邏輯都放在一個應(yīng)用未嘗不可。但是,兄弟們都清楚,好景不長,隨著系統(tǒng)用戶的不斷增加,系統(tǒng)的訪問壓力越來越多,同時隨著系統(tǒng)發(fā)展,為了滿足用戶的需求,原有的系統(tǒng)需要增加新的功能進來,系統(tǒng)變得越來越復(fù)雜的時候,我們會發(fā)現(xiàn)系統(tǒng)變得越來越難維護,難擴展,同時系統(tǒng)伸縮性和可用性也會受到影響。那么這個時候我們?nèi)绾谓鉀Q這些問題呢?明智的辦法就是拆分這也算是一種解耦,我們需要將原來的系統(tǒng)根據(jù)一定的標準,比如業(yè)務(wù)相關(guān)性等分為不同的子系統(tǒng),不同的系統(tǒng)負責不同的功能,這樣切分以后,我們可以對單獨的子系統(tǒng)進行擴展和維護,從而提高系統(tǒng)的擴展性和可維護性,同時我們系統(tǒng)的水平伸縮性scale out大大的提升了,因為我們可以有針對性的對壓力大的子系統(tǒng)進行水平擴展而不會影響到其它的子系統(tǒng),而不會像拆分以前,每次系統(tǒng)壓力變大的時候,我們都需要對整個大系統(tǒng)進行伸縮,而這樣的成本是比較大的,另外經(jīng)過切分,子系統(tǒng)與子系統(tǒng)之間的耦合減低了,當某個子系統(tǒng)暫時不可用的時候,整體系統(tǒng)還是可用的,從而整體系統(tǒng)的可用性也大大增強了。

      因此一個大型的互聯(lián)網(wǎng)應(yīng)用,肯定是要經(jīng)過拆分,因為只有拆分了,系統(tǒng)的擴展性,維護性,伸縮性,可用性才會變的更好。但是拆分也給系統(tǒng)帶來了問題,就是子系統(tǒng)之間如何通信的問題,而具體的通信方式有哪些呢?一般有同步通信和異步通信,這里我們首先來說下同步通信,下面的主題“消息系統(tǒng)”會說到異步通信。既然需要通信,這個時候一個高性能的遠程調(diào)用框架就顯得非常總要啦,因此咱們淘寶也有了自己的HSF框架。

      上面所說的都是拆分的好處,但是拆分以后必然的也會帶來新的問題,除了剛才說的子系統(tǒng)通信問題外,最值得關(guān)注的問題就是系統(tǒng)之間的依賴關(guān)系,因為系統(tǒng)多了,系統(tǒng)的依賴關(guān)系就會變得復(fù)雜,此時就需要更好的去關(guān)注拆分標準,比如能否將一些有依賴的系統(tǒng)進行垂直化,使得這些系統(tǒng)的功能盡量的垂直,這也是目前淘寶正在做的系統(tǒng)垂直化,同時一定要注意系統(tǒng)之間的循環(huán)依賴,如果出現(xiàn)循環(huán)依賴一定要小心,因為這可能導(dǎo)致系統(tǒng)連鎖啟動失敗。

      OK,既然明白了拆分的重要性,我們看看隨著淘寶的發(fā)展,淘寶本身是如何拆分系統(tǒng)的。

      首先我們來看以下這個圖:作者圖片已無法打開,請見諒

      從上面的圖可以看出淘寶系統(tǒng)的一個演變過程,在這個演變的過程中,我們所說的拆分就出現(xiàn)V2.2和V3.0之間。在V2.2版本中,淘寶幾乎所有的邏輯都放在Denali系統(tǒng)中,這樣導(dǎo)致的問題就是系統(tǒng)擴展和修改非常麻煩,并且更加致命的是隨著淘寶業(yè)務(wù)量的增加,如果按照V2.2的架構(gòu)已經(jīng)沒有辦法支撐以后淘寶的快速發(fā)展,因此大家決定對整個系統(tǒng)進行拆分,最終V3.0版本的淘寶系統(tǒng)架構(gòu)圖如下:作者圖片已無法打開,請見諒

      從上圖可以看出V3.0版本的系統(tǒng)對整個系統(tǒng)進行了水平和垂直兩個方向的拆分,水平方向上,按照功能分為交易,評價,用戶,商品等系統(tǒng),同樣垂直方向上,劃分為業(yè)務(wù)系統(tǒng),核心業(yè)務(wù)系統(tǒng)以及以及基礎(chǔ)服務(wù),這樣以來,各個系統(tǒng)都可以獨立維護和獨立的進行水平伸縮,比如交易系統(tǒng)可以在不影響其它系統(tǒng)的情況下獨立的進行水平伸縮以及功能擴展。

      從上面可以看出,一個大型系統(tǒng)要想變得可維護,可擴展,可伸縮,我們必須的對它進行拆分,拆分必然也帶來系統(tǒng)之間如何通信以及系統(tǒng)之間依賴管理等問題,關(guān)于通信方面,淘寶目前獨立開發(fā)了自己的高性能服務(wù)框架HSF,此框架主要解決了淘寶目前所有子系統(tǒng)之間的同步和異步通信目前HSF主要用于同步場合,F(xiàn)utureTask方式的調(diào)用場景還比較少。至于系統(tǒng)間的依賴管理,目前淘寶還做的不夠好,這應(yīng)該也是我們以后努力解決的問題。

      四數(shù)據(jù)庫拆分TDDL

      在前面“應(yīng)用拆分”主題中,我們提到了一個大型互聯(lián)網(wǎng)應(yīng)用需要進行良好的拆分,而那里我們僅僅說了”應(yīng)用級別”的拆分,其實我們的互聯(lián)網(wǎng)應(yīng)用除了應(yīng)用級別的拆分以外,還有另外一個很重要的層面就是存儲如何拆分的。因此這個主題主要涉及到如何對存儲系統(tǒng),通常就是所說的RDBMS進行拆分。

      好了,確定了這個小節(jié)的主題之后,我們回顧一下,一個互聯(lián)網(wǎng)應(yīng)用從小變大的過程中遇到的一些問題,通過遇到的問題來引出我們拆分RDBMS的重要性。

      系統(tǒng)剛開始的時候,因系統(tǒng)剛上線,用戶不多,那個時候,所有的數(shù)據(jù)都放在了同一個數(shù)據(jù)庫中,這個時候因為用戶少壓力小,一個數(shù)據(jù)庫完全可以應(yīng)付的了,但是隨著運營那些哥們辛苦的吶喊和拼命的推廣以后,突然有一天發(fā)現(xiàn),oh,god,用戶數(shù)量突然變多了起來,隨之而來的就是數(shù)據(jù)庫這哥們受不了,它終于在某一天大家都和愜意的時候掛掉啦。此時,咱們搞技術(shù)的哥們,就去看看究竟是啥原因,我們查了查以后,發(fā)現(xiàn)原來是數(shù)據(jù)庫讀取壓力太大了,此時咱們都清楚是到了讀寫分離的時候,這個時候我們會配置一個server為master節(jié)點,然后配幾個salve節(jié)點,這樣以來通過讀寫分離,使得讀取數(shù)據(jù)的壓力分攤到了不同的salve節(jié)點上面,系統(tǒng)終于又恢復(fù)了正常,開始正常運行了。但是好景還是不長,有一天我們發(fā)現(xiàn)master這哥們撐不住了,它負載老高了,汗流浹背,隨時都有翹掉的風險,這個時候就需要咱們垂直分區(qū)啦也就是所謂的分庫,比如將商品信息,用戶信息,交易信息分別存儲到不同的數(shù)據(jù)庫中,同時還可以針對商品信息的庫采用master,salve模式,OK,通過分庫以后,各個按照功能拆分的數(shù)據(jù)庫寫壓力被分擔到了不同的server上面,這樣數(shù)據(jù)庫的壓力終于有恢復(fù)到正常狀態(tài)。但是是不是這樣,我們就可以高枕無憂了呢?NO,這個NO,不是我說的,是前輩們通過經(jīng)驗總結(jié)出來的,隨著用戶量的不斷增加,你會發(fā)現(xiàn)系統(tǒng)中的某些表會變的異常龐大,比如好友關(guān)系表,店鋪的參數(shù)配置表等,這個時候無論是寫入還是讀取這些表的數(shù)據(jù),對數(shù)據(jù)庫來說都是一個很耗費精力的事情,因此此時就需要我們進行“水平分區(qū)”了這就是俗話說的分表,或者說sharding.

      OK,上面說了一大堆,無非就是告訴大家一個事實“數(shù)據(jù)庫是系統(tǒng)中最不容易scale out的一層”,一個大型的互聯(lián)網(wǎng)應(yīng)用必然會經(jīng)過一個從單一DB server,到Master/salve,再到垂直分區(qū)分庫,然后再到水平分區(qū)分表,sharding的過程,而在這個過程中,Master/salve以及垂直分區(qū)相對比較容易,應(yīng)用的影響也不是很大,但是分表會引起一些棘手的問題,比如不能跨越多個分區(qū)join查詢數(shù)據(jù),如何平衡各個shards的負載等等,這個時候就需要一個通用的DAL框架來屏蔽底層數(shù)據(jù)存儲對應(yīng)用邏輯的影響,使得底層數(shù)據(jù)的訪問對應(yīng)用透明化。

      拿淘寶目前的情況來說,淘寶目前也正在從昂貴的高端存儲小型機+ORACLE切換到MYSQL,切換到MYSQL以后,勢必會遇到垂直分區(qū)分庫以及水平分區(qū)Sharding的問題,因此目前淘寶根據(jù)自己的業(yè)務(wù)特點也開發(fā)了自己的TDDL框架,此框架主要解決了分庫分表對應(yīng)用的透明化以及異構(gòu)數(shù)據(jù)庫之間的數(shù)據(jù)復(fù)制

      五異步通信Notify

      在”遠程調(diào)用框架”的介紹中,我們說了一個大型的系統(tǒng)為了擴展性和伸縮性方面的需求,肯定是要進行拆分,但是拆分了以后,子系統(tǒng)之間如何通信就成了我們首要的問題,在”遠程調(diào)用框架”小節(jié)中,我們說了同步通信在一個大型分布式系統(tǒng)中的應(yīng)用,那么這一小節(jié)我們就來說說異步通信.好了,既然說到了異步通信,那么”消息中間件”就要登場了,采用異步通信這其實也是關(guān)系到系統(tǒng)的伸縮性,以及最大化的對各個子系統(tǒng)進行解耦.

      說到異步通信,我們需要關(guān)注的一點是這里的異步一定是根據(jù)業(yè)務(wù)特點來的,一定是針對業(yè)務(wù)的異步,通常適合異步的場合是一些松耦合的通信場合,而對于本身業(yè)務(wù)上關(guān)聯(lián)度比較大的業(yè)務(wù)系統(tǒng)之間,我們還是要采用同步通信比較靠譜。

      OK,那么下一步我們說說異步能給系統(tǒng)帶來什么樣子的好處。首先我們想想,假如系統(tǒng)有A和B兩個子系統(tǒng)構(gòu)成,假如A和B是同步通信的話,那么要想使得系統(tǒng)整體伸縮性提高必須同時對A和B進行伸縮,這就影響了對整個系統(tǒng)進行scale out.其次,同步調(diào)用還會影響到可用性,從數(shù)學推理的角度來說,A同步調(diào)用B,如果A可用,那么B可用,逆否命題就是如果B不可用,那么A也不可用,這將大大影響到系統(tǒng)可用性,再次,系統(tǒng)之間異步通信以后可以大大提高系統(tǒng)的響應(yīng)時間,使得每個請求的響應(yīng)時間變短,從而提高用戶體驗,因此異步在提高了系統(tǒng)的伸縮性以及可用性的同時,也大大的增強了請求的響應(yīng)時間當然了,請求的總體處理時間也許不會變少。

      下面我們就以淘寶的業(yè)務(wù)來看看異步在淘寶的具體應(yīng)用。交易系統(tǒng)會與很多其它的業(yè)務(wù)系統(tǒng)交互,如果在一次交易過程中采用同步調(diào)用的話,這就要求要向交易成功,必須依賴的所有系統(tǒng)都可用,而如果采用異步通信以后,交易系統(tǒng)借助于消息中間件Notify和其它的系統(tǒng)進行了解耦,這樣以來當其它的系統(tǒng)不可用的時候,也不會影響到某此交易,從而提高了系統(tǒng)的可用性。

      最后,關(guān)于異步方面的討論,我可以推薦大家一些資源:

      1 . J2EE meets web2.0

      2. Ebay架構(gòu)特點HPTS 2009

      六非結(jié)構(gòu)化數(shù)據(jù)存儲 TFS,NOSQL

      在一個大型的互聯(lián)網(wǎng)應(yīng)用當中,我們會發(fā)現(xiàn)并不是所有的數(shù)據(jù)都是結(jié)構(gòu)化的,比如一些配置文件,一個用戶對應(yīng)的動態(tài),以及一次交易的快照等信息,這些信息一般不適合保存到RDBMS中,它們更符合一種Key-value的結(jié)構(gòu),另外還有一類數(shù)據(jù),數(shù)據(jù)量非常的大,但是實時性要求不高,此時這些數(shù)據(jù)也需要通過另外的一種存儲方式進行存儲,另外一些靜態(tài)文件,比如各個商品的圖片,商品描述等信息,這些信息因為比較大,放入RDBMS會引起讀取性能問題,從而影響到其它的數(shù)據(jù)讀取性能,因此這些信息也需要和其它信息分開存儲,而一般的互聯(lián)網(wǎng)應(yīng)用系統(tǒng)都會選擇把這些信息保存到分布式文件系統(tǒng)中,因此淘寶目前也開發(fā)了自己的分布式文件系統(tǒng)TFS,TFS目前限制了文件大小為2M,適合于一些小于2M數(shù)據(jù)的存放。

      隨著互聯(lián)網(wǎng)發(fā)展,業(yè)界從08年下半年開始逐漸流行了一個概念就是NOSQL。我們都知道根據(jù)CAP理論,一致性,可用性和分區(qū)容錯性3者不能同時滿足,最多只能同時滿足兩個,我們傳統(tǒng)的關(guān)系數(shù)據(jù)采用了ACID的事務(wù)策略,而ACID的事務(wù)策略更加講究的是一種高一致性而降低了可用性的需求,但是互聯(lián)網(wǎng)應(yīng)用往往對可用性的要求要略高于一致性的需求,這個時候我們就需要避免采用數(shù)據(jù)的ACID事務(wù)策略,轉(zhuǎn)而采用BASE事務(wù)策略,BASE事務(wù)策略是基本可用性,事務(wù)軟狀態(tài)以及最終一致性的縮寫,通過BASE事務(wù)策略,我們可以通過最終一致性來提升系統(tǒng)的可用性,這也是目前很多NOSQL產(chǎn)品所采用的策略,包括facebook的cassandra,apache hbase,google bigtable等,這些產(chǎn)品非常適合一些非結(jié)構(gòu)化的數(shù)據(jù),比如key-value形式的數(shù)據(jù)存儲,并且這些產(chǎn)品有個很好的優(yōu)點就是水平伸縮性。目前淘寶也在研究和使用一些成熟的NOSQL產(chǎn)品。

      七監(jiān)控、預(yù)警系統(tǒng)

      對于大型的系統(tǒng)來說,唯一可靠的就是系統(tǒng)的各個部分是不可靠。

      因為一個大型的分布式系統(tǒng)中勢必會涉及到各種各樣的設(shè)備,比如網(wǎng)絡(luò)交換機,普通PC機,各種型號的網(wǎng)卡,硬盤,內(nèi)存等等,而這些東東都在數(shù)量非常多的時候,出現(xiàn)錯誤的概率也會變大,因此我們需要時時刻刻監(jiān)控系統(tǒng)的狀態(tài),而監(jiān)控也有粒度的粗細之分,粒度粗一點的話,我們需要對整個應(yīng)用系統(tǒng)進行監(jiān)控,比如目前的系統(tǒng)網(wǎng)絡(luò)流量是多少,內(nèi)存利用率是多少,IO,CPU的負載是多少,服務(wù)的訪問壓力是多少,服務(wù)的響應(yīng)時間是多少等這一系列的監(jiān)控,而細粒度一點的話,我們就需對比如應(yīng)用中的某個功能,某個URL的訪問量是多,每個頁面的PV是多少,頁面每天占用的帶寬是多少,頁面渲染時間是多少,靜態(tài)資源比如圖片每天占用的帶寬是多少等等進行進一步細粒度的監(jiān)控。因此一個監(jiān)控系統(tǒng)就變得必不可少了。

      前面說了一個監(jiān)控系統(tǒng)的重要性,有了監(jiān)控系統(tǒng)以后,更重要的是要和預(yù)警系統(tǒng)結(jié)合起來,比如當某個頁面訪問量增多的時候,系統(tǒng)能自動預(yù)警,某臺Server的CPU和內(nèi)存占用率突然變大的時候,系統(tǒng)也能自動預(yù)警,當并發(fā)請求丟失嚴重的時候,系統(tǒng)也能自動預(yù)警等等,這樣以來通過監(jiān)控系統(tǒng)和預(yù)警系統(tǒng)的結(jié)合可以使得我們能快速響應(yīng)系統(tǒng)出現(xiàn)的問題,提高系統(tǒng)的穩(wěn)定性和可用性。

      八配置統(tǒng)一管理

      一個大型的分布式應(yīng)用,一般都是有很多節(jié)點構(gòu)成的,如果每次一個新的節(jié)點加入都要更改其它節(jié)點的配置,或者每次刪除一個節(jié)點也要更改配置的話,這樣不僅不利于系統(tǒng)的維護和管理,同時也更加容易引入錯誤。另外很多時候集群中的很多系統(tǒng)的配置都是一樣的,如果不進行統(tǒng)一的配置管理,就需要再所有的系統(tǒng)上維護一份配置,這樣會造成配置的管理維護很麻煩,而通過一個統(tǒng)一的配置管理可以使得這些問題得到很好的解決,當有新的節(jié)點加入或者刪除的時候,配置管理系統(tǒng)可以通知各個節(jié)點更新配置,從而達到所有節(jié)點的配置一致性,這樣既方便也不會出錯。(編選: 勇全)

    發(fā)布于 9個月前, 閱讀(89) | 評論(1) | 投票(0) | 收藏(1) 閱讀全文...
  • 262013-03

    基于HTTP協(xié)議的Web API是時下最為流行的一種分布式服務(wù)提供方式。無論是在大型互聯(lián)網(wǎng)應(yīng)用還是企業(yè)級架構(gòu)中,我們都見到了越來越多SOA或RESTful的Web API。為什么Web API如此流行呢?我認為很大程度上應(yīng)歸功于簡單有效的HTTP協(xié)議。HTTP協(xié)議是一種分布式的面向資源的網(wǎng)絡(luò)應(yīng)用層協(xié)議,無論是服務(wù)器端提供Web服務(wù),還是客戶端消費Web服務(wù)都非常簡單。再加上瀏覽器、Javascript、AJAX、JSON以及HTML5等技術(shù)和工具的發(fā)展,互聯(lián)網(wǎng)應(yīng)用架構(gòu)設(shè)計表現(xiàn)出了從傳統(tǒng)的PHP、JSP、ASP.NET等服務(wù)器端動態(tài)網(wǎng)頁向Web API + RIA(富互聯(lián)網(wǎng)應(yīng)用)過渡的趨勢。Web API專注于提供業(yè)務(wù)服務(wù),RIA專注于用戶界面和交互設(shè)計,從此兩個領(lǐng)域的分工更加明晰。在這種趨勢下,Web API設(shè)計將成為服務(wù)器端程序員的必修課。然而,正如簡單的Java語言并不意味著高質(zhì)量的Java程序,簡單的HTTP協(xié)議也不意味著高質(zhì)量的Web API。要想設(shè)計出高質(zhì)量的Web API,還需要深入理解分布式系統(tǒng)及HTTP協(xié)議的特性。

     

    冪等性定義

    本文所要探討的正是HTTP協(xié)議涉及到的一種重要性質(zhì):冪等性(Idempotence)。在HTTP/1.1規(guī)范中冪等性的定義是:

    Methods can also have the property of "idempotence" in that (aside from error or expiration issues) the side-effects of N > 0 identical requests is the same as for a single request.

    從定義上看,HTTP方法的冪等性是指一次和多次請求某一個資源應(yīng)該具有同樣的副作用。冪等性屬于語義范疇,正如編譯器只能幫助檢查語法錯誤一樣,HTTP規(guī)范也沒有辦法通過消息格式等語法手段來定義它,這可能是它不太受到重視的原因之一。但實際上,冪等性是分布式系統(tǒng)設(shè)計中十分重要概念,而HTTP的分布式本質(zhì)也決定了它在HTTP中具有重要地位。

     

    分布式事務(wù) vs 冪等設(shè)計

    為什么需要冪等性呢?我們先從一個例子說起,假設(shè)有一個從賬戶取錢的遠程API(可以是HTTP的,也可以不是),我們暫時用類函數(shù)的方式記為: 

    bool withdraw(account_id, amount)

    withdraw的語義是從account_id對應(yīng)的賬戶中扣除amount數(shù)額的錢;如果扣除成功則返回true,賬戶余額減少amount;如果扣除失敗則返回false,賬戶余額不變。值得注意的是:和本地環(huán)境相比,我們不能輕易假設(shè)分布式環(huán)境的可靠性。一種典型的情況是withdraw請求已經(jīng)被服務(wù)器端正確處理,但服務(wù)器端的返回結(jié)果由于網(wǎng)絡(luò)等原因被掉丟了,導(dǎo)致客戶端無法得知處理結(jié)果。如果是在網(wǎng)頁上,一些不恰當?shù)脑O(shè)計可能會使用戶認為上一次操作失敗了,然后刷新頁面,這就導(dǎo)致了withdraw被調(diào)用兩次,賬戶也被多扣了一次錢。如圖1所示:

    non-idemponent

    圖1

    這個問題的解決方案一是采用分布式事務(wù),通過引入支持分布式事務(wù)的中間件來保證withdraw功能的事務(wù)性。分布式事務(wù)的優(yōu)點是對于調(diào)用者很簡單,復(fù)雜性都交給了中間件來管理。缺點則是一方面架構(gòu)太重量級,容易被綁在特定的中間件上,不利于異構(gòu)系統(tǒng)的集成;另一方面分布式事務(wù)雖然能保證事務(wù)的ACID性質(zhì),而但卻無法提供性能和可用性的保證。

    另一種更輕量級的解決方案是冪等設(shè)計。我們可以通過一些技巧把withdraw變成冪等的,比如:

    int create_ticket() 

    bool idempotent_withdraw(ticket_id, account_id, amount)

    create_ticket的語義是獲取一個服務(wù)器端生成的唯一的處理號ticket_id,它將用于標識后續(xù)的操作。idempotent_withdraw和withdraw的區(qū)別在于關(guān)聯(lián)了一個ticket_id,一個ticket_id表示的操作至多只會被處理一次,每次調(diào)用都將返回第一次調(diào)用時的處理結(jié)果。這樣,idempotent_withdraw就符合冪等性了,客戶端就可以放心地多次調(diào)用。

    基于冪等性的解決方案中一個完整的取錢流程被分解成了兩個步驟:1.調(diào)用create_ticket()獲取ticket_id;2.調(diào)用idempotent_withdraw(ticket_id, account_id, amount)。雖然create_ticket不是冪等的,但在這種設(shè)計下,它對系統(tǒng)狀態(tài)的影響可以忽略,加上idempotent_withdraw是冪等的,所以任何一步由于網(wǎng)絡(luò)等原因失敗或超時,客戶端都可以重試,直到獲得結(jié)果。如圖2所示:

    image

    圖2

    和分布式事務(wù)相比,冪等設(shè)計的優(yōu)勢在于它的輕量級,容易適應(yīng)異構(gòu)環(huán)境,以及性能和可用性方面。在某些性能要求比較高的應(yīng)用,冪等設(shè)計往往是唯一的選擇。

     

    HTTP的冪等性

    HTTP協(xié)議本身是一種面向資源的應(yīng)用層協(xié)議,但對HTTP協(xié)議的使用實際上存在著兩種不同的方式:一種是RESTful的,它把HTTP當成應(yīng)用層協(xié)議,比較忠實地遵守了HTTP協(xié)議的各種規(guī)定;另一種是SOA的,它并沒有完全把HTTP當成應(yīng)用層協(xié)議,而是把HTTP協(xié)議作為了傳輸層協(xié)議,然后在HTTP之上建立了自己的應(yīng)用層協(xié)議。本文所討論的HTTP冪等性主要針對RESTful風格的,不過正如上一節(jié)所看到的那樣,冪等性并不屬于特定的協(xié)議,它是分布式系統(tǒng)的一種特性;所以,不論是SOA還是RESTful的Web API設(shè)計都應(yīng)該考慮冪等性。下面將介紹HTTP GET、DELETE、PUT、POST四種主要方法的語義和冪等性。

    HTTP GET方法用于獲取資源,不應(yīng)有副作用,所以是冪等的。比如:GET http://www./account/123456,不會改變資源的狀態(tài),不論調(diào)用一次還是N次都沒有副作用。請注意,這里強調(diào)的是一次和N次具有相同的副作用,而不是每次GET的結(jié)果相同。GET http://www./latest-news這個HTTP請求可能會每次得到不同的結(jié)果,但它本身并沒有產(chǎn)生任何副作用,因而是滿足冪等性的。

    HTTP DELETE方法用于刪除資源,有副作用,但它應(yīng)該滿足冪等性。比如:DELETE http://www./article/4231,調(diào)用一次和N次對系統(tǒng)產(chǎn)生的副作用是相同的,即刪掉id為4231的帖子;因此,調(diào)用者可以多次調(diào)用或刷新頁面而不必擔心引起錯誤。

    比較容易混淆的是HTTP POST和PUT。POST和PUT的區(qū)別容易被簡單地誤認為“POST表示創(chuàng)建資源,PUT表示更新資源”;而實際上,二者均可用于創(chuàng)建資源,更為本質(zhì)的差別是在冪等性方面。在HTTP規(guī)范中對POST和PUT是這樣定義的:

    The POST method is used to request that the origin server accept the entity enclosed in the request as a new subordinate of the resource identified by the Request-URI in the Request-Line. ...... If a resource has been created on the origin server, the response SHOULD be 201 (Created) and contain an entity which describes the status of the request and refers to the new resource, and a Location header.

    The PUT method requests that the enclosed entity be stored under the supplied Request-URI. If the Request-URI refers to an already existing resource, the enclosed entity SHOULD be considered as a modified version of the one residing on the origin server. If the Request-URI does not point to an existing resource, and that URI is capable of being defined as a new resource by the requesting user agent, the origin server can create the resource with that URI.

    POST所對應(yīng)的URI并非創(chuàng)建的資源本身,而是資源的接收者。比如:POST http://www./articles的語義是在http://www./articles下創(chuàng)建一篇帖子,HTTP響應(yīng)中應(yīng)包含帖子的創(chuàng)建狀態(tài)以及帖子的URI。兩次相同的POST請求會在服務(wù)器端創(chuàng)建兩份資源,它們具有不同的URI;所以,POST方法不具備冪等性。而PUT所對應(yīng)的URI是要創(chuàng)建或更新的資源本身。比如:PUT http://www.forum/articles/4231的語義是創(chuàng)建或更新ID為4231的帖子。對同一URI進行多次PUT的副作用和一次PUT是相同的;因此,PUT方法具有冪等性。

    在介紹了幾種操作的語義和冪等性之后,我們來看看如何通過Web API的形式實現(xiàn)前面所提到的取款功能。很簡單,用POST /tickets來實現(xiàn)create_ticket;用PUT /accounts/account_id/ticket_id&amount=xxx來實現(xiàn)idempotent_withdraw。值得注意的是嚴格來講amount參數(shù)不應(yīng)該作為URI的一部分,真正的URI應(yīng)該是/accounts/account_id/ticket_id,而amount應(yīng)該放在請求的body中。這種模式可以應(yīng)用于很多場合,比如:論壇網(wǎng)站中防止意外的重復(fù)發(fā)帖。

     

    總結(jié)

    上面簡單介紹了冪等性的概念,用冪等設(shè)計取代分布式事務(wù)的方法,以及HTTP主要方法的語義和冪等性特征。其實,如果要追根溯源,冪等性是數(shù)學中的一個概念,表達的是N次變換與1次變換的結(jié)果相同,有興趣的讀者可以從Wikipedia上進一步了解。

     

    參考

    RFC 2616, Hypertext Transfer Protocol -- HTTP/1.1, Method Definitions

    The Importance of Idempotence

    stackoverflow -  PUT vs POST in REST

    發(fā)布于 9個月前, 閱讀(9) | 評論(0) | 投票(0) | 收藏(0) 閱讀全文...
  • 292012-11
    摘要:HBTC 2012(Hadoop&BigData Technology Conference 2012)即將召開,為了讓讀者可以提前了解一下目前國內(nèi)各個公司在Hadoop和大數(shù)據(jù)方面的運用,CSDN于會前對演講嘉賓進行了采訪。本期采訪了阿里巴巴的代志遠,他給我們提前分享了一下HBase在阿里巴巴海量數(shù)據(jù)部門的實踐。

    【CSDN報道】代志遠早年就職網(wǎng)易研究院從事MapReduce與DFS系統(tǒng)的自主研發(fā),后加入支付寶數(shù)據(jù)平臺負責Hadoop與HBase體系的架構(gòu)設(shè)計與二次研發(fā),支付寶流計算與分布式搜索系統(tǒng)的設(shè)計和研發(fā),后成為支付寶海量計算體系架構(gòu)師兼支付寶三代架構(gòu)成員?,F(xiàn)就轉(zhuǎn)戰(zhàn)于阿里巴巴集團-CDO-海量數(shù)據(jù)部門,負責創(chuàng)新性項目的研究和跟進,目前專注于Google第二代數(shù)據(jù)庫產(chǎn)品MegaStore的研究和在阿里的落地。

    在即將召開的HBTC大會中,我們有幸邀請到代志遠作為我們的演講嘉賓,請他分享下阿里巴巴在海量數(shù)據(jù)分布式數(shù)據(jù)庫領(lǐng)域的探索。我們也對他提前做了郵件采訪,讓用戶可以更快地了解阿里巴巴海量數(shù)據(jù)分布式數(shù)據(jù)庫以及在Hadoop應(yīng)用領(lǐng)域的實踐。

    阿里巴巴海量數(shù)據(jù)部門: 代志遠

    CSDN: Hadoop目前是大數(shù)據(jù)處理領(lǐng)域的王者,你認為中小企業(yè)應(yīng)用Hadoop的瓶頸在哪里?

    代志遠:首先因為Hadoop本身機制復(fù)雜,所依賴的參數(shù)配置頗多,并且Hadoop需要像數(shù)據(jù)庫一樣穩(wěn)定,滿足性能的運行,就需要運維人員如同DBA一樣要懂網(wǎng)絡(luò)、磁盤、內(nèi)核以及其他一些硬件知識,這對于運維人員的要求是比較高的。其次Hadoop社區(qū)蓬勃發(fā)展,生態(tài)圈不斷擴大,用戶不斷增多,規(guī)模極限也不斷突破,這就促使了Hadoop的架構(gòu)和代碼發(fā)展非??於易兏脖容^快,正因為如此,系統(tǒng)在快速發(fā)展的時候容易引入很多的Bug和一些缺陷(可能因為稍稍的使用不當或比較小的問題就引起整體性能和穩(wěn)定性的波動)。更重要的是,Hadoop代碼復(fù)雜,而且需要與社區(qū)接軌,能夠找到對Hadoop源碼熟悉并能優(yōu)化升級和bugfix的人才是很難的,這對于一個公司的研發(fā)來說是個很大的挑戰(zhàn)。最后一點是公司的認知,除了類似Cloudera、MapR之類的軟件公司需要對軟件技術(shù)負責,其他多數(shù)公司無論大中小都依賴于公司業(yè)務(wù),尤其中小公司業(yè)務(wù)壓力大、人員緊張,能夠從業(yè)務(wù)研發(fā)人員中抽調(diào)或通過其他方式組建專有的Hadoop運維團隊甚至是研發(fā)團隊,從公司規(guī)劃與發(fā)展上來說是比較困難的事情。

    CSDN: Hadoop的本質(zhì)是為全量而生,就是說它重吞吐量,響應(yīng)時間完全沒有保障,那么對于像淘寶、天貓在“雙11”活動搶購的時候,需要實時處理數(shù)據(jù)(可能是毫秒級,秒級的響應(yīng)),是如何進行實現(xiàn)的?

    代志遠:Hadoop是離線計算平臺,其中包括分布式文件系統(tǒng)(HDFS)和分布式計算(MapReduce),這本身是無法對響應(yīng)時間做保證的。但是目前在Hadoop之上的生態(tài)系統(tǒng)越來越完善,其中HBase就是支持海量數(shù)據(jù)、高并發(fā)的在線數(shù)據(jù)庫,應(yīng)對這種場景就非常適合。HBase在這次雙十一中與MySQL等在線數(shù)據(jù)庫共同作為線上庫使用,承擔了重要的責任,并創(chuàng)下了并在全天高壓力之下無故障的佳績。另外非Hadoop生態(tài)圈的流式計算框架Storm、S4也同樣可以為實時計算分擔一定的壓力。

    CSDN: 你在云計算大會時做的一場有關(guān)HBase的報告,主要講如何用HBase替代MySQL,HBase對比MySQL的優(yōu)勢在哪里?

    代志遠:準確來說是HBase替換MySQL的一部分應(yīng)用,這些應(yīng)用自然是要符合HBase的應(yīng)用場景(與MySQL對比),比如數(shù)據(jù)量大、對線性拓展有需求、對自動化運維(負載均衡)有要求而且應(yīng)用模式簡單。在支付寶中因其增長速度快,業(yè)務(wù)量大,造成了很多應(yīng)用都是數(shù)據(jù)量龐大而且速度增長快,因此有一些應(yīng)用迫切需要一個數(shù)據(jù)庫能夠支撐現(xiàn)在的業(yè)務(wù)而降低對關(guān)系型的需求,所以嘗試了HBase的解決方案。

    CSDN: 阿里巴巴在部署Hadoop的過程中有哪些比較好的經(jīng)驗可以跟技術(shù)人員分享?

    代志遠:最重要的是要有一個完善團隊,健全的流程。

    • 集群越來越大,要樹立以集群穩(wěn)定性和性能為要領(lǐng)的工作思路。
    • 現(xiàn)在進入Hadoop應(yīng)用開發(fā)領(lǐng)域的人變多,但本身知識因其入行早晚而積累不同,無法對集群的穩(wěn)定性負責,常常會寫出跑死集群的任務(wù)(數(shù)據(jù)庫中SQL使用不善也常會如此)。因此要有一個較好的管理流程約束開發(fā)人員做到責任分明,以便促使應(yīng)用開發(fā)不僅要對自己的任務(wù)負責還要對集群負責,不斷學習和檢查減少故障的產(chǎn)生。
    • 要有一個好的運維團隊,懂硬件、重流程、負責任。
    • 公司在資源和戰(zhàn)略上應(yīng)有所傾斜,重視研發(fā)人員加強在研發(fā)的投入,畢竟分布式系統(tǒng)的入行門檻相比應(yīng)用開發(fā)的技術(shù)門檻要高,當然有好的應(yīng)用架構(gòu)師能夠取長補短規(guī)避大多數(shù)問題也是可行的,但單一系統(tǒng)的穩(wěn)定性還是需要靠人來保證。

    CSDN: 請您簡要介紹一下本次HBTC2012大會上的議題的內(nèi)容。

    代志遠:06年Google發(fā)表論文Bigtable,社區(qū)隨之出現(xiàn)HBase,后Google 08年發(fā)表第二代數(shù)據(jù)庫產(chǎn)品MegaStore至今未有社區(qū)同類產(chǎn)品出現(xiàn),現(xiàn)今Google又出現(xiàn)新一代數(shù)據(jù)庫理論Spanner和F1。 而最近幾年隨之Bigtable和NoSQL的興起,社區(qū)產(chǎn)品HBase逐步走向NoSQL系統(tǒng)的主流產(chǎn)品,優(yōu)勢明顯然而缺點也明顯,大數(shù)據(jù)平臺下的業(yè)務(wù)由SQL向NoSQL的遷移比較復(fù)雜而應(yīng)用人員學習成本頗高,并且無法支持事務(wù)和多維索引,使得許多業(yè)務(wù)無法享用來自NoSQL系統(tǒng)中線性拓展能力。

    Google內(nèi)部MegaStore就作為Bigtable的一個補充而出現(xiàn),在Bigtable的上層支持了SQL,事務(wù)、索引、跨機房災(zāi)備,并成為大名鼎鼎的Gmail、Google App Engine、Android Market的底層存儲。因此我們決定以MegaStore為理論模型進行探索如何在HBase系統(tǒng)上不犧牲線性拓展能力,同時又能提供跨行事務(wù)、索引、SQL的功能。

    HBase系統(tǒng)故障恢復(fù)的優(yōu)化實踐

    其實在第四屆中國云計算大會上,當時還在支付寶數(shù)據(jù)平臺的架構(gòu)師代志遠就為大家?guī)砹祟}為“HBase系統(tǒng)故障恢復(fù)的優(yōu)化實踐分享”的精彩演講,他分析了支付寶海量數(shù)據(jù)在線處理的現(xiàn)狀,以HBase解決方案取代傳統(tǒng)MySQL解決方案的技術(shù)歷程,并詳盡分享了Region Server的宕機恢復(fù)流程(閱讀全文)。

    在Hadoop的體系當中,支持實時的一條線,HBase,支持海量數(shù)據(jù)庫初衷的時候,設(shè)計為了設(shè)計萬一級實時數(shù)據(jù)庫,HBase這個東西經(jīng)過這幾年的發(fā)展,已經(jīng)逐漸成為目前業(yè)界當中主要的實時數(shù)據(jù)庫,分布式數(shù)據(jù)庫,像支付寶直接上HBase系統(tǒng),就是考慮到HBase的先進架構(gòu),能夠幫助支付寶完成現(xiàn)在很多的海量數(shù)據(jù)的存儲以及在線隨機讀寫高性能的訪問和存儲。

    不過在HBase的系統(tǒng)當中,體現(xiàn)它的可用性有幾個風險。第一個是HBase本身在底層依賴的HDFS,加載了唯一一塊數(shù)據(jù),單臺機器保證一致性,HDFS保持了冗余。第二點,恢復(fù)過程當中,F(xiàn)ailover過程非常復(fù)雜,這個時間消耗越長,作為在線系統(tǒng),這種時間越長可能會影響到在線訪問用戶體驗。第三點它依賴的HDFS,HBase作為在線數(shù)據(jù)庫依賴HDFS有故障的,經(jīng)過幾小時恢復(fù)提供生產(chǎn)業(yè)務(wù),對業(yè)務(wù)方?jīng)]有直接感受,作為在線系統(tǒng)如果掛掉,如果需要經(jīng)過近小時恢復(fù)時間,恐怕就會直接收到自于支付寶外部的用戶投訴了。HBase目前它自己的監(jiān)控體系尚不完善,目前的監(jiān)控力度非常得粗,只能監(jiān)控到單臺的Region Server的情況,看不到當前用戶表有多少讀寫比例,看不到當前服務(wù)結(jié)點寫作量多少,讀出量多少。

    Region Server在恢復(fù)過程當中有幾個流程,這個流程很復(fù)雜,流程非常非常多,以當前的系統(tǒng)規(guī)模,它凸顯出來的問題,這幾個流程是影響到它的恢復(fù)速度的關(guān)鍵流程。等待時間周期非常長,周期之所以比較長,是因為現(xiàn)在的機器發(fā)展速度非常得快,每臺機器從兩個G到8個G,96G,140G的大層次的機器,Java語言實現(xiàn)了系統(tǒng)當中大內(nèi)存管理本身存在問題,除非革新這門語言,否則別無他法。如果說在設(shè)計的參數(shù)不合理,就可能會導(dǎo)致一個問題,有可能這臺服務(wù)器就會停止運行,發(fā)生這么一次情況就非??膳拢瑤资瓽的內(nèi)存這個過程需要幾十秒甚至上分鐘,通常情況下,我們會設(shè)置到3分鐘,這就意味著,為了避免出現(xiàn)這種問題,就會同時引入新的問題,宕機之后恢復(fù)等待時間需要三分鐘。第二個關(guān)鍵流程當中,當它感知到已經(jīng)掛掉了,在線數(shù)據(jù)庫協(xié)助WL數(shù)據(jù)重新做到存儲當中去,以保證實時更新是同步,否則這個數(shù)據(jù)庫肯定要丟出去,重做數(shù)據(jù)過程當中,會有一個過程,Split Hlog,跟當前數(shù)據(jù)量有關(guān)系,Edit Log數(shù)據(jù)又比較多,大家在業(yè)余時間可以進行測試,數(shù)據(jù)不以支付寶的為準,以當前數(shù)據(jù)系統(tǒng)大小為準。

    第三個關(guān)鍵流程,重做完數(shù)據(jù)之后,這部分重新上線,上線之前進行數(shù)據(jù)進行二次掃描,告訴系統(tǒng),Region怎么加入到Region Server當中去,掃描也存在問題,問題可能引發(fā)到兩分鐘到6分鐘,這也跟當前系統(tǒng)數(shù)據(jù)有關(guān)。第四部分,這個過程稱之為再次上線的過程,這個再次上線,上線時間跟當前這臺機器的Region上線有關(guān)系。支付寶面對消費記錄查詢,用戶查不出來數(shù)據(jù),15分鐘之后才能查到,在面臨在線問題上這是非??膳碌氖虑椤?/p>

    針對Region Server這一關(guān)鍵流程,做了一些優(yōu)化。這個優(yōu)化正是提到關(guān)鍵流程第一點,在判斷宕機超市的情況下,不強依賴于Zookeeper,支付寶又啟動了監(jiān)控進程Mirror Process,每一臺,Region Server當中都會起到PID存不存在,這種檢查并非完全可靠,當檢查PID不存在,就有理由認為已經(jīng)掛掉了,要進行可靠檢查,通常DBA在線判斷數(shù)據(jù)庫是否可用,通常會用PIng連續(xù)服務(wù)端口,這就彌補了系動中的調(diào)用命令不可靠的事情。最后當發(fā)現(xiàn)服務(wù)端口不可用時,有理由認為當前進程已經(jīng)死掉了,死掉了之后,那么就按照現(xiàn)有邏輯刪除結(jié)點,這三分鐘的時間就完全省略掉了。(整理/@CSDN王鵬,審校/包研)

    11月30日-12月1日,北京新云南皇冠假日酒店,業(yè)內(nèi)將迎來國內(nèi)大數(shù)據(jù)領(lǐng)域最純粹的技術(shù)盛會——HBTC 2012(Hadoop&BigData Technology Conference 2012)。Hadoop及云計算生態(tài)系統(tǒng)的力量齊聚北京,歡迎熱愛開源的朋友們加入!報名網(wǎng)址參見HBTC 2012。

    發(fā)布于 1年前, 閱讀(112) | 評論(0) | 投票(0) | 收藏(2) 閱讀全文...
  • 292012-11

    在前面三篇文章中,介紹了關(guān)于分布式系統(tǒng)中數(shù)據(jù)一致性的問題,這一篇主要介紹CAP定理以及自己對CAP定理的了解。

    CAP定理是2000年,由 Eric Brewer 提出來的

    Brewer認為在分布式的環(huán)境下設(shè)計和部署系統(tǒng)時,有3個核心的需求,以一種特殊的關(guān)系存在。這里的分布式系統(tǒng)說的是在物理上分布的系統(tǒng),比如我們常見的web系統(tǒng)。

    這3個核心的需求是:Consistency,AvailabilityPartition Tolerance,賦予了該理論另外一個名字 - CAP。

    Consistency:一致性,這個和數(shù)據(jù)庫ACID的一致性類似,但這里關(guān)注的所有數(shù)據(jù)節(jié)點上的數(shù)據(jù)一致性和正確性,而數(shù)據(jù)庫的ACID關(guān)注的是在在一個事務(wù)內(nèi),對數(shù)據(jù)的一些約束。

    Availability:可用性,關(guān)注的在某個結(jié)點的數(shù)據(jù)是否可用,可以認為某一個節(jié)點的系統(tǒng)是否可用,通信故障除外。

    Partition Tolerance:分區(qū)容忍性,是否可以對數(shù)據(jù)進行分區(qū)。這是考慮到性能和可伸縮性。

    為什么不能完全保證這個三點了,個人覺得主要是因為一旦進行分區(qū)了,就說明了必須節(jié)點之間必須進行通信,涉及到通信,就無法確保在有限的時間內(nèi)完成指定的行文,如果要求兩個操作之間要完整的進行,因為涉及到通信,肯定存在某一個時刻只完成一部分的業(yè)務(wù)操作,在通信完成的這一段時間內(nèi),數(shù)據(jù)就是不一致性的。如果要求保證一致性,那么就必須在通信完成這一段時間內(nèi)保護數(shù)據(jù),使得任何訪問這些數(shù)據(jù)的操作不可用。

    如果想保證一致性和可用性,那么數(shù)據(jù)就不能夠分區(qū)。一個簡單的理解就是所有的數(shù)據(jù)就必須存放在一個數(shù)據(jù)庫里面,不能進行數(shù)據(jù)庫拆分。這個對于大數(shù)據(jù)量,高并發(fā)的互聯(lián)網(wǎng)應(yīng)用來說,是不可接受的。

     

    我們可以拿一個簡單的例子來說明:假設(shè)一個購物系統(tǒng),賣家A和賣家B做了一筆交易100元,交易成功了,買家把錢給賣家。

    這里面存在兩張表的數(shù)據(jù):Trade表Account表 ,涉及到三條數(shù)據(jù)Trade(100),Account A ,Account B

    假設(shè) trade表和account表在一個數(shù)據(jù)庫,那么只需要使用數(shù)據(jù)庫的事務(wù),就可以保證一致性,同時不會影響可用性。但是隨著交易量越來越大,我們可以考慮按照業(yè)務(wù)分庫,把交易庫和account庫單獨分開,這樣就涉及到trade庫和account庫進行通信,也就是存在了分區(qū),那么我們就不可能同時保證可用性和一致性。

    我們假設(shè)初始狀態(tài)

    trade(buyer,seller,tradeNo,status) = trade(A,B,20121001,I)

    account(accountNo,balance) = account(A,300)

    account(accountNo,balance) = account(B,10)

    在理想情況下,我們期望的狀態(tài)是

    trade(buyer,seller,tradeNo,status) = trade(A,B,20121001,S)

    account(accountNo,balance) = account(A,200)

    account(accountNo,balance) = account(B,110)

     

    但是考慮到一些異常情況

    假設(shè)在trade(20121001,S)更新完成之前,帳戶A進行扣款之后,帳戶A進行了另外一筆300款錢的交易,把錢消費了,那么就存在一個狀態(tài)

    trade(buyer,seller,tradeNo,status) = trade(A,B,20121001,S)

    account(accountNo,balance) = account(A,0)

    account(accountNo,balance) = account(B,10)

    產(chǎn)生了數(shù)據(jù)不一致的狀態(tài)

     

    由于這個涉及到資金上的問題,對資金要求比較高,我們必須保證一致性,那么怎么辦,只能在進行trade(A,B,20121001)交易的時候,對于任何A的后續(xù)交易請求trade(A,X,X),必須等到A完成之后,才能夠進行處理,也就是說在進行trade(A,B,20121001)的時候,Account(A)的數(shù)據(jù)是不可用的。

     

    任何架構(gòu)師在設(shè)計分布式的系統(tǒng)的時候,都必須在這三者之間進行取舍。首先就是是否選擇分區(qū),由于在一個數(shù)據(jù)分區(qū)內(nèi),根據(jù)數(shù)據(jù)庫的ACID特性,是可以保證一致性的,不會存在可用性和一致性的問題,唯一需要考慮的就是性能問題。對于可用性和一致性,大多數(shù)應(yīng)用就必須保證可用性,畢竟是互聯(lián)網(wǎng)應(yīng)用,犧牲了可用性,相當于間接的影響了用戶體驗,而唯一可以考慮就是一致性了。

     

    犧牲一致性

    對于犧牲一致性的情況最多的就是緩存和數(shù)據(jù)庫的數(shù)據(jù)同步問題,我們把緩存看做一個數(shù)據(jù)分區(qū)節(jié)點,數(shù)據(jù)庫看作另外一個節(jié)點,這兩個節(jié)點之間的數(shù)據(jù)在任何時刻都無法保證一致性的。在web2.0這樣的業(yè)務(wù),開心網(wǎng)來舉例子,訪問一個用戶的信息的時候,可以先訪問緩存的數(shù)據(jù),但是如果用戶修改了自己的一些信息,首先修改的是數(shù)據(jù)庫,然后在通知緩存進行更新,這段期間內(nèi)就會導(dǎo)致的數(shù)據(jù)不一致,用戶可能訪問的是一個過期的緩存,而不是最新的數(shù)據(jù)。但是由于這些業(yè)務(wù)對一致性的要求比較高,不會帶來太大的影響。

     

    異常錯誤檢測和補償

    還有一種犧牲一致性的方法就是通過一種錯誤補償機制來進行,可以拿上面購物的例子來說,假設(shè)我們把業(yè)務(wù)邏輯順序調(diào)整一下,先扣買家錢,然后更新交易狀態(tài),在把錢打給賣家

    我們假設(shè)初始狀態(tài)

    account(accountNo,balance) = account(A,300)

    account(accountNo,balance) = account(B,10)

    trade(buyer,seller,tradeNo,status) = trade(A,B,20121001,I)

     

    那么有可能出現(xiàn)

    account(accountNo,balance) = account(A,200)

    trade(buyer,seller,tradeNo,status) = trade(A,B,20121001,S)

    account(accountNo,balance) = account(B,10)

     

    那么就出現(xiàn)了A扣款成功,交易狀態(tài)也成功了,但是錢沒有打給B,這個時候可以通過一個時候的異?;謴?fù)機制,把錢打給B,最終的情況保證了一致性,在一定時間內(nèi)數(shù)據(jù)可能是不一致的,但是不會影響太大。

     

    兩階段提交協(xié)議

    當然,還有一種方式就是我另外一篇文章里面《X/Open DTP-分布式事務(wù)模型》里面說的,但是再第一階段和第二階段之間,數(shù)據(jù)也可不能是一致性的,也可能出現(xiàn)同樣的情況導(dǎo)致異常。而且DTP的分布式事務(wù)模型 限制太多,例如必須有實現(xiàn)其功能的相關(guān)的容器支持,并且資源管理器也必須實現(xiàn)了XA規(guī)范。限制比較多。

     

    國外有的架構(gòu)師有兩種方案去解決CAP的限制,但是也是比較適合特定的業(yè)務(wù),而沒有通用的解決方案,

    探知分區(qū)->分區(qū)內(nèi)操作->事后補償

    就是上面介紹的異常檢測恢復(fù)機制,這種機制其實還是有限制,

    首先對于分區(qū)檢測操作,不同的業(yè)務(wù)涉及到的分區(qū)操作可能不一樣

    分區(qū)內(nèi)操作限制:不同的業(yè)務(wù)對應(yīng)的約束不一致

    事后補償:由于業(yè)務(wù)約束不一樣,補償方式也不一樣。

    所以這只能作為一種思想,不能做一個通用的解決方案

     

     

    轉(zhuǎn)載自:http://www.cnblogs.com/aigongsi/archive/2012/10/15/2721366.html

    發(fā)布于 1年前, 閱讀(69) | 評論(0) | 投票(0) | 收藏(0) 閱讀全文...
  • 292012-11
    關(guān)于分布式系統(tǒng)的數(shù)據(jù)一致性問題(三)

    在我的博文里面 關(guān)于分布式系統(tǒng)的數(shù)據(jù)一致性問題(二) 里面主要介紹了數(shù)據(jù)分布的情況下保證一致性的情況,在第二篇文章里面,我這里提出了三個問題

    1. 訂單系統(tǒng)調(diào)用支付系統(tǒng)支付訂單,支付成功,但是返回給訂單系統(tǒng)數(shù)據(jù)超時,訂單還是I(初始狀態(tài)),但是此時會員帳戶余額100,會員肯定會馬上找京東罵京東,為啥不給老子發(fā)貨,我都付錢了
    2. 訂單系統(tǒng)調(diào)用支付系統(tǒng)成功,狀態(tài)也已經(jīng)更新成功,但是通知倉庫發(fā)貨失敗,這個時候訂單是P(已支付)狀態(tài),此時會員帳戶余額是100,但是倉庫不會發(fā)貨。會員也要罵京東。
    3. 訂單系統(tǒng)調(diào)用支付系統(tǒng)成功,狀態(tài)也已經(jīng)更新成功,然后通知倉庫發(fā)貨,倉庫告訴訂單系統(tǒng),沒有貨了。這個時候數(shù)據(jù)狀態(tài)和第二種情況一樣。

     

    重點分析解決了第一個的問題以及相應(yīng)的方案,發(fā)現(xiàn)在數(shù)據(jù)分布的環(huán)境下,很難絕對的保證數(shù)據(jù)一致性(任何一段區(qū)間),但是有辦法通過一種補償機制,最終保證數(shù)據(jù)的一致性。

     

    在下面在分析一下第二個問題

    • 訂單系統(tǒng)調(diào)用支付系統(tǒng)成功,狀態(tài)也已經(jīng)更新成功,但是通知倉庫發(fā)貨失敗,這個時候訂單是P(已支付)狀態(tài),此時會員帳戶余額是100,但是倉庫不會發(fā)貨。會員也要罵京東。

    通過在上一篇文章里面分析過,這個相對來說是比較簡單的,我可以采取重試機制,如果發(fā)現(xiàn)通知倉庫發(fā)貨失敗,就一致重試,

    這里面有兩種方式:

    1 異步方式:通過類似MQ(消息通知)的機制,這個是異步的通知

    2 同步調(diào)用:類似于遠程過程調(diào)用

    對于同步的調(diào)用的方式,比較簡單,我們能夠及時獲取結(jié)果,對于異步的通知,就必須采用請求,應(yīng)答的方式進行,這一點在(關(guān)于分布式系統(tǒng)的數(shù)據(jù)一致性問題(一))里面有介紹。這里面就不再闡述。

     

    來看看第三個問題

    • 訂單系統(tǒng)調(diào)用支付系統(tǒng)成功,狀態(tài)也已經(jīng)更新成功,然后通知倉庫發(fā)貨,倉庫告訴訂單系統(tǒng),沒有貨了。這個時候數(shù)據(jù)狀態(tài)和第二種情況一樣。

    我覺得這是一個很有意思的問題,我們還是考慮幾種解決的方案

    1 在會員下單的時刻,就告訴倉庫,我要你把貨物留下來,

    2 在會員支付訂單時候,在支付之前檢查倉庫有沒有貨,如果沒有貨,就告知會員木有貨物了

    3 如果會員支付成功,這個時候沒有貨了,就會退款給用戶或者等待有貨的時候在發(fā)貨

     

    正常情況,京東的倉庫一般都是有貨的,所以影響到的會員很少,但是在秒殺和營銷的時候,這個時候就不一定了,我們考慮假設(shè)倉庫有10臺iphone

    如果采用第一種方案,

    1 在會員下單的時候,相當于庫存就-1,那么用戶惡意拍下來,沒有去支付,就影響到了其他用戶的購買。京東可以設(shè)置一個訂單超時時間,如果這段時間內(nèi)沒有支付,就自動取消訂單

    2 在會員支付之前,檢查倉庫有貨,這種方案了,對于用戶體驗不好,但是對于京東比較好,至少我東西都賣出去了。那些沒有及時付款的用戶,只能投訴了京東無故取消訂單

    3 第三種方案,這個方案體驗更不好,而且用戶感覺受到京東欺詐,但是對于京東來說,比第二種方案更有益,畢竟我還可以多賣出一點東西。

     

    個人覺得,京東應(yīng)該會采用第二種或者第三種方式來處理這類情況,我在微博上搜索了 “京東 無故取消訂單”,發(fā)現(xiàn)果真和我預(yù)料的處理方式。不過至于這里的無故取消是不是技術(shù)上的原因我不知道,如果真的是技術(shù)上的原因,我覺得京東可以采用不同的處理方案。對于秒殺和促銷商品,可以考慮第一種方案,大多數(shù)人都會直接付款,畢竟便宜啊,如果用戶搶不到便宜的東西,抱怨當然很大了。這樣可以照顧大多數(shù)用戶的體驗。對于一般的訂單,可以采用第二種或者第三種方式,這種情況下,發(fā)生付款之后倉庫沒有貨的情況會比較少,并且就算發(fā)生了,用戶也會覺得無所謂,大不了退錢嗎,這樣就可以實現(xiàn)自己的利益最大化而最低程度的減少用戶體驗。

     

    而鐵道部在這個問題上,采用的是第一種方案,為什么和京東不一樣,就是因為用戶體驗,如果用戶把票都買了,你告訴我木有票了,旅客會殺人的。哈哈,不過鐵道部不擔心票賣不出去,第一種方案對他影響沒有什么。

     

    說了這么多,就是說 分布式環(huán)境下(數(shù)據(jù)分布)要任何時刻保證數(shù)據(jù)一致性是不可能的,只能采取妥協(xié)的方案來保證數(shù)據(jù)最終一致性。這個也就是著名的CAP定理。

     

    轉(zhuǎn)載自:http://www.cnblogs.com/aigongsi/archive/2012/09/25/2701396.html


    發(fā)布于 1年前, 閱讀(36) | 評論(0) | 投票(0) | 收藏(0) 閱讀全文...
  • 292012-11

    分布式系統(tǒng)的數(shù)據(jù)一致性問題(一)里面,簡單的介紹了分布式數(shù)據(jù)的同步問題,上面的問題比較抽象,在目前的互聯(lián)網(wǎng)應(yīng)用中還很少見,這次在通過一個比較常見的例子,讓大家更深入的了解一下分布式系統(tǒng)設(shè)計中關(guān)于數(shù)據(jù)一致性的問題

     

    這次我們拿我們經(jīng)常使用的功能來考慮吧,最近網(wǎng)購比較熱門,就以京東為例的,我們來看看京東的一個簡單的購物流程

     

    用戶在京東上下了一個訂單,發(fā)現(xiàn)自己在京東的賬戶里面有余額,然后使用余額支付,支付成功之后,訂單狀態(tài)修改為支付成功,然后通知倉庫發(fā)貨。假設(shè)訂單系統(tǒng),支付系統(tǒng),倉庫系統(tǒng)是三個獨立的應(yīng)用,是獨立部署的,系統(tǒng)之間通過遠程服務(wù)調(diào)用。

    訂單的有三個狀態(tài):I:初始 P:已支付 W:已出庫,訂單金額100, 會員帳戶余額200

    如果整個流程比較順利,正常情況下,訂單的狀態(tài)會變?yōu)镮->P->W,會員帳戶余額100,訂單出庫。

     

    但是如果流程不順利了?考慮以下幾種情況

    1:訂單系統(tǒng)調(diào)用支付系統(tǒng)支付訂單,支付成功,但是返回給訂單系統(tǒng)數(shù)據(jù)超時,訂單還是I(初始狀態(tài)),但是此時會員帳戶余額100,會員肯定會馬上找京東罵京東,為啥不給老子發(fā)貨,我都付錢了

    2:訂單系統(tǒng)調(diào)用支付系統(tǒng)成功,狀態(tài)也已經(jīng)更新成功,但是通知倉庫發(fā)貨失敗,這個時候訂單是P(已支付)狀態(tài),此時會員帳戶余額是100,但是倉庫不會發(fā)貨。會員也要罵京東。

    3:訂單系統(tǒng)調(diào)用支付系統(tǒng)成功,狀態(tài)也已經(jīng)更新成功,然后通知倉庫發(fā)貨,倉庫告訴訂單系統(tǒng),沒有貨了。這個時候數(shù)據(jù)狀態(tài)和第二種情況一樣。

     

    對于問題一,我們來分析一下解決方案,能想到的解決方案如下

    1 假設(shè)調(diào)用支付系統(tǒng)支付訂單的時候先不扣錢,訂單狀態(tài)更新完成之后,在通知支付系統(tǒng)你扣錢

    如果采用這種設(shè)計方案,那么在同一時刻,這個用戶,又支付了另外一筆訂單,訂單價格200,順利完成了整個訂單支付流程,由于當前訂單的狀態(tài)已經(jīng)變成了支付成功,但是實際用戶已經(jīng)沒有錢支付了,這筆訂單的狀態(tài)就不一致了。即使用戶在同一個時刻沒有進行另外的訂單支付行為,通知支付系統(tǒng)扣錢這個動作也有可能完不成,因為也有可能失敗,反而增加了系統(tǒng)的復(fù)雜性。

     

    2 訂單系統(tǒng)自動發(fā)起重試,多重試幾次,例如三次,直到扣款成功為止。

    這個看起來也是不錯的考慮,但是和解決方案一樣,解決不了問題,還會帶來新的問題,假設(shè)訂單系統(tǒng)第一次調(diào)用支付系統(tǒng)成功,但是沒有辦法收到應(yīng)答,訂單系統(tǒng)又發(fā)起調(diào)用,完了,重復(fù)支付,一次訂單支付了200。

    假設(shè)支付系統(tǒng)正在發(fā)布,你重試多少次都一樣,都會失敗。這個時候用戶在等待,你怎么處理?

     

    3 在第二種方案的基礎(chǔ)上,我們先解決訂單的重復(fù)支付行為,我們需要在支付系統(tǒng)上對訂單號進行控制,一筆訂單如果已經(jīng)支付成功,不能在進行支付。返回重復(fù)支付標識。那么訂單系統(tǒng)根據(jù)返回的標識,更新訂單狀態(tài)。

    接下來解決重試問題,我們假設(shè)應(yīng)用上重試三次,如果三次都失敗,先返回給用戶提示支付結(jié)果未知。假設(shè)這個時候用戶重新發(fā)起支付,訂單系統(tǒng)調(diào)用支付系統(tǒng),發(fā)現(xiàn)訂單已經(jīng)支付,那么繼續(xù)下面的流程。如果會員沒有發(fā)起支付,系統(tǒng)定時(一分鐘一次)去核對訂單狀態(tài),如果發(fā)現(xiàn)已經(jīng)被支付,則繼續(xù)后續(xù)的流程。

     

    這種方案,用戶體驗非常差,告訴用戶支付結(jié)果未知,用戶一定會罵你,你丫咋回事情,我明明支付了,你告訴我未知。假設(shè)告訴用戶支付失敗,萬一實際是成功的咋辦。你告訴用戶支付成功,萬一支付失敗咋辦。

     

    4 第三種方案能夠解決訂單和支付數(shù)據(jù)的一致性問題,但是用戶體驗非常差。當然這種情況比較可能是少數(shù),可以犧牲這一部分的用戶體驗,我們還有沒有更好的解決方案,既能照顧用戶體驗,又能夠保證資金的安全性。

    我們再回來看看第一種方案,我們先不扣錢,但是有木有辦法讓這一部分錢不讓用戶使用,對了,我們先把這一部分錢凍結(jié)起來,訂單系統(tǒng)先調(diào)用支付系統(tǒng)成功的時候,支付系統(tǒng)先不扣錢,而是先把錢凍結(jié)起來,不讓用戶給其他訂單支付,然后等訂單系統(tǒng)把訂單狀態(tài)更新為支付成功的時候,再通知支付系統(tǒng),你扣錢吧,這個時候支付系統(tǒng)扣錢,完成后續(xù)的操作。

     

    看起來這個方案不錯,我們仔細在分析一下流程,這個方案還存在什么問題,假設(shè)訂單系統(tǒng)在調(diào)用支付系統(tǒng)凍結(jié)的時候,支付系統(tǒng)凍結(jié)成功,但是訂單系統(tǒng)超時,這個時候返回給用戶,告知用戶支付失敗,如果用戶再次支付這筆訂單,那么由于支付系統(tǒng)進行控制,告訴訂單系統(tǒng)凍結(jié)成功,訂單系統(tǒng)更新狀態(tài),然后通知支付系統(tǒng),扣錢吧。如果這個時候通知失敗,木有問題,反正錢都已經(jīng)是凍結(jié)的了,用戶不能用,我只要定時掃描訂單和支付狀態(tài),進行扣錢而已。

     

    那么如果變態(tài)的用戶重新拍下來一筆訂單,100塊錢,對新的訂單進行支付,這個時候由于先前那一筆訂單的錢被凍結(jié)了,這個時候用戶余額剩余100,凍結(jié)100,發(fā)現(xiàn)可用的余額足夠,那就直接在對用戶扣錢。這個時候余額剩余0,凍結(jié)100。先前那一筆怎么辦,一個辦法就是定時掃描,發(fā)現(xiàn)訂單狀態(tài)是初始的話,就對用戶的支付余額進行解凍處理。這個時候用戶的余額變成100,訂單數(shù)據(jù)和支付數(shù)據(jù)又一致了。假設(shè)原先用戶余額只有100,被凍結(jié)了,用戶重新下單,支付的時候就失敗了啊,的確會發(fā)生這一種情況,所以要盡可能的保證在第一次訂單結(jié)果不明確的情況,盡早解凍用戶余額,比如10秒之內(nèi)。但是不管如何快速,總有數(shù)據(jù)不一致的時刻,這個是沒有辦法避免的。

     

    第二種情況和第三種情況如何處理,下次在分析吧。

    由于互聯(lián)網(wǎng)目前越來越強調(diào)分布式架構(gòu),如果是交易類系統(tǒng),面臨的將會是分布式事務(wù)上的挑戰(zhàn)。當然目前有很多開源的分布式事務(wù)產(chǎn)品,例如java JPA,但是這種解決方案的成本是非常高的,而且實現(xiàn)起來非常復(fù)雜,效率也比較低下。對于極端的情況:例如發(fā)布,故障的時候都是沒有辦法保證強一致性的。

     

    轉(zhuǎn)載自:http://www.cnblogs.com/aigongsi/archive/2012/09/22/2698055.html

    發(fā)布于 1年前, 閱讀(41) | 評論(0) | 投票(0) | 收藏(1) 閱讀全文...
  • 292012-11
    關(guān)于分布式系統(tǒng)的數(shù)據(jù)一致性問題(一)

     

    先把問題簡單化處理,假設(shè)A增加一條記錄Message_A,發(fā)送到M,B增加一條記錄 MESSAGE_B發(fā)送到M,都是通過MQ服務(wù)器進行轉(zhuǎn)發(fā),那么M系統(tǒng)接收到條消息,增加兩條數(shù)據(jù),那么M在把增加的消息群發(fā)給A,B,A和B找到自己缺失的數(shù)據(jù),更新數(shù)據(jù)庫。這樣就完成了一個數(shù)據(jù)的同步。

     

    從正常情況下來看,都沒有問題,邏輯完全合理,但是請考慮以下三個問題

    1 如何保證A->M的消息,M一定接收到了,同樣,如何保證M->A的消息,M一定接收到了

    2 如果數(shù)據(jù)需要一致性更新,比如A發(fā)送了三條消息給M,M要么全部保存,要么全部不保存,不能夠只保存其中的幾條記錄。我們假設(shè)更新的數(shù)據(jù)是一條條發(fā)送的。

    3 假設(shè)同時A發(fā)送了多條更新請求,如何保證順序性要求?

     

    這兩個問題就是分布式環(huán)境下數(shù)據(jù)一致性的問題

    對于第一個問題,比較好解決,我們先看看一個tcp/ip協(xié)議鏈接建立的過程

    我們的思路可以從這個上面出發(fā),在簡化一下,就一個請求,一個應(yīng)答。

    簡單的通信模型是這樣的

    A->M : 你收到我的一條消息沒有,消息的ID是12345

    M->A:  我收到了你的一條消息數(shù)據(jù),消息數(shù)據(jù)是ID;12345

    這樣就一個請求,一個應(yīng)答,就完成了一次可靠性的傳輸。如果A一致沒有收到M的應(yīng)答,就不斷的重試。這個時候M就必須保證冪等性。不能重復(fù)的處理消息。那么最極端的情況是,怎么也收不到M的應(yīng)答,這個時候是系統(tǒng)故障。自己檢查一下吧。

    這么設(shè)計就要求,A在發(fā)送消息的時候持久化這個消息的數(shù)據(jù)內(nèi)容,然后不斷的重試,一旦接收到M的應(yīng)答,就刪除這條消息。同樣,M端也是一樣的。不要相信MQ的持久化機制,不是很靠譜的。

    那么M給A發(fā)送消息也采取類似的原理就可以了。

     

    下面在看看第二個問題,如何保持數(shù)據(jù)的一致性更新,這個還是可以參考TCP/IP的協(xié)議。

    首先A發(fā)送一條消息給M:我要發(fā)送一批消息數(shù)據(jù)給你,批次號是10000,數(shù)據(jù)是5條。

    M發(fā)送一條消息給A:ok,我準備好了,批次號是10000,發(fā)送方你A

    接著A發(fā)送5條消息給M,消息ID分別為1,2,3,4,5 ,批次號是10000,

    緊接著,A發(fā)送一個信息給M:我已經(jīng)完成5小消息的發(fā)送,你要提交數(shù)據(jù)更新了

     

    接下來可能發(fā)送兩種情況

    1 那么M發(fā)送消息給A:ok,我收到了5條消息,開始提交數(shù)據(jù)

    2 那么M也可以發(fā)送給A:我收到了5條消息,但是還缺少,請你重新發(fā)送,那么A就繼續(xù)發(fā)送,直到A收到M成功的應(yīng)答。

    整個過程相當復(fù)雜。這個也就是數(shù)據(jù)一旦分布了,帶來最大的問題就是數(shù)據(jù)一致性的問題。這個成本非常高。

     

    對于第三個問題,這個就比較復(fù)雜了

    這個最核心的問題就是消息的順序性,我們只能在每個消息發(fā)一個消息的序列號,但是還是沒有最好解決這個問題的辦法。因為消息接收方不知道順序。因為即使給他了序列號,也沒有辦法告訴他,這個應(yīng)該何時處理。最好的辦法是在第二種方式的基礎(chǔ)作為一個批次來更新。

     

    這個只是以最簡單的例子來說明一下分布式系統(tǒng)的要保證數(shù)據(jù)一致性是一件代價很大的事情。當然有的博主會說,這個何必這么復(fù)雜,直接數(shù)據(jù)庫同步不就可以了。這個例子當然是沒有問題的,萬一這個幾個庫的模型都不一樣,我發(fā)送消息要處理的事情不一樣的。怎么辦?

     

    轉(zhuǎn)載自:http://www.cnblogs.com/aigongsi/archive/2012/09/21/2696773.html


    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多