Ceph Monitor實現(xiàn)

在之前的一篇博客Ceph Monitor and Paxos中介紹了Ceph Monitor利用改進的Paxos算法,以集群的形式對外提供元信息管理服務。本文講分別從Ceph Monitor的架構,其初始化過程、選主過程、Recovery過程、讀寫過程、狀態(tài)轉換六個方面介紹Ceph Monitor的實現(xiàn)。本文假設讀者已經(jīng)了解Paxos算法的基本過程,了解Prepare、Promise、Commit、Accept、Quorum等概念。注意Ceph Monitor中的Accept概念其實相當于Paxos中的Promise。

架構

Ceph Monitor Architecture

上圖所示是Ceph Monitor的結構圖,自下而上有以下幾個部分組成:

  • DBStore層:數(shù)據(jù)的最終存儲組件,以leveldb為例;
  • Paxos層:在集群上對上層提供一致的數(shù)據(jù)訪問邏輯,在這一層看來所有的數(shù)據(jù)都是kv;上層的多中PaxosService將不同的組件的map數(shù)據(jù)序列化為單條value,公用同一個paxos實例。
  • PaxosService層:每個PaxosService代表集群的一種狀態(tài)信息。對應的,Ceph Moinitor中包含分別負責OSD Map,Monitor Map, PG Map, CRUSH Map的幾種PaxosService。PaxosService負責將自己對應的數(shù)據(jù)序列化為kv寫入Paxos層。Ceph集群所有與Monitor的交互最終都是在調用對應的PaxosSevice功能。

初始化

Ceph Monitor Initial

可以看出,Ceph Monitor在啟動節(jié)點端,主要做了三件事情:

  • 自下而上依次初始化上述的三大組成部分:DBStroe,Paxos,PaxoService
  • 初始化Messager,并向其中注冊命令執(zhí)行回調函數(shù)。Messager是Ceph中的網(wǎng)絡線程模塊,Messager會在收到網(wǎng)絡請求后,回調Moniotor在初始化階段注冊命令處理函數(shù)。
  • Bootstrap過程在整個Monitor的生命周期中被反復調用,下面就重點介紹一下這個過程。

Boostrap

  • 執(zhí)行Boostrap的Monitor節(jié)點會首先進入PROBING狀態(tài),并開始向所有monmap中其他節(jié)點發(fā)送Probing消息。
  • 收到Probing消息的節(jié)點執(zhí)行Boostrap并回復Probing_ack,并給出自己的last_commit以及first_commit,其中first_commit指示當前機器的commit記錄中最早的一條,其存在使得單個節(jié)點上可以僅保存最近的幾條記錄。
  • 收到Probing_ack的節(jié)點發(fā)現(xiàn)commit數(shù)據(jù)的差距早于對方first_commit,則主動發(fā)起全同步,并在之后重新Boostrap
  • 收到超過半數(shù)的ack并不需要全同步時,則進入選主過程。

上述交互過程見下圖:

Ceph Monitor Boostrap

目的:可以看出,經(jīng)過了Boostrap過程,可以完成以下兩步保證:

  • 可以與超過半數(shù)的節(jié)點通信;
  • 節(jié)點間commit數(shù)據(jù)歷史差距不大。

選主

接著,節(jié)點進入選主過程:

  • 將election_epoch加1,向Monmap中的所有其他節(jié)點發(fā)送Propose消息;
  • 收到Propose消息的節(jié)點進入election狀態(tài)并僅對有更新的election_epoch且rank值大于自己的消息答復Ack。這里的rank簡單的由ip大小決定;
  • 發(fā)送Propose的節(jié)點統(tǒng)計收到的Ack數(shù),超時時間內收到Monmap中大多數(shù)的ack后可進入victory過程,這些發(fā)送ack的節(jié)點形成quorum;

victory

  • election_epoch加1,可以看出election_epoch的奇偶可以表示是否在選舉輪次;
  • 向quorum中的所有節(jié)點發(fā)送VICTORY消息,并告知自己的epoch及quorum;
  • 當前節(jié)點完成Election,進入Leader狀態(tài);
  • 收到VICTORY消息的節(jié)點完成Election,進入Peon狀態(tài)

上述交互過程見下圖:

Ceph Monitor Election

目的:可以看出,Monitor選主過程的目的如下:

  • 簡單的根據(jù)ip大小選出leader,而并沒有考慮commit數(shù)據(jù)長度;
  • 確定quroum,在此之前所有的操作都是針對Monmap內容的,直到這里才有了quroum,之后的所有Paxos操作便基于當前這個quorum了。

RECOVERY階段

經(jīng)過了上述的選主階段,便確定了leader,peon角色,以及quorum成員。在真正的開始一致性讀寫之前,還需要經(jīng)過RECOVERY階段:

  • leader生成新的更大的新的pn,并通過collect消息發(fā)送給所有的quorum中成員;
  • 收到collect消息的節(jié)點當pn大于自己已經(jīng)accept的最大pn時,接受并通過last消息返回自己的commit位置及uncommitted;
  • leader收到last消息,更新自己的commit位置及數(shù)據(jù),并重復提升pn發(fā)送collect消息的過程,直到quorum中所有的節(jié)點都接受自己。
  • 同時leader會根據(jù)收到的commit及uncommitted位置,分別用commit消息和begin消息更新對應的peon;
  • leader向quorum中所有節(jié)點發(fā)送lease消息,使整個集群進入active狀態(tài)。

這個階段的交互過程如下圖:

Ceph Monitor Collect

目的

  • 將leader及quorum節(jié)點的數(shù)據(jù)更新到最新且一致;
  • 整個集群進入可用狀態(tài)。

讀寫流程

經(jīng)過了上面的初始化、選主、恢復階段整個集群進入到一個非常正常的狀況,終于可以利用Paxos進行一致性地讀寫了,其中讀過程比較簡單,在lease內的所有quroum均可以提供服務。而所有的寫都會轉發(fā)給leader,寫過程如下:

  • leader在本地記錄要提交的value,并向quroum中的所有節(jié)點發(fā)送begin消息,其中攜帶了要提交的value, accept_pn及l(fā)ast_commit;
  • peon收到begin消息,如果accept過更高的pn則忽略,否則將value寫入db并返回accept消息。同時peon會將當前的lease過期掉,在下一次收到lease前不再提供服務;
  • leader收到全部quorum的accept后進行commit。本地commit后向所有quorum節(jié)點發(fā)送commit消息;
  • peon收到commit消息,本地commit數(shù)據(jù);
  • leader通過lease消息將整個集群帶入到active狀態(tài)。

交互過程如下:

Ceph Monitor Write

目的

  • 由leader發(fā)起propose,并依次完成寫入,一個value完成commit才會開始下一個;
  • 通過lease分擔讀壓力。

數(shù)據(jù)存儲:我們知道commit以后的數(shù)據(jù)才算真正寫入到集群,那么為什么在begin過程中,leader和peon都會將數(shù)據(jù)寫入db呢?這是因為Ceph Montor利用db來完成了log和value兩部分數(shù)據(jù)的存儲,而commit時會將log數(shù)據(jù)反序列化后以value的格式重新存儲到db。

狀態(tài)

在Monitor的生命周期,貫穿于上述各個過程的包括兩個層面的狀態(tài)轉換,Monitor自身的狀態(tài),以及Monitor進入主從狀態(tài)后,其Paxos過程中的狀態(tài)。

Monitor狀態(tài)轉換
Ceph Monitor Status
  • STATE_PROBING:boostrap過程中節(jié)點間相互探測,發(fā)現(xiàn)數(shù)據(jù)差距;
  • STATE_SYNCHRONIZING:當數(shù)據(jù)差距較大無法通過后續(xù)機制補齊時,進行全同步;
  • STATE_ELECTING:Monitor在進行選主
  • STATE_LEADER:當前Monitor成為leader
  • STATE_PEON:非leader節(jié)點
Paxos狀態(tài)轉換
Ceph Monitor Paxos Status
  • STATE_RECOVERING:對應上述RECOVERING過程;
  • STATE_ACTIVE:leader可以讀寫或peon擁有l(wèi)ease;
  • STATE_UPDATING(STATE_UPDATING_PREVIOUS):向quroum發(fā)送begin,等待accept;
  • STATE_WRITING(STATE_WRITING_PREVIOUS):收到accept
  • STATE_REFRESH:本地提交并向quorum發(fā)送commit;

參考:

RADOS: A Scalable, Reliable Storage Service for Petabyte-scale Storage Clusters

SOURCE CODE

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容