欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
NoSQL數據庫的分布式算法

NoSQL數據庫的分布式算法

270人收藏此文章, 我要收藏 發(fā)表于4個(gè)月前(2012-11-09 16:06) , 已有8820次閱讀 ,共28個(gè)評論

本文另一地址請見(jiàn)NoSQL數據庫的分布式算法

本文譯自 Distributed Algorithms in NoSQL Databases

系統的可擴展性是推動(dòng)NoSQL運動(dòng)發(fā)展的的主要理由,包含了分布式系統協(xié)調,故障轉移,資源管理和許多其他特性。這么講使得NoSQL聽(tīng)起來(lái)像是一個(gè)大筐,什么都能塞進(jìn)去。盡管NoSQL運動(dòng)并沒(méi)有給分布式數據處理帶來(lái)根本性的技術(shù)變革,但是依然引發(fā)了鋪天蓋地的關(guān)于各種協(xié)議和算法的研究以及實(shí)踐。正是通過(guò)這些嘗試逐漸總結出了一些行之有效的數據庫構建方法。在這篇文章里,我將針對NoSQL數據庫的分布式特點(diǎn)進(jìn)行一些系統化的描述。

接下來(lái)我們將研究一些分布式策略,比如故障檢測中的復制,這些策略用黑體字標出,被分為三段:

  • 數據一致性。NoSQL需要在分布式系統的一致性,容錯性和性能,低延遲及高可用之間作出權衡,一般來(lái)說(shuō),數據一致性是一個(gè)必選項,所以這一節主要是關(guān)于數據復制數據恢復。
  • 數據放置。一個(gè)數據庫產(chǎn)品應該能夠應對不同的數據分布,集群拓撲和硬件配置。在這一節我們將討論如何分布以及調整數據分布才能夠能夠及時(shí)解決故障,提供持久化保證,高效查詢(xún)和保證集群中的資源(如內存和硬盤(pán)空間)得到均衡使用。
  • 對等系統。像 leader election 這樣的的技術(shù)已經(jīng)被用于多個(gè)數據庫產(chǎn)品以實(shí)現容錯和數據強一致性。然而,即使是分散的的數據庫(無(wú)中心)也要跟蹤它們的全局狀態(tài),檢測故障和拓撲變化。這一節將介紹幾種使系統保持一致?tīng)顟B(tài)的技術(shù)。

數據一致性

眾所周知,分布式系統經(jīng)常會(huì )遇到網(wǎng)絡(luò )隔離或是延遲的情況,在這種情況下隔離的部分是不可用的,因此要保持高可用性而不犧牲一致性是不可能的。這一事實(shí)通常被稱(chēng)作“CAP理論”。然而,一致性在分布式系統中是一個(gè)非常昂貴的東西,所以經(jīng)常需要在這上面做一些讓步,不只是針對可用性,還有多種權衡。為了研究這些權衡,我們注意到分布式系統的一致性問(wèn)題是由數據隔離和復制引起的,所以我們將從研究復制的特點(diǎn)開(kāi)始:

  • 可用性。在網(wǎng)絡(luò )隔離的情況下剩余部分仍然可以應對讀寫(xiě)請求。
  • 讀寫(xiě)延遲。讀寫(xiě)請求能夠在短時(shí)間內處理。
  • 讀寫(xiě)延展性。讀寫(xiě)的壓力可由多個(gè)節點(diǎn)均衡分擔。
  • 容錯性。對于讀寫(xiě)請求的處理不依賴(lài)于任何一個(gè)特定節點(diǎn)。
  • 數據持久性。特定條件下的節點(diǎn)故障不會(huì )造成數據丟失。
  • 一致性。一致性比前面幾個(gè)特性都要復雜得多,我們需要詳細討論一下幾種不同的觀(guān)點(diǎn)。 但是我們不會(huì )涉及過(guò)多的一致性理論和并發(fā)模型,因為這已經(jīng)超出了本文的范疇,我只會(huì )使用一些簡(jiǎn)單特點(diǎn)構成的精簡(jiǎn)體系。
    • 讀寫(xiě)一致性。從讀寫(xiě)的觀(guān)點(diǎn)來(lái)看,數據庫的基本目標是使副本趨同的時(shí)間盡可能短(即更新傳遞到所有副本的時(shí)間),保證最終一致性。除了這個(gè)較弱的保證,還有一些更強的一致性特點(diǎn):
      • 寫(xiě)后讀一致性。在數據項X上寫(xiě)操作的效果總是能夠被后續的X上的讀操作看見(jiàn)。
      • 讀后讀一致性。在一次對數據項X的讀操作之后,后續對X的讀操作應該返回與第一次的返回值相同或是更加新的值。
    • 寫(xiě)一致性。分區的數據庫經(jīng)常會(huì )發(fā)生寫(xiě)沖突。數據庫應當能處理這種沖突并保證多個(gè)寫(xiě)請求不會(huì )被不同的分區所處理。這方面數據庫提供了幾種不同的一致性模型:
      • 原子寫(xiě)。假如數據庫提供了API,一次寫(xiě)操作只能是一個(gè)單獨的原子性的賦值,避免寫(xiě)沖突的辦法是找出每個(gè)數據的“最新版本”。這使得所有的節點(diǎn)都能夠在更新結束時(shí)獲得同一版本,而與更新的順序無(wú)關(guān),網(wǎng)絡(luò )故障和延遲經(jīng)常造成各節點(diǎn)更新順序不一致。 數據版本可以用時(shí)間戳或是用戶(hù)指定的值來(lái)表示。Cassandra用的就是這種方法。
      • 原子化的讀-改-寫(xiě)。應用有時(shí)候需要進(jìn)行 讀-改-寫(xiě) 序列操作而非單獨的原子寫(xiě)操作。假如有兩個(gè)客戶(hù)端讀取了同一版本的數據,修改并且把修改后的數據寫(xiě)回,按照原子寫(xiě)模型,時(shí)間上比較靠后的那一次更新將會(huì )覆蓋前一次。這種行為在某些情況下是不正確的(例如,兩個(gè)客戶(hù)端往同一個(gè)列表值中添加新值)。數據庫提供了至少兩種解決方法:
        • 沖突預防。 讀-改-寫(xiě) 可以被認為是一種特殊情況下的事務(wù),所以分布式鎖或是 PAXOS [20, 21] 這樣的一致協(xié)議都可以解決這種問(wèn)題。這種技術(shù)支持原子讀改寫(xiě)語(yǔ)義和任意隔離級別的事務(wù)。另一種方法是避免分布式的并發(fā)寫(xiě)操作,將對特定數據項的所有寫(xiě)操作路由到單個(gè)節點(diǎn)上(可以是全局主節點(diǎn)或者分區主節點(diǎn))。為了避免沖突,數據庫必須犧牲網(wǎng)絡(luò )隔離情況下的可用性。這種方法常用于許多提供強一致性保證的系統(例如大多數關(guān)系數據庫,HBase,MongoDB)。
        • 沖突檢測。數據庫跟蹤并發(fā)更新的沖突,并選擇回滾其中之一或是維持兩個(gè)版本交由客戶(hù)端解決。并發(fā)更新通常用向量時(shí)鐘 [19] (這是一種樂(lè )觀(guān)鎖)來(lái)跟蹤,或者維護一個(gè)完整的版本歷史。這個(gè)方法用于 Riak, Voldemort, CouchDB.

