鬥魚直播雲原生實踐——註冊中心篇

騰訊雲原生發表於2021-09-29

孔令圳,鬥魚首席架構師,全面負責鬥魚全站技術架構體系規劃和建設,10 餘年中大型網際網路產品架構經驗,擅長高併發、高可用場景下的架構與方案設計。


於競,鬥魚技術保障運維專家,負責鬥魚高可用基礎架構建設,擅長註冊中心、監控體系等技術領域,同時也是鬥魚多活基礎保障負責人。


唐聰,騰訊雲資深工程師,極客時間專欄《etcd 實戰課》作者,etcd 活躍貢獻者,主要負責騰訊雲大規模 k8s/etcd 平臺、有狀態服務容器化、在離線混部等產品研發設計工作。


陳鵬,騰訊雲容器服務產品架構師,多年專注雲原生領域,幫助了大量使用者雲原生容器化改造和生產落地,擁有豐富的一線實踐經驗,也發表了海量的雲原生技術文章。

1業務背景和痛點 

鬥魚直播作為業界領先的遊戲直播平臺,每天為數以億計的網際網路使用者提供優質的遊戲直播觀看、互動和娛樂等服務。

隨著近年直播市場的火熱,鬥魚直播平臺作為業內口碑和體驗俱佳的網際網路公司,使用者量也出現井噴式增長。海量使用者給平臺帶來的穩定性技術挑戰也越發強烈,鬥魚的老架構如下圖所示,無論是業務支撐還是架構設計,均存在一定的風險和隱患。

鬥魚老架構  

圖一 鬥魚老架構

為了給使用者帶來更好的可用性體驗,鬥魚急需解決單一資料中心的問題,將老架構從單資料中心升級到多資料中心。

多資料中心挑戰

在實現單活升級為多活的過程中,為了確保無故障的遷移升級,我們面臨一系列挑戰,比如:

  • 有狀態服務 etcd、zookeeper 等如何多資料中心同步?
  • 應用彼此之間存在 1 個複雜的樹狀或網狀依賴關係,應該從哪裡開始遷移?
  • 按什麼維度來劃分目標的邊界,怎麼避免業務焊死在一起,造成無從下手的局面?
  • 如果遷移後出現問題,如何快速恢復,並且不牽連已遷移成功的業務?

因單活升級到多活的過程中,涉及系統眾多,本文將是鬥魚直播多活改造系列的第一篇,只聚焦於註冊中心模組,因此我們先和你介紹下注冊中心背後的 etcd 和 zookeeper。

zk/etcd 承擔的角色

dubbo 透過註冊中心來解決大規模叢集下的服務註冊與發現問題,以下是註冊中心架構圖:

dubbo 預設支援 zookeeper 註冊中心,雖然新版也有 etcd 實現,但該實現尚缺乏大規模投產的先例,Java 技術棧採用 etcd 作為註冊中心的案例也比較罕見。

當採用 zookeeper 作為 dubbo 註冊中心時,其註冊關係為樹形結構,詳細結構如下圖所示:

因為 zookeeper 是基於類似檔案系統的樹形結構來儲存資料,但 etcd 卻是採用鍵值對儲存,二者之間的差異會給註冊關係同步帶來較大困難。

此外,如果從 zookeeper 遷移到 etcd,則在整個遷移過程中:已有的線上服務不能受損,更不能停服;如果遷移失敗,還要能回退到到 zookeeper。

同城雙活與多活新架構  

為了實現多活,我們透過跨資料中心的同步服務、服務依賴梳理與邊界劃分、可控變更等技術手段和運維理念,成功解決了以上挑戰,設計瞭如下一套新的架構來實現多活,如下圖所示:

圖二 鬥魚多活新架構

在新的架構下,可以按域名甚至是 URL 來細粒度的排程流量,RPC 層面也具備了自動就近呼叫的能力,其中註冊中心的區域性架構圖如下:

圖三 鬥魚註冊中心老架構

註冊中心多活方案選型與目標

在註冊中心多活改造過程中,我們面臨多個方案,如下表所示:



