趣解 ceph rgw multisite data sync 機制

    multisite是ceph rgw對象數據異地容災備份的一個有效方案,筆者但願深刻理解該技術,並應用於生產環境中,然而rgw的這部分代碼晦澀難懂,筆者屢次嘗試閱讀,仍雲裏霧裏不解其意,最終流着淚咬着牙堅持多看了幾遍,總結出了data sync的流程,這裏以通俗易懂的形式呈現出來,但願對你們有所幫助~html

數據同步流程圖

https://www.cnblogs.com/wangmingshuai/articles/11040979.html

 

首先,認識下 data sync機制 的三個角色Data、DataLogShard、BucketShard

    rgw的multisite同步分爲兩部分:metadata數據同步 和 data數據同步。metadata數據包括bucket信息、bucket instance信息、user信息等;data數據指的是存儲的對象的實際數據,即Data。本文僅涉及data數據的同步。
    rgw使用datalog來記錄Data的變化,爲防止datalog成爲瓶頸,將datalog分紅了${rgw_data_log_num_shards}個shard,即DataLogShard。全部的 DataLogShard 的數據變化就反應了Data的變化。
    rgw使用bucket index來提高list對象的效率。爲防止bucket index成爲瓶頸,將bucket分紅了${rgw_override_bucket_index_max_shards}個shard,即BucketShard。每一個BucketShard的bucket index log記錄了該BucketShard對象的變化。
    rgw的每一個BucketShard都會經過hash映射到某個DataLogShard上,造成了以下形式的映射關係。理解映射關係是理解data sync的重要前提。
          DataLogShard ...   :   ...
          DataLogShard 12 :  bucket_a:0、bucket_b:3
          DataLogShard 13 :  bucket_a:四、bucket_b:七、bucket_c:5 ...
          DataLogShard ...   :   ...
    當某個BucketShard的數據發生變化時,對應的DataLogShard的datalog會記錄哪一個BucketShard發送了數據表更。安全

咳咳,講完data sync的三個角色,下面切入主題講講data sync的故事

    data sync的目標是將 源頭rgw Data 都同步到 目標rgw 中。話很少說,繫好安全帶,老司機直接帶你走一遭data sync流程。
    故事是這樣的,北京rgw想要開拓上海的市場,因而派DataSync去上海建立rgw並負責把北京rgw的數據資源同步到上海rgw,即data sync(北京rgw -> 上海rgw)。
    老大DataSync到達上海,來掌控整個data sync流程的進度。前面說了,全部的DataLogShard的變化即反應了rgw Data的變化。老大DataSync決定招聘${rgw_data_log_num_shards}個 小弟DataLogShardSync 來負責將北京rgw中的數據同步到上海rgw,每一個小弟負責北京rgw的一個DataLogShard。老大DataSync懂得,數據同步不是一蹴而就的,他只有記錄下同步的進度來,才能防止意外的同步失敗而致使須要從頭開始數據同步。
    因而老大DataSync用名爲rgw_data_sync_info的記錄來規劃了他第一階段工做爲StateInit,並記錄了他有${rgw_data_log_num_shards}個小弟DataLogShardSync要進行數據同步。
    struct rgw_data_sync_info { uint16_t state; uint32_t num_shards;}ide

① 老大DataSync::StateInit:
    老大DataSync須要給他num_shards個小弟DataLogShardSync設定KPI,毫無疑問,小弟DataLogShardSync的目標是遇上北京rgw的數據更新進度,老大DataSync打電話問北京rgw各個DataLogShard數據的最新marker記錄成小弟的next_step_marker,並記錄各個小弟DataLogShardSync的同步狀態爲FullSync,整理到rgw_data_sync_marker中 。
    struct rgw_data_sync_marker {uint16_t state; string next_step_marker;}
    老大DataSync將本身的工做進度(rgw_data_sync_info )和直屬小弟的工做進度(rgw_data_sync_marker)都記錄了下來到了rgw_data_sync_status中。
    struct rgw_data_sync_status {
        rgw_data_sync_info sync_info;  // 記錄data sync的總體同步進度
        map sync_markers;  // 記錄每一個DataLogShard的同步進度
    }
    這樣,老大DataSync作完了第一階段StateInit的工做,規劃作下一階段StateBuildingFullSyncMaps的工做。ui

② 老大DataSync::StateBuildingFullSyncMaps:
    老大DataSync說,北京rgw的datalog會進行截斷,若是經過datalog來同步數據到上海rgw,會致使一些數據同步不過來,因此須要進行下FullSync。而進行FullSync就是將小弟DataLogShardSync都管轄着的各個小嘍囉BucketShard中的對象逐一list出來,而後從北京rgw傳輸到上海rgw。由於須要知道小弟DataLogShardSync分別管轄着哪些小嘍囉BucketShard。老大打電話問了北京rgw,並將這些信息(每一個DataLogShard下有哪些BucketShard)記錄下來。
    這樣,老大DataSync作完了第二階段StateBuildingFullSyncMaps的工做,規劃下一階段StateSync的工做。orm