現在讓我們仔細看看常用的復制技術(shù),并按照描述的特點(diǎn)給他們分一下類(lèi)。第一幅圖描繪了不同技術(shù)之間的邏輯關(guān)系和不同技術(shù)在系統的一致性、擴展性、可用性、延遲性之間的權衡坐標。 第二張圖詳細描繪了每個(gè)技術(shù)。

復本因子是4。讀寫(xiě)協(xié)調者可以是一個(gè)外部客戶(hù)端或是一個(gè)內部代理節點(diǎn)。

我們會(huì )依據一致性從弱到強把所有的技術(shù)過(guò)一遍:

  • (A, 反熵) 一致性最弱,基于策略如下。寫(xiě)操作的時(shí)候選擇任意一個(gè)節點(diǎn)更新,在讀的時(shí)候如果新數據還沒(méi)有通過(guò)后臺的反熵協(xié)議傳遞到讀的那個(gè)節點(diǎn),那么讀到的仍然是舊數據。(下一節會(huì )詳細介紹反熵協(xié)議)。這種方法的主要特點(diǎn)是:
    • 過(guò)高的傳播延遲使它在數據同步方面不太好用,所以比較典型的用法是只作為輔助性的功能來(lái)檢測和修復計劃外的不一致。Cassandra就使用了反熵算法來(lái)在各節點(diǎn)之間傳遞數據庫拓撲和其他一些元數據信息。
    • 一致性保證較弱:即使在沒(méi)有發(fā)生故障的情況下,也會(huì )出現寫(xiě)沖突與讀寫(xiě)不一致。
    • 在網(wǎng)絡(luò )隔離下的高可用和健壯性。用異步的批處理替代了逐個(gè)更新,這使得性能表現優(yōu)異。
    • 持久性保障較弱因為新的數據最初只有單個(gè)副本。
  • (B) 對上面模式的一個(gè)改進(jìn)是在任意一個(gè)節點(diǎn)收到更新數據請求的同時(shí)異步的發(fā)送更新給所有可用節點(diǎn)。這也被認為是定向的反熵。
    • 與純粹的反熵相比,這種做法只用一點(diǎn)小小的性能犧牲就極大地提高了一致性。然而,正式一致性和持久性保持不變。
    • 假如某些節點(diǎn)因為網(wǎng)絡(luò )故障或是節點(diǎn)失效在當時(shí)是不可用的,更新最終也會(huì )通過(guò)反熵傳播過(guò)程來(lái)傳遞到該節點(diǎn)。
  • (C) 在前一個(gè)模式中,使用提示移交技術(shù) [8] 可以更好地處理某個(gè)節點(diǎn)的操作失敗。對于失效節點(diǎn)的預期更新被記錄在額外的代理節點(diǎn)上,并且標明一旦特點(diǎn)節點(diǎn)可用就要將更新傳遞給該節點(diǎn)。這樣做提高了一致性,降低了復制收斂時(shí)間。
  • (D, 一次性讀寫(xiě))因為提示移交的責任節點(diǎn)也有可能在將更新傳遞出去之前就已經(jīng)失效,在這種情況下就有必要通過(guò)所謂的讀修復來(lái)保證一致性。每個(gè)讀操作都會(huì )啟動(dòng)一個(gè)異步過(guò)程,向存儲這條數據的所有節點(diǎn)請求一份數據摘要(像簽名或者hash),如果發(fā)現各節點(diǎn)返回的摘要不一致則統一各節點(diǎn)上的數據版本。我們用一次性讀寫(xiě)來(lái)命名組合了A、B、C、D的技術(shù)- 他們都沒(méi)有提供嚴格的一致性保證,但是作為一個(gè)自備的方法已經(jīng)可以用于實(shí)踐了。
  • (E, 讀若干寫(xiě)若干) 上面的策略是降低了復制收斂時(shí)間的啟發(fā)式增強。為了保證更強的一致性,必須犧牲可用性來(lái)保證一定的讀寫(xiě)重疊。 通常的做法是同時(shí)寫(xiě)入W個(gè)副本而不是一個(gè),讀的時(shí)候也要讀R個(gè)副本。
    • 首先,可以配置寫(xiě)副本數W>1。
    • 其次,因為R+W>N,寫(xiě)入的節點(diǎn)和讀取的節點(diǎn)之間必然會(huì )有重疊,所以讀取的多個(gè)數據副本里至少會(huì )有一個(gè)是比較新的數據(上面的圖中 W=2, R=3, N=4 )。這樣在讀寫(xiě)請求依序進(jìn)行的時(shí)候(寫(xiě)執行完再讀)能夠保證一致性(對于單個(gè)用戶(hù)的讀寫(xiě)一致性),但是不能保障全局的讀一致性。用下面圖示里的例子來(lái)看,R=2,W=2,N=3,因為寫(xiě)操作對于兩個(gè)副本的更新是非事務(wù)的,在更新沒(méi)有完成的時(shí)候讀就可能讀到兩個(gè)都是舊值或者一新一舊:

    • 對于某種讀延遲的要求,設置R和W的不同值可以調整寫(xiě)延遲與持久性,反之亦然。
  • 如果W<=N/2,并發(fā)的多個(gè)寫(xiě)入會(huì )寫(xiě)到不同的若干節點(diǎn)(如,寫(xiě)操作A寫(xiě)前N/2個(gè),B寫(xiě)后N/2個(gè))。 設置 W>N/2 可以保證在符合回滾模型的原子讀改寫(xiě)時(shí)及時(shí)檢測到?jīng)_突。
    • 嚴格來(lái)講,這種模式雖然可以容忍個(gè)別節點(diǎn)的失效, 但是對于網(wǎng)絡(luò )隔離的容錯性并不好。在實(shí)踐中,常使用”近似數量通過(guò)“這樣的方法,通過(guò)犧牲一致性來(lái)提高某些情景下的可用性。
  • (F, 讀全部寫(xiě)若干)讀一致性問(wèn)題可以通過(guò)在讀數據的時(shí)候訪(fǎng)問(wèn)所有副本(讀數據或者檢查摘要)來(lái)減輕。這確保了只要有至少一個(gè)節點(diǎn)上的數據更新新的數據就能被讀取者看到。但是在網(wǎng)絡(luò )隔離的情況下這種保證就不能起到作用了。
  • (G, 主從) 這種技術(shù)常被用來(lái)提供原子寫(xiě)或者 沖突檢測持久級別的讀改寫(xiě)。為了實(shí)現沖突預防級別,必須要用一種集中管理方式或者是鎖。最簡(jiǎn)單的策略是用主從異步復制。對于特定數據項的寫(xiě)操作全部被路由到一個(gè)中心節點(diǎn),并在上面順序執行。這種情況下主節點(diǎn)會(huì )成為瓶頸,所以必須要將數據劃分成一個(gè)個(gè)獨立的片區(不同片有不同的master),這樣才能提供擴展性。
  • (H, Transactional Read Quorum Write Quorum and Read One Write All)  更新多個(gè)副本的方法可以通過(guò)使用事務(wù)控制技術(shù)來(lái)避免寫(xiě)沖突。 眾所周知的方法是使用兩階段提交協(xié)議。但兩階段提交并不是完全可靠的,因為協(xié)調者失效可能會(huì )造成資源阻塞。 PAXOS提交協(xié)議 [20, 21] 是更可靠的選擇,但會(huì )損失一點(diǎn)性能。 在這個(gè)基礎上再向前一小步就是讀一個(gè)副本寫(xiě)所有副本,這種方法把所有副本的更新放在一個(gè)事務(wù)中,它提供了強容錯一致性但會(huì )損失掉一些性能和可用性。

上面分析中的一些權衡有必要再強調一下:

  • 一致性與可用性。 嚴密的權衡已經(jīng)由CAP理論給出了。在網(wǎng)絡(luò )隔離的情況下,數據庫要么將數據集中,要么既要接受數據丟失的風(fēng)險。
  • 一致性與擴展性。 看得出即使讀寫(xiě)一致性保證降低了副本集的擴展性,只有在原子寫(xiě)模型中才可以以一種相對可擴展的方式處理寫(xiě)沖突。原子讀改寫(xiě)模型通過(guò)給數據加上臨時(shí)性的全局鎖來(lái)避免沖突。這表明, 數據或操作之間的依賴(lài),即使是很小范圍內或很短時(shí)間的,也會(huì )損害擴展性。所以精心設計數據模型,將數據分片分開(kāi)存放對于擴展性非常重要。
  • 一致性與延遲。 如上所述,當數據庫需要提供強一致性或者持久性的時(shí)候應該偏向于讀寫(xiě)所有副本技術(shù)。但是很明顯一致性與請求延遲成反比,所以使用若干副本技術(shù)會(huì )是比較中允的辦法。
  • 故障轉移與一致性/擴展性/延遲。有趣的是容錯性與一致性、擴展性、延遲的取舍沖突并不劇烈。通過(guò)合理的放棄一些性能與一致性,集群可以容忍多達 up to 的節點(diǎn)失效。這種折中在兩階段提交與 PAXOS 協(xié)議的區別里體現得很明顯。這種折中的另一個(gè)例子是增加特定的一致性保障,比如使用嚴格會(huì )話(huà)進(jìn)程的“讀己所寫(xiě)”,但這又增加了故障轉移的復雜性 [22]。

反熵協(xié)議, 謠言傳播算法

讓我們從以下場(chǎng)景開(kāi)始:

有許多節點(diǎn),每條數據會(huì )在其中的若干的節點(diǎn)上面存有副本。每個(gè)節點(diǎn)都可以單獨處理更新請求,每個(gè)節點(diǎn)定期和其他節點(diǎn)同步狀態(tài),如此一段時(shí)間之后所有的副本都會(huì )趨向一致。同步過(guò)程是怎樣進(jìn)行的?同步何時(shí)開(kāi)始?怎樣選擇同步的對象?怎么交換數據?我們假定兩個(gè)節點(diǎn)總是用較新版本的數據覆蓋舊的數據或者兩個(gè)版本都保留以待應用層處理。