由於歷史原因,我們有 zookeeper(以下簡稱 zk)和 etcd 這 2 套註冊中心,加上我們有 Java、Go、C++、PHP 這 4 個技術棧,因此在註冊中心領域仍然一些不足,希望能統一到 etcd 來解決痛點問題,並達到以下目標:

降低維護成本:此前需要運維 zk+etcd 兩套註冊中心,更困難的是做多活解決方案時也需要適配 zk+etcd,這導致註冊中心多活研發成本翻倍。由於 etcd 是 k8s 的一部分,運維 etcd 又不可避免,這是選擇 etcd 的第 1 個原因。

擁抱更繁榮的生態:etcd 有云原生託管解決方案,有廠商透過 etcd 管理 10K node 級別的 k8s 叢集,etcd 還自帶 proxy、cache、mirror 等各種周邊工具,java 側 dubbo 也支援以 etcd 作為註冊中心,etcd 相對於 zk 來說發展前景更好,這是選擇 etcd 的第 2 個原因。

增強跨語言能力:etcd 可基於 http 或 grpc 協議通訊,並且支援長輪詢,具有較強的跨語言能力。而 zk 需要引入專用客戶端,除 java 客戶端之外,其它語言客戶端尚不成熟。而我們有 JAVA、Go、C++、PHP 等 4 種研發語言,這是選擇 etcd 的第 3 個原因。

基於以上原因,我們選擇了方案四,方案四大新架構如下圖所示:

圖四 鬥魚註冊中心新架構

註冊中心多活難點與挑戰  

為了實現新註冊中心,達到我們期望的設計目標,註冊中心在改造過程中,面臨以下難點與挑戰:

  • 如何解決 zk 的多資料中心同步問題?尤其是 zookeeper watch 機制是不可靠的,可能出現丟失 watch 事件的問題?(正確性)
  • 如何解決 etcd 的多資料中心同步問題?從下面方案選型中,我們可以看到社群目前並無任何成熟、生產環境可用的解決方案。(正確性)
  • 如何解決跨資料中心讀的效能問題?(效能)
  • 如何解決跨資料中心的服務穩定性問題?網路鏈路上,比如內網專線若中斷了怎麼辦?同步服務設計上,是否會導致 etcd/zk 同步服務進入效能極慢的全同步邏輯,同步服務本身是否具備高可用等等?容災測試上,我們又該如何設計測試用例驗證?運維上,我們又該如何快速發現隱患、消除潛在的故障,建設視覺化、靈活的多活運維繫統?(穩定性、可運維性)
2註冊中心多活難點分析
遷移過程中如何保證新舊服務互通?
 開發  zk2etcd

我們很多 java 開發的業務使用 dubbo 框架做服務治理,註冊中心是 zookeeper,我們希望 java 和 go 開發的業務全部都統一使用 etcd 作為註冊中心,也為跨語言呼叫的可能性做好鋪墊。

由於業務眾多,改造和遷移的週期會很長,預計持續 1~2 年,在此過程中我們需要將 zookeeper 中的註冊資料同步到 etcd 中,實時同步,而且要保證資料一致性以及高可用,當前市面上沒有找到滿足我們需求的工具,於是我們和騰訊雲 TKE 團隊合作開發了一個 zk2etcd 來同步實現 zookeeper 資料到 etcd,並且已將其開源,整體方案落地篇我們將詳細介紹。

如何實現 etcd 異地容災?

透過 zk2etcd 同步服務,我們成功解決了 zookeeper 資料遷移問題,使得新老業務的註冊中心資料都使用 etcd 來儲存。

因此,etcd 的重要性不言而喻,它的可用性決定著我們的整體可用性,而鬥魚直播目前的部署架構又嚴重依賴某核心機房,一旦核心機房出現故障,將導致整體不可用。因此鬥魚直播下一個痛點就是提升 etcd 的可用性,期望實現 etcd 跨城容災、異地容災能力。

