zookeeper,kafka,redis等分布式框架的主從同步策略


1 zookeeper選主機制

1.1 LeaderElection選舉算法

選舉線程由當前Server發起選舉的線程擔任,他主要的功能對投票結果進行統計,並選出推薦的Server。選舉線程首先向所有Server發起一次詢問(包括自己),被詢問方,根據自己當前的狀態作相應的回復,選舉線程收到回復后,驗證是否是自己發起的詢問(驗證xid 是否一致),然后獲取對方的id(myid),並存儲到當前詢問對象列表中,最后獲取對方提議 的

leader 相關信息(id,zxid),並將這些 信息存儲到當次選舉的投票記錄表中,當向所有Serve r

都詢問完以后,對統計結果進行篩選並進行統計,計算出當次詢問后獲勝的是哪一個Server,並將當前zxid最大的Server 設置為當前Server要推薦的Server(有可能是自己,也有可以是其它的Server,根據投票結果而定,但是每一個Server在第一次投票時都會投自己),如果此時獲勝的Server獲得n/2 + 1的Server票數,設置當前推薦的leader為獲勝的Server。根據獲勝的Server相關信息設置自己的狀態。每一個Server都重復以上流程直到選舉出Leader。

 

初始化選票(第一張選票): 每個quorum節點一開始都投給自己;

收集選票: 使用UDP協議盡量收集所有quorum節點當前的選票(單線程/同步方式),超時設置200ms;

統計選票: 1).每個quorum節點的票數;

         2).為自己產生一張新選票(zxid、myid均最大);

選舉成功: 某一個quorum節點的票數超過半數;

更新選票: 在本輪選舉失敗的情況下,當前quorum節點會從收集的選票中選取合適的選票(zxid、myid均最大)作為自己下一輪選舉的投票;

異常問題的處理

1). 選舉過程中,Server的加入

當一個Server啟動時它都會發起一次選舉,此時由選舉線程發起相關流程,那么每個 Serve r都會獲得當前zxi d最大的哪個Serve r是誰,如果當次最大的Serve r沒有獲得n/2+1 個票數,那么下一次投票時,他將向zxid最大的Server投票,重復以上流程,最后一定能選舉出一個Leader。

2). 選舉過程中,Server的退出

只要保證n/2+1個Server存活就沒有任何問題,如果少於n/2+1個Server 存活就沒辦法選出Leader。

3). 選舉過程中,Leader死亡

當選舉出Leader以后,此時每個Server應該是什么狀態(FLLOWING)都已經確定,此時由於Leader已經死亡我們就不管它,其它的Fllower按正常的流程繼續下去,當完成這個流程以后,所有的Fllower都會向Leader發送Ping消息,如果無法ping通,就改變自己的狀為(FLLOWING ==> LOOKING),發起新的一輪選舉。

4). 選舉完成以后,Leader死亡

處理過程同上。

5). 雙主問題

Leader的選舉是保證只產生一個公認的Leader的,而且Follower重新選舉與舊Leader恢復並退出基本上是同時發生的,當Follower無法ping同Leader是就認為Leader已經出問題開始重新選舉,Leader收到Follower的ping沒有達到半數以上則要退出Leader重新選舉。

1.2 FastLeaderElection選舉算法

FastLeaderElection是標准的fast paxos的實現,它首先向所有Server提議自己要成為leader,當其它Server收到提議以后,解決 epoch 和 zxid 的沖突,並接受對方的提議,然后向對方發送接受提議完成的消息。

FastLeaderElection算法通過異步的通信方式來收集其它節點的選票,同時在分析選票時又根據投票者的當前狀態來作不同的處理,以加快Leader的選舉進程。

每個Server都一個接收線程池和一個發送線程池, 在沒有發起選舉時,這兩個線程池處於阻塞狀態,直到有消息到來時才解除阻塞並處理消息,同時每個Serve r都有一個選舉線程(可以發起選舉的線程擔任)。

1). 主動發起選舉端(選舉線程)的處理