這個(gè)問(wèn)題常見(jiàn)于數據一致性維護和集群狀態(tài)同步(如集群成員信息傳播)等場(chǎng)景。雖然引入一個(gè)監控數據庫并制定同步計劃的協(xié)調者可以解決這個(gè)問(wèn)題,但是去中心化的數據庫能夠提供更好的容錯性。去中心化的主要做法是利用精心設計的傳染協(xié)議[7],這種協(xié)議相對簡(jiǎn)單,但是提供了很好的收斂時(shí)間,而且能夠容忍任何節點(diǎn)的失效和網(wǎng)絡(luò )隔離。盡管有許多類(lèi)型的傳染算法,我們只關(guān)注反熵協(xié)議,因為NoSQL數據庫都在使用它。

反熵協(xié)議假定同步會(huì )按照一個(gè)固定進(jìn)度表執行,每個(gè)節點(diǎn)定期隨機或是按照某種規則選擇另外一個(gè)節點(diǎn)交換數據,消除差異。有三種反風(fēng)格的反熵協(xié)議:推,拉和混合。推協(xié)議的原理是簡(jiǎn)單選取一個(gè)隨機節點(diǎn)然后把數據狀態(tài)發(fā)送過(guò)去。在真實(shí)應用中將全部數據都推送出去顯然是愚蠢的,所以節點(diǎn)一般按照下圖所示的方式工作。

節點(diǎn)A作為同步發(fā)起者準備好一份數據摘要,里面包含了A上數據的指紋。節點(diǎn)B接收到摘要之后將摘要中的數據與本地數據進(jìn)行比較,并將數據差異做成一份摘要返回給A。最后,A發(fā)送一個(gè)更新給B,B再更新數據。拉方式和混合方式的協(xié)議與此類(lèi)似,就如上圖所示的。

反熵協(xié)議提供了足夠好的收斂時(shí)間和擴展性。下圖展示了一個(gè)在100個(gè)節點(diǎn)的集群中傳播一個(gè)更新的模擬結果。在每次迭代中,每個(gè)節點(diǎn)只與一個(gè)隨機選取的對等節點(diǎn)發(fā)生聯(lián)系。

可以看到,拉方式的收斂性比推方式更好,這可以從理論上得到證明[7]。而且推方式還存在一個(gè)“收斂尾巴”的問(wèn)題。在多次迭代之后,盡管幾乎遍歷到了所有的節點(diǎn),但還是有很少的一部分沒(méi)受到影響。與單純的推和拉方式相比, 混合方式的效率更高,所以實(shí)際應用中通常使用這種方式。反熵是可擴展的,因為平均轉換時(shí)間以集群規模的對數函數形式增長(cháng)。

盡管這些技術(shù)看起來(lái)很簡(jiǎn)單,仍然有許多研究關(guān)注于不同約束條件下反熵協(xié)議的性能表現。其中之一通過(guò)一種更有效的結構使用網(wǎng)絡(luò )拓撲來(lái)取代隨機選取 [10] 。在網(wǎng)絡(luò )帶寬有限的條件下調整傳輸率或使用先進(jìn)的規則來(lái)選取要同步的數據 [9]。摘要計算也面臨挑戰,數據庫會(huì )維護一份最近更新的日志以有助于摘要計算。

最終一致數據類(lèi)型Eventually Consistent Data Types

在上一節我們假定兩個(gè)節點(diǎn)總是合并他們的數據版本。但要解決更新沖突并不容易,讓所有副本都最終達到一個(gè)語(yǔ)義上正確的值出乎意料的難。一個(gè)眾所周知的例子是Amazon Dynamo數據庫[8]中已經(jīng)刪除的條目可以重現。

我們假設一個(gè)例子來(lái)說(shuō)明這個(gè)問(wèn)題:數據庫維護一個(gè)邏輯上的全局計數器,每個(gè)節點(diǎn)可以增加或者減少計數。雖然每個(gè)節點(diǎn)可以在本地維護一個(gè)自己的值,但這些本地計數卻不能通過(guò)簡(jiǎn)單的加減來(lái)合并。假設這樣一個(gè)例子:有三個(gè)節點(diǎn)A、B和C,每個(gè)節點(diǎn)執行了一次加操作。如果A從B獲得一個(gè)值,并且加到本地副本上,然后C從B獲得值,然后C再從A獲得值,那么C最后的值是4,而這是錯誤的。解決這個(gè)問(wèn)題的方法是用一個(gè)類(lèi)似于向量時(shí)鐘[19]的數據結構為每個(gè)節點(diǎn)維護一對計數器[1]:

1 class Counter { 2 int[] plus 3 int[] minus 4 int NODE_ID 5 6 increment() { 7 plus[NODE_ID]++ 8 } 9 10 decrement() {11 minus[NODE_ID]++12 }13 14 get() {15 return sum(plus) – sum(minus)16 }17 18 merge(Counter other) {19 for i in 1..MAX_ID {20 plus[i] = max(plus[i], other.plus[i])21 minus[i] = max(minus[i], other.minus[i])22 }

23 }24 }

 

 

Cassandra用類(lèi)似的方法計數[11]。利用基于狀態(tài)的或是基于操作的復制理論也可以設計出更復雜的最終一致的數據結構。例如,[1]中就提及了一系列這樣的數據結構,包括:

  • 計數器(加減操作)
  • 集合(添加和移除操作)
  • 圖(增加邊或頂點(diǎn),移除邊或頂點(diǎn))
  • 列表(插入某位置或者移除某位置)