鬥魚直播理想中的 etcd 跨城同步服務應該具備如下特性:

  • etcd 跨城容災部署後,讀寫效能不顯著下降,能滿足業務場景基本訴求。
  • 同步元件達到生產環境可用級別,具備完備的一致性檢測、日誌、metrics 監控等。
  • 對資料一致性要求不強的業務可就近訪問同地區的 etcd 叢集服務、強一致訴求業務可訪問主 etcd 叢集。
  • 主叢集故障後,業務運維能根據一致性監控等,快速將備叢集提升為主叢集。

那麼有哪些方案呢?各個方案又有哪些優缺點呢?最終評估瞭如下幾種方案:

  • 單叢集多地部署方案
  • etcd 社群 make-mirror 方案
  • etcd 社群 learner 方案
  • 騰訊雲 etcd-syncer 方案
 單叢集多地部署方案

單叢集多地部署方案圖如下:

在此方案中,etcd Leader 節點透過 Raft 協議將資料複製到各個地域的 Follower 節點。

此方案它的優點如下:

  • 各地域網路互通後,部署簡單,無需運維額外元件

  • 資料跨城強一致同步,3 節點部署場景中,可容忍任一城市故障,並且不丟失任何資料

介紹完它的優點後,我們再看看它的缺點,如下所示:

  • 在 3 節點部署的場景下,任意寫請求至少需要兩個節點應答確認,而不同節點部署在各地,ping 延時會從幾毫秒上升到 30ms 左右(深圳 - 上海),因此會導致寫效能急劇下降。

  • etcd 預設的讀請求是線性讀,當 Follower 節點收到 Client 發起的讀請求後,它也需要向 Leader 節點獲取相關資訊,確認本地資料追趕上 Leader 後才能返回資料給 client,避免讀取到舊資料等,在這過程中也會導致 etcd 讀延時上升、吞吐量下降。

  • 跨城部署網路之間質量也較容易波動,導致服務質量抖動等。

  • client 訪問 etcd 叢集的配置,為了防止單點故障,必須配置多個 etcd 節點,而這又可能導致 client 訪問到異地的 etcd 節點,導致服務請求延時增大等。

 etcd 社群 make-mirror 方案

介紹完單叢集多地部署方案後,我們再看看 etcd 社群提供的 make-mirror 方案,它的原理圖如下:

在此方案中,我們分別在不同城市部署了一套獨立的 etcd 叢集,透過 etcd 社群提供的 make-mirror 工具實現跨城資料複製。

make-mirror 工具原理如下:

  • 指定資料同步的字首後,透過 etcd Range 讀介面從主叢集遍歷此字首下的所有資料,寫入到目的 etcd。(全量同步)
  • 隨後透過 etcd Watch 介面指定讀請求返回的“版本號”,監聽從此版本號後的所有變更事件。
  • make-mirror 收到主 etcd 叢集推送的 key-value 變化事件後,透過 txn 事務介面將資料寫入到熱備叢集。(增量同步)

此方案它的優點如下:

  • 主 etcd 叢集讀寫效能高,整體上不受跨地域網路延時、網路質量波動影響
  • 若業務可容忍短暫不一致,可就近訪問距離最近的 etcd 叢集
  • 若業務要求強一致,可透過內網專線訪問主 etcd 叢集
  • 不依賴高版本 etcd

介紹完它的優點後,我們再看看它的缺點,如下所示:

  • 當寫請求較大的時候,備叢集可能存在一定的資料落後,可能讀到髒資料。
  • 社群自帶的 make-mirror 同步鏈路中斷後,退出重啟會再次進入全量同步模式,效能較差,無法滿足生產環境訴求。
  • 社群自帶的 make-mirror 工具缺少 leader 選舉、資料一致性檢測、日誌、metrics 等一系列特性,不具備生產環境可用性。
  • 不支援同步非 key-value 資料,如 auth 鑑權相關資料、lease 資料等。
 etcd 社群 learner 方案

介紹完 etcd 社群的 make-mirror 方案後,我們再看看 etcd 社群提供的 learner 方案,它的原理圖如下:

