副本機制與副本同步------《Designing Data-Intensive Applications》讀書筆記6

來源:互聯網
上載者:User

標籤:版本   簡單   ati   hdf   自動   image   postgres   gpo   很多   

進入到第五章了,來到了分布式系統之中最核心與複雜的內容:副本與一致性。通常分布式系統會通過網路連接的多台機器上儲存相同資料的副本,所以在本篇之中,我們來展開看看如何去管理和維護這些副本,以及這個過程之中會遇到的各種問題。

1.副本

在資料系統之中,我們通常會有這樣幾個原因來使用副本技術:

  • 保持地理位置接近使用者,從而減少延遲(如:Cache,CDN技術
  • 提高系統的可用性和魯棒性,即使系統中的某些部分已經失效了,仍然可以對外提供服務。(如:GFS三副本的設計
  • 通過擴充性來提供讀查詢,從而增加讀取輸送量。(如:ZooKeeper之中的Observer

首先,如果副本的資料不隨時間變化,那麼副本的管理是比較簡單的:只需要將資料複製到每個節點一次,就OK了。副本管理真正的困難在於對副本資料的修改,這會涉及到很多瑣碎的問題。其次,副本複製時要考慮許多權衡,使用同步還是非同步複製,以及如何處理失效的副本?接下來我們來一一探討這個問題。

2.Leader-Follower機制

如何保障多個副本在不同節點上的一致性一直分布式系統之中的一個核心問題。分布式系統在寫入資料時,需要由每個副本進行處理;否則,副本將不再包含相同的資料。Leader-Follower是一種常見的機制,我們來梳理一下它的原理:

    1. 一個節點上的副本被指定為Leader。當用戶端需要向系統寫入資料時,必須將寫入請求發送給Leader,由Leader首先將新資料寫入本機存放區的副本。
    1. 管理其他副本的節點稱為Follower。每當Leader將新資料寫入本機存放區d的副本時,也會將資料更改寫入日誌之中。每個Follower會從Leader那裡擷取修改日誌,並相應地更新資料到的本機複本之中,這樣,所有的在Follower上副本的修改順序會和Leader保持相同的順序。
    1. 當用戶端需要從系統之中讀取資料時,它可以查詢Leader或其他Follower。(註:Follower與Leader之中的資料存在延遲,無法保證強一致性)寫入請求只能由Leader來響應,或是由Follower轉寄給Leader

許多關聯式資料庫在同步複本時使用這樣的機制,如PostgreSQL,MySQL,Oracle Data Guard 和SQL Server。同時許多非關係型資料庫與分布式訊息佇列也採用這樣的機制,包括MongoDB,Rethinkd,Kafka,RabbitMQ。

2.1 同步與非同步複製

在副本進行主從複製時一個重要細節是複製是同步還是非同步發生的?(在關聯式資料庫中,這往往是一個可配置的選項。在其他系統之中,如Ceph,是系統預設的)

由可知,同步複製有相當大的延遲,而非同步複製的響應相當快速。但是非同步複製卻不能保證完成所需要多長時間。有些情況下,Follower的資料可能比Leader上的資料落後幾分鐘或更多。如:節點之間存在網路問題或節點的故障恢複。如果Leader失敗且不可恢複,則尚未複製到Follower的任何寫操作都將丟失。

而同步複製的優點是保證了Follower與Leader之間的副本一致性,一旦任意一個Leader失效了,任何一個Follower的資料都與Leader相同。但是同步複製一旦出現網路或節點的故障,會導致無法處理寫入。Leader必須阻止所有寫入並等待Follow上的副本再次可用。如果所有的Follower都是同步複製,那麼任何一個節點的中斷都會導致整個系統癱瘓。在實際運用之中,如果在資料庫上啟用同步複製,通常其中一個副本是同步複製的,而另一個是非同步複製的。如果同步的副本變得不可用或十分緩慢,可以將同步操作切換到另一個非同步副本之中。這樣保證了至少兩個節點上有一個資料的最新副本:Leader和一個同步Follower。這種配置稱之為半同步。(鏈式複製也是類似於半同步的一種複製機制,不遺失資料但仍能提供良好效能和可用性的複製方法。)

2.2 添加新的Follower

有時我們需要添加新的Follower來增加副本的數量,或者替換失敗的節點。此時就需要確保新的Follower擁有一個正確的副本的資料。僅僅將資料檔案從一個節點複製到另一個節點通常是不夠的:用戶端不停向系統寫入資料,所以資料副本總是處於不斷變化的狀態。這裡可以簡單地通過鎖定系統,使其拒絕用戶端的寫請求來使各個副本上保持一致,但這樣會大大降低系統的可用性。所以我們需要一個不停機的方式來添加新的Follower:

  • 1.在某個時間點對Leader的副本進行快照,並且將快照式複寫到新加入的Follower節點。

  • 2 .Follower串連到Leader,並向Leader請求快照之後所有的資料更改。通常是Leader節點的記錄序號。

    1. 當Follower處理完快照之後的資料更改之後,它就可以正常處理來自Leader的資料更改了。
2.3 節點故障

在分布式系統之中,任何節點都可能出現故障,而能夠在不停機的情況下重新啟動單個節點是操作和維護是十分必要的。儘管每個節點故障,但我們需要讓一個節點停機的影響儘可能小。

  • Follower故障

在Follower的本地磁碟上,都儲存著從Leader收到的資料更改的日誌。當一個Follower崩潰並重新啟動,或者Leader與Follower之間的網路暫時中斷。Follower可從它的日誌找到故障發生之前處理的最後一個事務,然後串連到Leader並請求在Follower中斷連線的時候發生的所有資料變化。(這個流程和添加新的Follower其實是同樣的思路

  • Leader故障

在處理Leader的失敗時顯然會更為棘手:其中一個Follower需要被提升為新的Leader,用戶端也需要識別並且將後續的請求發送給新的Leader,而其他的Follower則需要開始在新Leader之下工作。處理Leader故障通常是如下的流程:

  • 1、確認Leader失效。絕大多數系統使用逾時機制:如果一個節點不響應一段時間,例如,30秒,它被認為是失效了。(如果是中心化的系統可以採用Lease機制。筆者在碩士生階段對Cassandra資料庫有過系統的調研,在Cassandra中採用了由日本學者Naohiro Hayashibara提出的《The Phi Accrual Failure Detector》失敗探測演算法,通過多維度累積量來判斷節點是否失效,不失為一個好的解決方案,十分適合類P2P架構的分布式系統

  • 2、選取新的Leader。在中心化架構之中,如HDFS,新的Leader可以用中心化節點指定。而在非中心化的架構之中,則可以通過選舉過程來完成,分布式系統之中的選舉協議有很多:2PC,3PC,Paxos,Raft等等。

  • 3、調整系統配置以使用新的Leader。如果舊的Leader迴歸到叢集,它可能仍然認為自己是Leader,這時需要確保舊的Leader成為Follower並承認新的Leader。

如果是非同步複製的情境,新的Leader可能舊的Leader之前的完整的寫入資訊。最常見的解決方案是丟棄舊Leader之前寫入多於新Leader的資訊丟棄,但是這顯然違反了資料系統寫入持久性的要求。
在某些故障情境中,可能會出現兩個節點都認為他們是Leader,這種情況被稱為腦裂。此時兩個Leader都會接受寫請求,資料很可能會出現丟失或損壞。
什麼時候進行故障切換也是一個值得探討的問題:較長的逾時時間意味著在Leader失效的情況下恢復更長。然而,如果時間太短,可能會有不必要的容錯移轉。例如,臨時負載高峰時刻可能導致節點的回應時間增加到逾時,那麼不必要的容錯移轉會使情況變得更糟,而不是更好。為此,一些運營團隊更願意執行手動的容錯移轉,即使系統本身支援自動的容錯移轉。

3. 日誌的複製

日誌在副本的一致性之中是至關重要的,所以我們接下來簡要的梳理一下日誌複製可用的方法:

  • Statement-Based複製
    在最簡單的情況下,Leader將每個寫請求通過日誌的形式發送給Follower。每個Follower解析和執行對應的動作陳述式,雖然這聽起來很合理,但是實際操作中會存在一些坑:

(1) 非確定性函數,如now()獲得當前的日期和時間或rand()得到一個隨機數,這樣會導致副本之間的不一致。(這裡可以轉換思維,用一個確定的修改值,來替換不確定性函數調用)

(2) 如果使用一個自動遞增的列,或如果他們依賴於資料庫中的現有資料(例如,更新…在<條件>),他們必須執行完全相同的順序在每個副本,否則也會產生不一致性。(非同步轉寄,亂序到達。這個可以通過操作序號等強制要求進行規避。

(3) 有副作用的語句(例如觸發器、預存程序、使用者定義函數)可能會導致每個副本上出現不同的副作用。

  • Write-ahead日誌複製
    日誌是一個只包含所有寫入操作的位元組序列。我們可以使用完全相同的日誌來在另一個節點上構建一個副本。Leader將日誌寫入磁碟之後,將它通過網路發送給Follower。當Follower處理這個日誌時,它構建了一個與Leader完全相同的資料結構的副本。這種方式的缺點是:日誌在非常低的層級上描述資料。這使得資料拷貝與儲存引擎緊密耦合。

  • Row-based日誌複製
    Row-based與Write-ahead的方法類似,但是它允許複製日誌與儲存引擎內部分離。這種日誌稱為邏輯日誌,邏輯日誌通常是描述在一個行的粒度上記錄寫入操作:
    對於插入的行,日誌包含所有列的新值。
    對於已刪除的行,日誌包含足夠的資訊以唯一地標識刪除的行。(主鍵
    對於更新的行,日誌包含足夠的資訊以唯一地標識更新的行,以及所有列的新值。
    由於邏輯日誌與儲存引擎內部分離,因此可以更容易地保持向後相容,從而允許Leader與Follower運行不同版本的資料系統,甚至是不同的儲存引擎。同時,邏輯日誌格式對外部應用程式也更容易解析。可以將邏輯日誌的內容發送到外部系統(如用於離線分析的資料倉儲),或者用於構建自訂索引和緩衝。

4. 複寫延遲

副本可以增加系統的延展性(處理比單個機器處理更多的請求)和降低延遲(將副本放置在離使用者更近的地方)。寫入操作必須通過Leader副本,但是唯讀查詢可以在任何副本上進行。 對於一次寫入,多次讀取的應用來說,採用讀擴充架構是十分合理的。但是由於上文提及的原因,我們通常不會採用同步複製的方式。這將導致資料出現明顯的不一致性:如果您同時對Leader和Follwer執行相同的查詢,可能會得到不同的結果,因為並不是所有的寫入即時在Follower上反饋。這種不一致性僅僅是暫時狀態,所以這種情況被稱為最終一致性。

對於這種情況我們應該這麼去處理和理解,我們下回分解~~~(第五章的內容炒雞多,接下來會通過多篇讀書筆記來給大家梳理,講解,下一篇再見~~

副本機制與副本同步------《Designing Data-Intensive Applications》讀書筆記6

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.