最終一致數據類(lèi)型的功能通常是有限的,還會(huì )帶來(lái)額外的性能開(kāi)銷(xiāo)。

數據放置

這部分主要關(guān)注控制在分布式數據庫中放置數據的算法。這些算法負責把數據項映射到合適的物理節點(diǎn)上,在節點(diǎn)間遷移數據以及像內存這樣的資源的全局調配。

均衡數據

我們還是從一個(gè)簡(jiǎn)單的協(xié)議開(kāi)始,它可以提供集群節點(diǎn)間無(wú)縫的數據遷移。這常發(fā)生于像集群擴容(加入新節點(diǎn)),故障轉移(一些節點(diǎn)宕機)或是均衡數據(數據在節點(diǎn)間的分布不均衡)這樣的場(chǎng)景。如下圖A中所描繪的場(chǎng)景 - 有三個(gè)節點(diǎn),數據隨便分布在三個(gè)節點(diǎn)上(假設數據都是key-value型)。

如果數據庫不支持數據內部均衡,就要在每個(gè)節點(diǎn)上發(fā)布數據庫實(shí)例,如上面圖B所示。這需要手動(dòng)進(jìn)行集群擴展,停掉要遷移的數據庫實(shí)例,把它轉移到新節點(diǎn)上,再在新節點(diǎn)上啟動(dòng),如圖C所示。盡管數據庫能夠監控到每一條記錄,包括MongoDB, Oracle Coherence, 和還在開(kāi)發(fā)中的 Redis Cluster 在內的許多系統仍然使用的是自動(dòng)均衡技術(shù)。也即,將數據分片并把每個(gè)數據分片作為遷移的最小單位,這是基于效率的考慮。很明顯分片數會(huì )比節點(diǎn)數多,數據分片可以在各節點(diǎn)間平均分布。按照一種簡(jiǎn)單的協(xié)議即可實(shí)現無(wú)縫數據遷移,這個(gè)協(xié)議可以在遷移數據分片的時(shí)候重定向客戶(hù)的數據遷出節點(diǎn)和遷入節點(diǎn)。下圖描繪了一個(gè)Redis Cluster中實(shí)現的get(key)邏輯的狀態(tài)機。

假定每個(gè)節點(diǎn)都知道集群拓撲,能夠把任意key映射到相應的數據分片,把數據分片映射到節點(diǎn)。如果節點(diǎn)判斷被請求的key屬于本地分片,就會(huì )在本地查找(上圖中上面的方框)。假如節點(diǎn)判斷請求的key屬于另一個(gè)節點(diǎn)X,他會(huì )發(fā)送一個(gè)永久重定向命令給客戶(hù)端(上圖中下方的方框)。永久重定向意味著(zhù)客戶(hù)端可以緩存分片和節點(diǎn)間的映射關(guān)系。如果分片遷移正在進(jìn)行,遷出節點(diǎn)和遷入節點(diǎn)會(huì )標記相應的分片并且將分片的數據加鎖逐條加鎖然后開(kāi)始移動(dòng)。遷出節點(diǎn)首先會(huì )在本地查找key,如果沒(méi)有找到,重定向客戶(hù)端到遷入節點(diǎn),假如key已經(jīng)遷移完畢的話(huà)。這種重定向是一次性的,并且不能被緩存。遷入節點(diǎn)在本地處理重定向,但定期查詢(xún)在遷移還沒(méi)完成前被永久重定向。

動(dòng)態(tài)環(huán)境中的數據分片和復制

我們關(guān)注的另一個(gè)問(wèn)題是怎么把記錄映射到物理節點(diǎn)。比較直接的方法是用一張表來(lái)記錄每個(gè)范圍的key與節點(diǎn)的映射關(guān)系,一個(gè)范圍的key對應到一個(gè)節點(diǎn),或者用key的hash值與節點(diǎn)數取模得到的值作為節點(diǎn)ID。但是hash取模的方法在集群發(fā)生更改的情況下就不是很好用,因為增加或者減少節點(diǎn)都會(huì )引起集群內的數據徹底重排。導致很難進(jìn)行復制和故障恢復。

有許多方法在復制和故障恢復的角度進(jìn)行了增強。最著(zhù)名的就是一致性hash。網(wǎng)上已經(jīng)有很多關(guān)于一致性hash的介紹了,所以在這里我只提供一個(gè)基本介紹,僅僅為了文章內容的完整性。下圖描繪了一致性hash的基本原理:

一致性hash從根本上來(lái)講是一個(gè)鍵值映射結構 - 它把鍵(通常是hash過(guò)的)映射到物理節點(diǎn)。鍵經(jīng)過(guò)hash之后的取值空間是一個(gè)有序的定長(cháng)二進(jìn)制字符串,很顯然每個(gè)在此范圍內的鍵都會(huì )被映射到圖A中A、B、C三個(gè)節點(diǎn)中的某一個(gè)。為了副本復制,將取值空間閉合成一個(gè)環(huán),沿環(huán)順時(shí)針前行直到所有副本都被映射到合適的節點(diǎn)上,如圖B所示。換句話(huà)說(shuō),Y將被定位在節點(diǎn)B上,因為它在B的范圍內,第一個(gè)副本應該放置在C,第二個(gè)副本放置在A(yíng),以此類(lèi)推。

這種結構的好處體現在增加或減少一個(gè)節點(diǎn)的時(shí)候,因為它只會(huì )引起臨接區域的數據重新均衡。如圖C所示,節點(diǎn)D的加入只會(huì )對數據項X產(chǎn)生影響而對Y無(wú)影響。同樣,移除節點(diǎn)B(或者B失效)只會(huì )影響Y和X的副本,而不會(huì )對X自身造成影響。但是,正如參考資料[8]中所提到的,這種做法在帶來(lái)好處的同時(shí)也有弱點(diǎn),那就是重新均衡的負擔都由鄰節點(diǎn)承受了,它們將移動(dòng)大量的數據。通過(guò)將每個(gè)節點(diǎn)映射到多個(gè)范圍而不是一個(gè)范圍可以一定程度上減輕這個(gè)問(wèn)題帶來(lái)的不利影響,如圖D所示。這是一個(gè)折中,它避免了重新均衡數據時(shí)負載過(guò)于集中,但是與基于模塊的映射相比,保持了總均衡數量適當降低。

給大規模的集群維護一個(gè)完整連貫的hash環(huán)很不容易。對于相對小一點(diǎn)的數據庫集群就不會(huì )有問(wèn)題,研究如何在對等網(wǎng)絡(luò )中將數據放置與網(wǎng)絡(luò )路由結合起來(lái)很有意思。一個(gè)比較好的例子是Chord算法,它使環(huán)的完整性讓步于單個(gè)節點(diǎn)的查找效率。Chord算法也使用了環(huán)映射鍵到節點(diǎn)的理念,在這方面和一致性hash很相似。不同的是,一個(gè)特定節點(diǎn)維護一個(gè)短列表,列表中的節點(diǎn)在環(huán)上的邏輯位置是指數增長(cháng)的(如下圖)。這使得可以使用二分搜索只需要幾次網(wǎng)絡(luò )跳躍就可以定位一個(gè)鍵。

這張圖畫(huà)的是一個(gè)由16個(gè)節點(diǎn)組成的集群,描繪了節點(diǎn)A是如何查找放在節點(diǎn)D上的key的。 (A) 描繪了路由,(B) 描繪了環(huán)針對節點(diǎn)A、B、C的局部圖像。在參考資料[15]中有更多關(guān)于分散式系統中的數據復制的內容。

按照多個(gè)屬性的數據分片

當只需要通過(guò)主鍵來(lái)訪(fǎng)問(wèn)數據的時(shí)候,一致性hash的數據放置策略很有效,但是當需要按照多個(gè)屬性來(lái)查詢(xún)的時(shí)候事情就會(huì )復雜得多。一種簡(jiǎn)單的做法(MongoDB使用的)是用主鍵來(lái)分布數據而不考慮其他屬性。這樣做的結果是依據主鍵的查詢(xún)可以被路由到接個(gè)合適的節點(diǎn)上,但是對其他查詢(xún)的處理就要遍歷集群的所有節點(diǎn)。查詢(xún)效率的不均衡造成下面的問(wèn)題:

有一個(gè)數據集,其中的每條數據都有若干屬性和相應的值。是否有一種數據分布策略能夠使得限定了任意多個(gè)屬性的查詢(xún)會(huì )被交予盡量少的幾個(gè)節點(diǎn)執行?

HyperDex數據庫提供了一種解決方案?;舅枷胧前衙總€(gè)屬性視作多維空間中的一個(gè)軸,將空間中的區域映射到物理節點(diǎn)上。一次查詢(xún)會(huì )被對應到一個(gè)由空間中多個(gè)相鄰區域組成的超平面,所以只有這些區域與該查詢(xún)有關(guān)。讓我們看看參考資料[6]中的一個(gè)例子:

每一條數據都是一條用戶(hù)信息,有三個(gè)屬性First Name 、Last Name 和Phone Number。這些屬性被視作一個(gè)三維空間,可行的數據分布策略是將每個(gè)象限映射到一個(gè)物理節點(diǎn)。像“First Name = John”這樣的查詢(xún)對應到一個(gè)貫穿4個(gè)象限的平面,也即只有4個(gè)節點(diǎn)會(huì )參與處理此次查詢(xún)。有兩個(gè)屬性限制的查詢(xún)對應于一條貫穿兩個(gè)象限的直線(xiàn),如上圖所示,因此只有2個(gè)節點(diǎn)會(huì )參與處理。

這個(gè)方法的問(wèn)題是空間象限會(huì )呈屬性數的指數函數增長(cháng)。結果就會(huì )是,只有幾個(gè)屬性限制的查詢(xún)會(huì )投射到許多個(gè)空間區域,也即許多臺服務(wù)器。將一個(gè)屬性較多的數據項拆分成幾個(gè)屬性相對較少的子項,并將每個(gè)子項都映射到一個(gè)獨立的子空間,而不是將整條數據映射到一個(gè)多維空間,這樣可以一定程度上緩解這個(gè)問(wèn)題:

這樣能夠提供更好的查詢(xún)到節點(diǎn)的映射,但是增加了集群協(xié)調的復雜度,因為這種情況下一條數據會(huì )散布在多個(gè)獨立的子空間,而每個(gè)子空間都對應各自的若干個(gè)物理節點(diǎn),數據更新時(shí)就必須考慮事務(wù)問(wèn)題。參考資料 [6]有這種技術(shù)的更多介紹和實(shí)現細節。

鈍化副本

有的應用有很強的隨機讀取要求,這就需要把所有數據放在內存里。在這種情況下,將數據分片并把每個(gè)分片主從復制通常需要兩倍以上的內存,因為每個(gè)數據都要在主節點(diǎn)和從節點(diǎn)上各有一份。為了在主節點(diǎn)失效的時(shí)候起到代替作用,從節點(diǎn)上的內存大小應該和主節點(diǎn)一樣。如果系統能夠容忍節點(diǎn)失效的時(shí)候出現短暫中斷或性能下降,也可以不要分片。

下面的圖描繪了4個(gè)節點(diǎn)上的16個(gè)分片,每個(gè)分片都有一份在內存里,副本存在硬盤(pán)上:

灰色箭頭突出了節點(diǎn)2上的分片復制。其他節點(diǎn)上的分片也是同樣復制的。紅色箭頭描繪了在節點(diǎn)2失效的情況下副本怎樣加載進(jìn)內存。集群內副本的均勻分布使得只需要預留很少的內存就可以存放節點(diǎn)失效情況下激活的副本。在上面的圖里,集群只預留了1/3的內存就可以承受單個(gè)節點(diǎn)的失效。特別要指出的是副本的激活(從硬盤(pán)加載入內存)會(huì )花費一些時(shí)間,這會(huì )造成短時(shí)間的性能下降或者正在恢復中的那部分數據服務(wù)中斷。

系統協(xié)調

在這部分我們將討論與系統協(xié)調相關(guān)的兩種技術(shù)。分布式協(xié)調是一個(gè)比較大的領(lǐng)域,數十年以來(lái)有很多人對此進(jìn)行了深入的研究。這篇文章里只涉及兩種已經(jīng)投入實(shí)用的技術(shù)。關(guān)于分布式鎖,consensus協(xié)議以及其他一些基礎技術(shù)的內容可以在很多書(shū)或者網(wǎng)絡(luò )資源中找到,也可以去看參考資料[17, 18, 21]。

故障檢測

故障檢測是任何一個(gè)擁有容錯性的分布式系統的基本功能。實(shí)際上所有的故障檢測協(xié)議都基于心跳通訊機制,原理很簡(jiǎn)單,被監控的組件定期發(fā)送心跳信息給監控進(jìn)程(或者由監控進(jìn)程輪詢(xún)被監控組件),如果有一段時(shí)間沒(méi)有收到心跳信息就被認為失效了。除此之外,真正的分布式系統還要有另外一些功能要求:

  • 自適應。故障檢測應該能夠應對暫時(shí)的網(wǎng)絡(luò )故障和延遲,以及集群拓撲、負載和帶寬的變化。但這有很大難度,因為沒(méi)有辦法去分辨一個(gè)長(cháng)時(shí)間沒(méi)有響應的進(jìn)程到底是不是真的失效了,因此,故障檢測需要權衡故障識別時(shí)間(花多長(cháng)時(shí)間才能識別一個(gè)真正的故障,也即一個(gè)進(jìn)程失去響應多久之后會(huì )被認為是失效)和虛假警報率之間的輕重。這個(gè)權衡因子應該能夠動(dòng)態(tài)自動(dòng)調整。
  • 靈活性。乍看上去,故障檢測只需要輸出一個(gè)表明被監控進(jìn)程是否處于工作狀態(tài)的布爾值,但在實(shí)際應用中這是不夠的。我們來(lái)看參考資料[12]中的一個(gè)類(lèi)似MapReduce的例子。有一個(gè)由一個(gè)主節點(diǎn)和若干工作節點(diǎn)組成的分布式應用,主節點(diǎn)維護一個(gè)作業(yè)列表,并將列表中的作業(yè)分配給工作節點(diǎn)。主節點(diǎn)能夠區分不同程度的失敗。如果主節點(diǎn)懷疑某個(gè)工作節點(diǎn)掛了,他就不會(huì )再給這個(gè)節點(diǎn)分配作業(yè)。其次,隨著(zhù)時(shí)間推移,如果沒(méi)有收到該節點(diǎn)的心跳信息,主節點(diǎn)就會(huì )把運行在這個(gè)節點(diǎn)上的作業(yè)重新分配給別的節點(diǎn)。最后,主節點(diǎn)確認這個(gè)節點(diǎn)已經(jīng)失效,并釋放所有相關(guān)資源。
  • 可擴展性和健壯性。失敗檢測作為一個(gè)系統功能應該能夠隨著(zhù)系統的擴大而擴展。他應該是健壯和一致的,也即,即使在發(fā)生通訊故障的情況下,系統中的所有節點(diǎn)都應該有一個(gè)一致的看法(即所有節點(diǎn)都應該知道哪些節點(diǎn)是不可用的,那些節點(diǎn)是可用的,各節點(diǎn)對此的認知不能發(fā)生沖突,不能出現一部分節點(diǎn)知道某節點(diǎn)A不可用,而另一部分節點(diǎn)不知道的情況)
所謂的累計失效檢測器[12]可以解決前兩個(gè)問(wèn)題,Cassandra[16]對它進(jìn)行了一些修改并應用在產(chǎn)品中。其基本工作流程如下:
  • 對于每一個(gè)被監控資源,檢測器記錄心跳信息到達時(shí)間Ti。
  • 計算在統計預測范圍內的到達時(shí)間的均值和方差。
  • 假定到達時(shí)間的分布已知(下圖包括一個(gè)正態(tài)分布的公式),我們可以計算心跳延遲(當前時(shí)間t_now和上一次到達時(shí)間Tc之間的差值) 的概率,用這個(gè)概率來(lái)判斷是否發(fā)生故障。如參考資料[12]中所建議的,可以使用對數函數來(lái)調整它以提高可用性。在這種情況下,輸出1意味著(zhù)判斷錯誤(認為節點(diǎn)失效)的概率是10%,2意味著(zhù)1%,以此類(lèi)推。

根據重要程度不同來(lái)分層次組織監控區,各區域之間通過(guò)謠言傳播協(xié)議或者中央容錯庫同步,這樣可以滿(mǎn)足擴展性的要求,又可以防止心跳信息在網(wǎng)絡(luò )中泛濫[14]。如下圖所示(6個(gè)故障檢測器組成了兩個(gè)區域,互相之間通過(guò)謠言傳播協(xié)議或者像ZooKeeper這樣的健壯性庫來(lái)聯(lián)系):

協(xié)調者競選

協(xié)調者競選是用于強一致性數據庫的一個(gè)重要技術(shù)。首先,它可以組織主從結構的系統中主節點(diǎn)的故障恢復。其次,在網(wǎng)絡(luò )隔離的情況下,它可以斷開(kāi)處于少數的那部分節點(diǎn),以避免寫(xiě)沖突。

Bully 算法是一種相對簡(jiǎn)單的協(xié)調者競選算法。MongoDB 用了這個(gè)算法來(lái)決定副本集中主要的那一個(gè)。Bully 算法的主要思想是集群的每個(gè)成員都可以聲明它是協(xié)調者并通知其他節點(diǎn)。別的節點(diǎn)可以選擇接受這個(gè)聲稱(chēng)或是拒絕并進(jìn)入協(xié)調者競爭。被其他所有節點(diǎn)接受的節點(diǎn)才能成為協(xié)調者。節點(diǎn)按照一些屬性來(lái)判斷誰(shuí)應該勝出。這個(gè)屬性可以是一個(gè)靜態(tài)ID,也可以是更新的度量像最近一次事務(wù)ID(最新的節點(diǎn)會(huì )勝出)。

下圖的例子展示了bully算法的執行過(guò)程。使用靜態(tài)ID作為度量,ID值更大的節點(diǎn)會(huì )勝出:

  1. 最初集群有5個(gè)節點(diǎn),節點(diǎn)5是一個(gè)公認的協(xié)調者。
  2. 假設節點(diǎn)5掛了,并且節點(diǎn)2和節點(diǎn)3同時(shí)發(fā)現了這一情況。兩個(gè)節點(diǎn)開(kāi)始競選并發(fā)送競選消息給ID更大的節點(diǎn)。
  3. 節點(diǎn)4淘汰了節點(diǎn)2和3,節點(diǎn)3淘汰了節點(diǎn)2。
  4. 這時(shí)候節點(diǎn)1察覺(jué)了節點(diǎn)5失效并向所有ID更大的節點(diǎn)發(fā)送了競選信息。
  5. 節點(diǎn)2、3和4都淘汰了節點(diǎn)1。
  6. 節點(diǎn)4發(fā)送競選信息給節點(diǎn)5。
  7. 節點(diǎn)5沒(méi)有響應,所以節點(diǎn)4宣布自己當選并向其他節點(diǎn)通告了這一消息。

協(xié)調者競選過(guò)程會(huì )統計參與的節點(diǎn)數目并確保集群中至少一半的節點(diǎn)參與了競選。這確保了在網(wǎng)絡(luò )隔離的情況下只有一部分節點(diǎn)能選出協(xié)調者(假設網(wǎng)絡(luò )中網(wǎng)絡(luò )會(huì )被分割成多塊區域,之間互不聯(lián)通,協(xié)調者競選的結果必然會(huì )在節點(diǎn)數相對比較多的那個(gè)區域中選出協(xié)調者,當然前提是那個(gè)區域中的可用節點(diǎn)多于集群原有節點(diǎn)數的半數。如果集群被隔離成幾個(gè)區塊,而沒(méi)有一個(gè)區塊的節點(diǎn)數多于原有節點(diǎn)總數的一半,那就無(wú)法選舉出協(xié)調者,當然這樣的情況下也別指望集群能夠繼續提供服務(wù)了)。

參考資料
  1. M. Shapiro et al. A Comprehensive Study of Convergent and Commutative Replicated Data Types
  2. I. Stoica et al. Chord: A Scalable Peer-to-peer Lookup Service for Internet Applications
  3. R. J. Honicky, E.L.Miller. Replication Under Scalable Hashing: A Family of Algorithms for Scalable Decentralized Data Distribution
  4. G. Shah. Distributed Data Structures for Peer-to-Peer Systems
  5. A. Montresor, Gossip Protocols for Large-Scale Distributed Systems
  6. R. Escriva, B. Wong, E.G. Sirer. HyperDex: A Distributed, Searchable Key-Value Store
  7. A. Demers et al. Epidemic Algorithms for Replicated Database Maintenance
  8. G. DeCandia, et al. Dynamo: Amazon’s Highly Available Key-value Store
  9. R. van Resesse et al. Efficient Reconciliation and Flow Control for Anti-Entropy Protocols
  10. S. Ranganathan et al. Gossip-Style Failure Detection and Distributed Consensus for Scalable Heterogeneous Clusters
  11. http://www.slideshare.net/kakugawa/distributed-counters-in-cassandra-cassandra-summit-2010
  12. N. Hayashibara, X. Defago, R. Yared, T. Katayama. The Phi Accrual Failure Detector
  13. M.J. Fischer, N.A. Lynch, and M.S. Paterson. Impossibility of Distributed Consensus with One Faulty Process
  14. N. Hayashibara, A. Cherif, T. Katayama. Failure Detectors for Large-Scale Distributed Systems
  15. M. Leslie, J. Davies, and T. Huffman. A Comparison Of Replication Strategies for Reliable Decentralised Storage
  16. A. Lakshman, P.Malik. Cassandra – A Decentralized Structured Storage System
  17. N. A. Lynch. Distributed Algorithms
  18. G. Tel. Introduction to Distributed Algorithms
  19. http://basho.com/blog/technical/2010/04/05/why-vector-clocks-are-hard/
  20. L. Lamport. Paxos Made Simple
  21. J. Chase. Distributed Systems, Failures, and Consensus
  22. W. Vogels. Eventualy Consistent – Revisited
  23. J. C. Corbett et al. Spanner: Google’s Globally-Distributed Database
本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
分布式存儲系統基礎
別再說(shuō)你不會(huì )分布式了,面試官能問(wèn)的都在這了
分布式架構原理解析
云南紅塔銀行app(分布式架構在云南紅塔銀行核心系統的實(shí)踐)
HBase vs Cassandra: 我們遷移系統的原因 ? 我有分寸
如何讓你的內存中的 NoSQL 數據存儲適合企業(yè)級應用
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久