它的核心原理如下:

  • etcd raft 演算法庫在 2017 年的時候就已經支援了 learner 節點,詳情可參考 pr 8751。
  • etcd 社群在 2019.8 月推出的 3.4 版本中,正式支援 Learner 節點,它作為非投票 (Non-Voting) 的成員節點加入叢集,不參與叢集選舉等投票,只進行資料複製。
  • Leader 收到寫請求後,將日誌同步給 Follower 和 Learner 節點,並在記憶體中使用一個名為 Progress 的資料結構,維護 Follower 和 Learner 節點的日誌同步進展資訊。
  • 當 Learner 節點的資料與 Leader 資料差距較小的時候,它就可以被提升為可投票的成員節點加入叢集。

此方案它的優點如下:

  • 各地域網路互通後,部署簡單,只需往 etcd 叢集中新增一個 Learner 節點,無需運維額外元件
  • Learner 節點可同步任意型別資料,如 key-value、auth 鑑權資料、lease 資料

介紹完它的優點後,我們再看看它的缺點,如下所示:

  • Learner 節點只允許序列讀,也就是業務如果就近讀,會讀到舊資料。
  • 依賴高版本 etcd,etcd 3.4 及以上版本才支援 Learner 特性,並且只允許一個 Learner 節點 .
  • 主叢集全面故障後,無法快速將 Learner 節點提升為可寫的獨立 etcd 叢集。

介紹完已有的幾種方案後,我們發現它們都無法滿足業務生產環境訴求,於是我們自研完成了生產環境可用的 etcd 同步服務落地,在整體方案落地章節將詳細介紹。

如何確保 etcd 和 zk 同步服務的穩定性、可運維性?  

為了確保 etcd、zk 同步服務的穩定性,模擬 5 類常見的故障,檢驗服務在這些典型故障場景下的自愈能力,詳細測試方案如下。

 故障場景
  1. redis 閃斷 (zk2etcd 服務依賴),例如:redis 版本升級、非平滑擴容。

  2. zk 2etcd 離 ,例如:OOM、容器驅逐、宿主機故障。


  3. etc d2etcd 離線 ,例如:OOM、容器驅逐、宿主機故障

  4. 網路閃斷,例如:OOM、容器驅逐、宿主機故障。

  5. 弱網環境,例如:專線斷掉後臨時用公網頂替。

上述 5 種場景的實際觸發原因有多種多樣,只需要模擬出一種情況。

 演練方案
  1. redis 閃斷:透過改 host 模擬 redis 不可達,此時自動訂正停止;模擬 redis 恢復後,自動訂正亦自動恢復。

  2. z k2etcd  離線:透過殺容器節點模擬 zk2etcd 掛掉,15 秒內 k8s 自動拉起,拉起完成後同步正常、資料一致。

  3. etc d2e tcd 離線 :透過殺容器節點模擬 zk2etcd 掛掉,15 秒內 k8s 自動拉起,拉起完成後同步正常、資料一致。

  4. 網路閃斷: 透過改 host 模擬 zk、etcd 不可達,此時同步中斷,後去掉 host 模擬網路恢復,恢復後同步正常、資料一致。

  5. 弱網環境: 透過切公網模擬弱網環境,切公網後同步效率降低在 4 倍以內,1 次全量同步仍然可在 1 分鐘內完成。

另外針對可運維性問題,無論是 etcd 還是 zk 同步服務,都提供了詳細的 metrics、日誌,我們針對各個核心場景、異常場景都配置了視覺化的觀測檢視,並配置了告警策略。

3整體方案落地
整體架構
  • etcd 叢集多活架構圖如下所示:

說明

黑實線:正常情況下的專線訪問

黑虛線:切公網方式訪問

紅實線:etcd 叢集,發生主備切換後的專線訪問

紅虛線:etcd 叢集,發生主備切換後的公網訪問

  • etcd2etcd/zk2etcd 資料同步服務圖如下所示:

 

zk同步服務工程化實踐

zookeeper 與 etcd 儲存結構不一致,加大了同步的實現難度。zookeeper 儲存是樹狀結構,而 etcd v3 是扁平結構。zookeeper 無法像 etcd 一樣按照 prefix 來 list 所有 key;etcd 無法像 zookeeper 一樣透過 list chilren 來查詢某個目錄下的子節點,也加大了實現同步的難度。