首先自己的 logicalclock加1,然后生成notification消息,並將消息放入發送隊列中, 系統中配置有幾個Server就生成幾條消息,保證每個Server都能收到此消息,如果當前Server 的狀態是LOOKING就一直循環檢查接收隊列是否有消息,如果有消息,根據消息中對方的狀態進行相應的處理。

2).主動發送消息端(發送線程池)的處理

將要發送的消息由Notification消息轉換成ToSend消息,然后發送對方,並等待對方的回復。

3). 被動接收消息端(接收線程池)的處理

將收到的消息轉換成Notification消息放入接收隊列中,如果對方Server的epoch小於logicalclock則向其發送一個消息(讓其更新epoch);如果對方Server處於Looking狀態,自己則處於Following或Leading狀態,則也發送一個消息(當前Leader已產生,讓其盡快收斂)。

 

2.kafka分區的選主機制

kafka如何解決以上選舉機制的
kafka的leader election方案解決了上述問題,它在所有的broker中選出一個controller,所有的partition的leader選舉都有controller決定。controller會將leader的改變直接通過RPC的方式(比zookeeper Queue的方式更高效)通知需要為此作為響應的broker。

原因:
1、不用zk選舉,使用controller(Controller會將leader的改變通過rpc方式通知給follower),沒有zk負載過重問題
2、也沒有注冊watch不會觸發任何事件-驚群效應
3、leader失敗是由一個Controller進行選舉並不會產生任何通信,所以不會有腦裂的情況

問題:
(1)Controller是如何選舉出來的
每一個broker都會在Controller path(/controller)上注冊一個watch。當前controller失敗時,對應的Controller path會自動消失(臨時節點)。此時該watch被觸發,所有活着的broker都會去競選成為新的Controller(創建新的controller path),但是只有一個會競選成功。競選成功者成為新的leader。競選失敗則重新在新的Controller path上注冊watch,因為zk的watch是一次性的,被觸發一次之后即失效,所以需要重新注冊。
(2)如何使用Controller進行partition選舉
a、從zk中讀取當前分區的所有ISR(in-sync-replicas)集合
b、調用配置的分區算法選擇分區的leader
kafka選擇分區算法:
i、NoOpLeaderSelector–偏愛分區(SR中的第一個),並將leader發送給為此做出改變的broker,
ii、offlinePartitionLeader–也是選擇偏愛分區作為leader
iii、reassignedPartitionLeader
iii、preferredReplicaPartitionLeader
iiii、ControlledShutdownLeader
上面五中算法都使用偏愛分區作為leader,區別是選擇leader之后所做的操作不同。

4.數據同步機制

Kafka的主從同步ISR

kafka的主從同步,主要是針對它的broker來說。

在kafka的broker中,同一個topic可以被分配成多個Partition,每個Partition的可以有一個或者多個replicas(備份),即會有一個leader以及0到多個Follower,在consumer讀取數據的時候,只會從Leader上讀取數據,Follower只是在Leader宕機的時候來替代Leader,主從同步有兩種方式:同步復制和異步復制,Kafka采用的是中間策略ISR(In Sync Replicas)。

Kafka的ISR策略
在有數據寫上Leader的時候,Leader會查看Follower組成的ISR列表,並且符合以下兩點才算是屬於ISR列表:

1、broker可以維護和zookeeper的連接,zookeeper通過心跳機制檢查每個節點的連接

2、如果節點是個follow它必須能及時同步Leader的寫操作,不能延時太久。

當有寫消息的時候,我們可以根據配置做如下配置:

request.required.acks參數的設置來進行調整:
0 ,相當於異步發送,消息發送完畢即offset增加,繼續生產;相當於At most once
1,leader收到leader replica 對一個消息的接受ack才增加offset,然后繼續生產;
-1,leader收到所有replica 對一個消息的接受ack才增加offset,然后繼續生產
Zookeeper的主從同步ZAB
Zookeeper的zab策略脫胎於Paxos算法,默認情況下,zk中寫數據時,要有一半以上的從節點寫入成功,才算是寫入成功。

Redis的主從同步
redis因為是要提升性能,所以直接采用的異步復制,當在Master上寫入數據后直接返回,然后把數據快照廣播給Slave,讓所有的Slaves去執行操作


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM