聊聊replication的方式

2021-09-14 06:31:01 字數 3516 閱讀 5679

本文主要聊一聊主流開源產品的replication方式。

replication和partition/sharding是分布式系統必備的兩種能力。具體詳見複製、分片和路由.

對於海量資料來說,replication一方面可以增加冗餘,保證系統可用性,一方面還可以提公升讀取的效率。

本文主要聚焦於replication,即假設每個node都足以存下整個副本。

按照有無leader以及leader數目可以分為:

具體詳見副本更新策略,主要有如下幾種

無中心的複製,可以分為三種拓撲結構,環形、星/樹型、網狀拓撲

主要分為以下幾種

pg使用的就是這種。

一般replication增加冗餘常用來做master的的熱備(支援查詢)/溫備(不支援查詢)

一旦replication支援讀取的話,那麼就涉及讀的一致性問題,一般理論上除了強一致外,有這幾種最終一致性:

讀取的話,涉及讀己所寫,因果讀(針對操作有序)、單調讀(不讀到舊資料)

假設某份資料需要複製到3個節點,為了保證強一致性,不需要所有節點都確認寫入操作,只需要其中兩個節點(也就是超半數節點)確認就可以了。在這種情況下,如果發生兩個相互衝突的寫入操作,那麼只有其中乙個操作能為超過半數的節點所認可,這就是寫入仲裁(write quorum),如果用稍微正規一點的方式說,那就是w>n/2,這個不等式的意思是參與寫入操作的節點數w,必須超過副本節點數n的一半,副本節點數又稱為複製因子(replication factor)。

讀取仲裁(read quorum),也就是說想保證能夠讀到最新的資料,必須與多少個節點聯絡才行。假設寫入操作需要兩個節點來確認(w=2),那麼我們至少得聯絡兩個節點,才能保證獲取到最新資料。然而,假如某些寫入操作只被乙個節點所確認(w=1),那麼我們就必須3個節點都通訊一遍,才能確保獲取到的資料是最新的。乙個情況下,由於寫入操作沒有獲得足夠的節點支援率,所以可能會產生更新衝突。但是,只要從足夠數量的節點中讀出資料,就一定能偵測出此類衝突。因此,即使在寫入操作不具備強一致性的情況下,也可以實現除具有強一致性的讀取操作來。

這三者之間的關係,可以用乙個不等式來表述,即只有當r+w>n的時候,才能保證讀取操作的強一致性。

產品複製方式

實現方式

其他mysql

主從半同步

mysql 5.0及之前的版本僅支援statement-based的複製,5.1+版本,當有不確定語句時,就切換為row-based log replication

主從延遲處理

kafka

主從isr半同步

leader寫入訊息並複製到所有follower,isr中的副本寫入成功返回ack給leader才算commit成功

生產者可以選擇是否等待isr的ack

elasticsearch

主從半同步,預設replication=sync

consistency可選的值有quorum、one和all。預設的設定為quorum

tradelog及fsync以及refresh

pg主從非同步複製

基於write-ahead log

archive及stream方式

redis

主從非同步複製

增量redis protocol(全量增量長連線)

sentinel failover

mongo

主從非同步,replica set模式

持久化的ring-buffer local.oplog.rs(initial_sync,steady-sync)

arbiter選主

可以看見一些對一致性要求高的,可以採用半同步的機制,一般是基於quorum機制,像es就是基於這種機制,而kafka是採用isr機制,二者都可以配置

其他的基本是非同步複製,對於新加入的node以及recovery node的同步來說,採用不同的同步方式,新加入的一般採用全量同步,而處於正常狀態的node,一般是增量同步

所有的副本(replicas)統稱為assigned replicas,即ar。isr是ar中的乙個子集,由leader維護isr列表,follower從leader同步資料有一些延遲,任意乙個超過閾值都會把follower剔除出isr,存入osr(outof-sync replicas)列表,新加入的follower也會先存放在osr中。ar=isr+osr。

當producer傳送一條訊息到broker後,leader寫入訊息並複製到所有follower。訊息提交之後才被成功複製到所有的同步副本。訊息複製延遲受最慢的follower限制,重要的是快速檢測慢副本,如果follower「落後」太多或者失效,leader將會把它從isr中刪除。

由此可見,kafka的複製機制既不是完全的同步複製,也不是單純的非同步複製。事實上,同步複製要求所有能工作的follower都複製完,這條訊息才會被commit,這種複製方式極大的影響了吞吐率。而非同步複製方式下,follower非同步的從leader複製資料,資料只要被leader寫入log就被認為已經commit,這種情況下如果follower都還沒有複製完,落後於leader時,突然leader宕機,則會丟失資料。而kafka的這種使用isr的方式則很好的均衡了確保資料不丟失以及吞吐率。

es的一致性主要有兩個方面:

在elasticsearch和磁碟之間是檔案系統快取。 在記憶體索引緩衝區中的文件會被寫入到乙個新的段中,但是這裡新段會被先寫入到檔案系統快取--這一步代價會比較低,稍後再被重新整理到磁碟--這一步代價比較高。不過只要檔案已經在快取中, 就可以像其它檔案一樣被開啟和讀取了。

在 elasticsearch 中,寫入和開啟乙個新段的輕量的過程叫做 refresh 。 預設情況下每個分片會每秒自動重新整理一次。這就是為什麼我們說 elasticsearch是近實時搜尋: 文件的變化並不是立即對搜尋可見,但會在一秒之內變為可見。

這些行為可能會對新使用者造成困惑: 他們索引了乙個文件然後嘗試搜尋它,但卻沒有搜到。這個問題的解決辦法是用 refresh api 執行一次手動重新整理.

refresh_interval 可以在既存索引上進行動態更新。 在生產環境中,當你正在建立乙個大的新索引時,可以先關閉自動重新整理,待開始使用該索引時,再把它們調回來.

不同產品的replication細節不盡相同,但是大的理論是一致的,對於replication除了關注上述的replication相關方式外,還需要額外關注replication相關異常場景,才能做到成熟應用。

rwn及quorum與強一致性

es一致性問題

es的寫入過程

elasticsearch學習筆記(三)elasticsearch集群分片的讀寫操作流程

elasticsearch權威指南-分片內部原理

聊聊replication的方式

本文主要聊一聊主流開源產品的replication方式。replication和partition sharding是分布式系統必備的兩種能力。具體詳見複製 分片和路由.對於海量資料來說,replication一方面可以增加冗餘,保證系統可用性,一方面還可以提公升讀取的效率。本文主要聚焦於repli...

Replication 複製相關的作業

複製使用下列作業來執行計畫維護和按需維護 作業名稱 說明 預設排程 歷史記錄清除 分發 從分發資料庫中刪除複製 歷史記錄。每十分鐘執行一次 分發清除 分發 從分發資料庫中刪除複製的事務。停用在最大分發保持期內尚未同步的訂閱。每十分鐘執行一次 過期訂閱清除 從發布資料庫檢測和刪除過期的訂閱。每天凌晨 ...

聊聊高效的與第三方合作方溝通

當公司在高速發展的時候,經常會有一些第三方的合作蹦出來,一般來說都說互惠互利的,也不存在什麼甲方乙方之說。在開發眼裡,無非就說我需要在專案裡嵌入你的sdk 或者是我需要編寫乙個sdk供你嵌入之類的。但是,這種合作通常實際去溝通細節的開發們,基本上是不會碰面的。在網際網路上通過工具溝通,畢竟沒有面對面...