如何感知 zookeeper 中的資料變化?zookeeper 的 watch 不像 etcd 一樣可以簡單的感知到任意 key 的新增,需要遞迴的 watch 所有的節點,收到 ChildrenChanged 事件後拿到該事件對應節點下的所有子節點,再與 etcd 中的資料進行比對,就可以得到新增的資料,並將其同步 put 到 etcd 中。類似的,可以用遞迴的方法 watch 所有節點的刪除事件,並同步刪除 etcd 中的資料。

另外 zookeeper 的 watch 有著先天性的缺陷,watch 是一次性的,所以每次收到事件後又必須重新 watch,兩次 watch 之間理論上是可能丟事件的,主要是在同一個 key 連續多次變更的時候可能會發生。如果丟事件發生就會破壞了資料一致性,我們引入了自動 diff 和訂正的能力,即計算 zookeeper 和 etcd 中資料存在的差異,每次都會經過兩輪 diff 計算,因為在頻繁變更資料的情況下,一輪 diff 計算往往存在一些因不是強一致性同步導致的"偽差異",當 diff 計算出了結果就會自動 fix 掉這些差異。

如何解決與 etcd2etcd 共存?當同一個路徑下,即有 etcd2etcd 同步寫入的資料,又有 zk2etcd 寫入的資料,在 zk2etcd 的自動訂正邏輯裡面,會計算出差異並訂正差異,但我們不希望因此而誤刪 etcd2etcd 寫入的資料。我們透過為 zk2etcd 引入了 redis 來儲存狀態解決了這個問題,在 zk2etcd 往 etcd 中同步寫入或刪除資料時,也同步在 redis 中記錄和刪除:

然後 zk2etcd 在自動訂正計算差異的時候,只考慮本工具寫入過的資料,避免誤刪其它同步工具寫入的資料。

etcd2etcd 工程化實踐 

為了解決 etcd 同步難題,我們調研瞭如下兩種方案,接下來我們就詳細介紹下它的原理:

 etcd-syncer 之 mirror-plus 版

首先我們介紹下 etcd-syncer 的 mirror-plus 方案,顧名思義,它是 etcd 社群 make-mirror 的加強版。為了解決 make-mirror 的各種缺陷,它實現了以下特性、優點:

  • 支援多種同步模式,全量同步、斷點續傳,不再擔憂專線、公網網路質量抖動
  • 高可用,負責同一資料路徑複製的例項支援多副本部署, 一副本故障後,其他副本將在 5 秒後獲得鎖,在之前例項同步的進度基礎上,進行快速恢復
  • 支援一致性檢查(全量資料檢查、快照檢查)
  • 支援多例項併發複製提升效能(不同例項負責不同的路徑),建議生產環境配置多例項,每個例項負責不同路徑
  • 良好的運維能力,基於 k8s deployment 一鍵部署,豐富的 metrics、日誌,完備的 e2e 測試用例覆蓋核心場景(http/https 場景,服務異常中斷、網路異常等 )

那麼它的缺點是什麼呢?因為它核心原理依然是依賴 etcd 的 mvcc+watch 特性,因此資料無法保證強一致性和只同步 key-value 資料。

  • 斷點續傳依賴 mvcc 歷史版本保留時間,最好業務能儲存至少 1 個小時的歷史資料。
  • 當寫請求較大的時候,備叢集可能存在一定的資料落後,可能讀到髒資料。
  • 不支援同步非 key-value 資料,如 auth 鑑權相關資料、lease 資料等。

 etcd-syncer 之 Raft 版

為了解決所有型別的資料同步問題以及消除對 etcd mvcc 歷史資料的依賴,騰訊雲還可提供基於 Raft 日誌的同步方案 etcd-syncer 之 raft 版本。

它的部署圖如下所示,etcd-syncer 同步服務作為一個類似 learner 節點的身份,加入主 etcd 叢集。

主 etcd 叢集 Leader 將 Raft 日誌資料透過 MsgApp/Snapshot 等訊息同步給 etcd-syncer, etcd-syncer 解析 Raft 日誌,將 Raft 日誌條目對應的 Txn/Delete/Auth 等請求應用到目的 etcd 叢集。

它具備如下優點:

  • 具備 etcd-syncer 之 mirror-plus 版本的所有特性和優點,同時不依賴 etcd mvcc 歷史資料。

  • 基於 etcd 底層的 Raft 日誌同步資料,可以同步 key-value、auth、lease 等各種型別的資料。

  • 不依賴高版本的 etcd。

完備的容災測試  
 grpc-proxy

此方案引入了 grpc-proxy 代理服務,也是頭一次使用。為了瞭解此代理服務的效能情況,我們使用 etcd 自帶的 benchmark 進行了讀和寫的測試,另外手寫了一個小工具做了一下 watch 測試。以下為部分測試內容。

寫入測試

直接訪問 etcd 服務的負載均衡入口

走 grpc-proxy 代理訪問 etcd 服務的情況

  • grpc-proxy 代理在 endpoints 配置走專線或公網情況下,都能正常寫入
  • 寫入 key 總數一定的情況下,連線數和客戶端數越大,總耗時越低
  • 寫入 key 總數越大,單次寫入的平均耗時(Average)會有所增加,但仍為毫秒級
  • 當一次寫入 key 總數為 10 萬時,直連 etcdserver 會出現 too many requests 的報錯,但 grpc-proxy 沒有
  • 公網情況比專線效能有所下降
  • 走 grpc-proxy 代理的平均耗時相比直連有所增加,但滿足需求

讀取測試

直接訪問 etcd 服務的負載均衡入口

走 grpc-proxy 代理訪問 etcd 服務的情況

  • grpc-proxy 代理在 endpoints 配置走專線或公網情況下,都能正常讀取

  • 走 grpc-proxy 代理的平均耗時相比直連有所增加,但在可接受範圍

watch 測試