③ 老大DataSync::StateSync:
    老大在這個階段的主要工做是,監督小弟工做,老大前面已經規劃了小弟的第一階段工做是FullSync,小弟DataLogShardSync因而開始循序漸進的工做。htm

④ 小弟DataLogShardSync::FullSync:
    小弟DataLogShardSync做爲中層幹部,須要管理下屬的各個小嘍囉BucketShardSync,使用rgw_bucket_shard_sync_info來記錄下屬的每一個小嘍囉的工做狀況。
    struct rgw_bucket_shard_sync_info {
        uint16_t state;
        rgw_bucket_shard_full_sync_marker full_marker;
        rgw_bucket_shard_inc_sync_marker inc_marker;
    }
    一樣地,小弟DataLogShardSync須要給下屬的各個小嘍囉BucketShardSync安排工做。小弟將小嘍囉BucketShardSync的第一個階段工做設定爲StateInit。嗯,小弟的工做完成了,真簡單,輪到小嘍囉幹活了。對象

⑤ 小嘍囉BucketShardSync::StateInit:
    雖然小弟沒有給下屬小嘍囉設定KPI,但小嘍囉BucketShardSync很自覺,本身打電話給北京rgw問到了其對應的BucketShard的最新marker,而後記錄到本身的rgw_bucket_shard_sync_info的inc_marker中。意思是,要先full sync(全量同步)到這個marker,而後從這個marker開始inc sync(增量同步)。
    這樣,小嘍囉的第一階段工做完成了,準備進入下一階段StateFullSync。blog

⑥ 小嘍囉BucketShardSync::StateFullSync:
    在這個階段,小嘍囉會批量從北京rgw查詢其對應的BucketShard中的對象,同步到上海rgw,並持續更新full_marker,直到本身的rgw_bucket_shard_sync_info的inc_marker。結束後,小嘍囉規劃進行下一階段工做爲StateIncrementalSync。資源

嗯哼,full sync(全量同步)結束,進入inc sync(增量同步階段)。

⑦ 小弟DataLogShardSync::IncrementalSync:
    進行完full sync,終於能夠根據datalog的變化來inc sync了。打電話問問北京rgw自從上次同步點,有哪些下屬小嘍囉BucketShardSync對應的BucketShard發生數據變動。而後,安排這些小嘍囉單獨進行工做。rem

⑧ 小嘍囉BucketShardSync::StateIncrementalSync:
    小嘍囉打電話到北京rgw,問從本身的inc_marker開始,有什麼新的數據變動,而後根據數據變動來同步數據。

至此,data sync的故事講完了...

故事太長都忘了?來個簡易版:
老大DataSync::StateInit:
    更新各個DataLogShard的同步目標爲北京rgw的各個DataLogShard的最新marker
老大DataSync::StateBuildingFullSyncMaps:
    記錄各個DataLogShard下有哪些BucketShard
老大DataSync::StateSync:
    安排小弟幹活
小弟DataLogShardSync::FullSync:
    安排小嘍囉幹活
小嘍囉BucketShardSync::StateInit:
    更新本身的同步目標爲北京rgw對應BucketShard的最新marker
小嘍囉BucketShardSync::StateFullSync :
    幹活幹到本身的目標
小弟DataLogShardSync::IncrementalSync:
    根據北京rgw的DataLogShard的更新狀況,繼續安排小嘍囉幹活
小嘍囉BucketShardSync::StateIncrementalSync:
    根據北京rgw的對應BucketShard的更新狀況,繼續幹活

友情出演:
老大DataSync:
    控制着整個data sync流程的同步進度。標識進度的狀態有三個:StateInit、StateBuildingFullSyncMaps、StateSync。
小弟DataLogShardSync:
    控制着一個DataLogShard的同步進度。標識進度的狀態有兩個:FullSync、IncrementalSync。
小嘍囉BucketShardSync:
    控制着一個BucketShard的同步進度。標識進度的狀態有三個:StateInit、StateFullSync 、StateIncrementalSync。

番外篇:
    上海rgw的全部工做人員集體出走了,上海rgw新招了一堆新人,若是保持數據同步呢?新人根據rgw_data_sync_info獲知rgw data sync的進度爲StateSync,而後根據rgw_data_sync_marker獲知各個DataLogShard的同步狀態爲IncrementalSync,而後根據rgw_bucket_shard_sync_info的獲知各個BucketShard的同步進度爲StateIncrementalSync。因而,輕鬆交接工做,繼續幹活同步數據,即
DataSync::StateSync -> DataLogShardSync::IncrementalSync -> BucketShardSync::StateIncrementalSync

同步流程圖

https://www.cnblogs.com/wangmingshuai/articles/11040979.html

關注筆者

專一筆者公衆號,閱讀更多幹貨文章:)

 
相關文章
相關標籤/搜索