根據我們自己寫的一個 etcdwatcher 服務對 grpc-proxy 進行 watch 測試:可以設定總 watcher 數量,更新頻率,以及測試時間,結束時列印出簡報

    ./etcdwatch -num=100 -span=500 -duration=10 -endpoint= 
    test done
    total 100 task
    0 task failed
    current revision is 631490
    least revision is 631490
    0 task is not synced

    引數說明:

    • num 任務數量

    • span 更新間隔,單位毫秒

    • duration 總測試時間,單位秒

    • current revision:代表寫入的 revision

    • least revision:表示 num 個任務中同步最慢的 revision

    • failed 為 0 說明正常;如果過出現 task not sync 說明 watch 和 put 不同步

    以上測試結果來看:failed 數為 0,watch 測試正常

     zk2etcd

    我們使用的是 1.2.5 版本,透過 k8s 的 deployment 方式部署

    1. 模擬 zk server 失聯

    場景
    • 透過將 hosts 中注入錯誤解析地址

    現象
    • 期間沒有發現 zk 失聯的報錯日誌
    • 監控指標沒有發現異常
    • 此後執行重啟,fixed 運算元沒有出現凸增情況(在 1.2.4 版本中,存在 full sync 雖然在定時執行,但是並沒有感知到需要 fix 的 key 的 bug。導致重啟 zk2etcd 服務例項後,可能觀察到 fixed 操作凸增的現象)

    2.模擬 redis 失聯

    模擬操作
    • 09:56:49 將 hosts 中注入 redis 錯誤解析地址
    • 10:07:34 恢復 redis
    • 10:16:00 重啟同步服務 pod(操作重啟是為了觀察 full sync 是否正常)

    現象
    • 期間 fixed operation 數量沒有增長,其他監控指標未發現明顯異常
    • 例項重啟後沒有出現 fixed 數凸增的情況


    3. 模擬etcd失聯

    模擬操作
    • 16:15:10 etcd server 失聯

    • 16:30 恢復

    • 16:45 重啟 pod

    現象
    • 期間 fixed operation 數量沒有增長,其他監控指標未發現明顯異常

    • 此後重啟,fixed operation 數量有所增漲(不能確定是 full sync 未生效,還是重啟後剛好有更新修復導致)

    總結

    • 只要 full sync 機制工作正常,各異常場景發生後,都能在下一個 full sync 觸發後被恢復

    • 恢復的最小時間間隔取決於設定的 full sync 定時執行間隔時間(預設為 5m),業務對此間隔時間容忍情況自行調整引數

    • 此外,為了避免異常發生後,full sync 機制定時執行但也沒能感知到情況發生,保險起見事後可以第一時間重啟一下 zk2etcd 服務

    • 對於追加的 etcd 公網測試,full sync completed 和 zk、etcd 操作耗時,相比內網情況有一定(秒級)增長

     etcd2etcd

    etcd2etcd 的同步服務,我採用 deployment 雙副本部署

    1. 多副本 backup 能力

    期望
    • ⼯作節點故障後備⽤節點會在 5s 後接管同步任務

    測試方案
    • etcd syncer 雙例項部署

    • 殺掉正在執行的工作節點進行觀察

    結論

    不論是增量同步還是全量同步過程中,主備切換都能正常工作(需要注意的是,當全量同步中發生主備切換後會變為增量同步,從而可能導致比對較慢)

    1. 斷點續傳能力

    期望
    • 故障恢復後能從斷點繼續開始同步

    其實在第 1 部分,備節點切換為主後接管同步工作,fast_path 變為 1 也證明了斷點續傳能力,我們還額外補充幾個驗證場景:

    (a) 短時間故障

    故障場景

    • 中心 etcd 叢集到熱備叢集的同步過程中,因作為源的中心 etcd 叢集中也存在 -etcd-syncer-meta- 的 key,觸發了同步服務報錯(同 txn 中不能包含相同的 key),出現了資料差異

    現象

    • 將同步服務執行引數新增對 -etcd-syncer-meta- 的過濾,然後觀察進過一段時間追趕資料後,最終 miss 數降去達到一致

    (b) 長時間故障

    故障場景

    • 停止同步服務的部署 deployment

    • 等待兩邊 etcd 叢集產生資料差異,併發生一次 compact 後再啟動同步服務

    現象

    • 等產生資料差異,併發生 compact 後,重新啟動同步服務,其日誌如下:因 compacted 發生,觸發全量同步

    • 同步服務監控指標:(a) dst miss key 很快降下去;(b) src miss key 有所增加,並持續不降

    分析

    • 同步服務停止以後,源 etcd 的 key 數量發生不少變化,監控圖看出期間有下降,說明發生過 key 的刪除

    • 這裡也暴露出一個小問題,當出現 src miss key 的時候,目前不能自動修復,需要人工接入清理多餘的 key


      3.  res et 觸發全量同步

    當同步發生重大差異(如,發生 dst miss)進行緊急修復的時候,透過配置 --reset-last-synced-rev 引數刪除斷點續傳資訊,來觸發全量同步修復差異

    現象

    因某種異常,同步出現 dst miss(圖中黃線例項)的情況。為了進行修復,新例項新增 --reset-last-synced-rev 引數後執行

    分析

    • slow_path 為 1,說明觸發全量同步(圖中綠線例項)

    • 綠線例項的 dst miss 值沒有增長起來,說明已經達到一致


    4. 網路故障

    兩 etcd 叢集之間專線中斷

    • 增量同步中

    • 全量同步中

    測試方案

    • 當專線中斷切換公網時,需要修改執行引數中的 etcd 叢集訪問地址,即:必會發生重啟(重啟場景測試前面已經涵蓋,這裡不再重複)

    總結

    • etcd-syncer 同步服務有較好的主備機制,能夠及時有效的進行切換

    • 短時間故障後的斷點續傳表現符合預期;對於長時間故障,同時發生 compact 的複雜情況時,恢復同步後出現 src miss 的情況,可能需要人工接入

    • 透過配置 --reset-last-synced-rev 引數對 src miss 的異常修復有較好的效果


    來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69984638/viewspace-2794360/,如需轉載,請註明出處,否則將追究法律責任。

    相關文章