日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

斗鱼基于etcd和ZooKeeper的注册中心实践案例

發(fā)布時(shí)間:2023/12/10 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 斗鱼基于etcd和ZooKeeper的注册中心实践案例 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

業(yè)務(wù)背景和痛點(diǎn)

斗魚直播作為業(yè)界領(lǐng)先的游戲直播平臺(tái),每天為數(shù)以億計(jì)的互聯(lián)網(wǎng)用戶提供優(yōu)質(zhì)的游戲直播觀看、互動(dòng)和娛樂等服務(wù)。

隨著近年直播市場(chǎng)的火熱,斗魚直播平臺(tái)作為業(yè)內(nèi)口碑和體驗(yàn)俱佳的互聯(lián)網(wǎng)公司,用戶量也出現(xiàn)井噴式增長。海量用戶給平臺(tái)帶來的穩(wěn)定性技術(shù)挑戰(zhàn)也越發(fā)強(qiáng)烈,斗魚的老架構(gòu)如下圖所示,無論是業(yè)務(wù)支撐還是架構(gòu)設(shè)計(jì),均存在一定的風(fēng)險(xiǎn)和隱患。

斗魚老架構(gòu)

圖一 斗魚老架構(gòu)

為了給用戶帶來更好的可用性體驗(yàn),斗魚急需解決單一數(shù)據(jù)中心的問題,將老架構(gòu)從單數(shù)據(jù)中心升級(jí)到多數(shù)據(jù)中心。

多數(shù)據(jù)中心挑戰(zhàn)

在實(shí)現(xiàn)單活升級(jí)為多活的過程中,為了確保無故障的遷移升級(jí),我們面臨一系列挑戰(zhàn),比如:

  • 有狀態(tài)服務(wù) etcd、ZooKeeper 等如何多數(shù)據(jù)中心同步?

  • 應(yīng)用彼此之間存在 1 個(gè)復(fù)雜的樹狀或網(wǎng)狀依賴關(guān)系,應(yīng)該從哪里開始遷移?

  • 按什么維度來劃分目標(biāo)的邊界,怎么避免業(yè)務(wù)焊死在一起,造成無從下手的局面?

  • 如果遷移后出現(xiàn)問題,如何快速恢復(fù),并且不牽連已遷移成功的業(yè)務(wù)?

因單活升級(jí)到多活的過程中,涉及系統(tǒng)眾多,本文將是斗魚直播多活改造系列的第一篇,只聚焦于注冊(cè)中心模塊,因此我們先和你介紹下注冊(cè)中心背后的 etcd 和 ZooKeeper。

ZooKeeper/etcd 承擔(dān)的角色

Dubbo 通過注冊(cè)中心來解決大規(guī)模集群下的服務(wù)注冊(cè)與發(fā)現(xiàn)問題,以下是注冊(cè)中心架構(gòu)圖:

Dubbo 默認(rèn)支持 ZooKeeper 注冊(cè)中心,雖然新版也有 etcd 實(shí)現(xiàn),但該實(shí)現(xiàn)尚缺乏大規(guī)模投產(chǎn)的先例,Java 技術(shù)棧采用 etcd 作為注冊(cè)中心的案例也比較罕見。

當(dāng)采用 ZooKeeper 作為 Dubbo 注冊(cè)中心時(shí),其注冊(cè)關(guān)系為樹形結(jié)構(gòu),詳細(xì)結(jié)構(gòu)如下圖所示:

因?yàn)?ZooKeeper 是基于類似文件系統(tǒng)的樹形結(jié)構(gòu)來存儲(chǔ)數(shù)據(jù),但 etcd 卻是采用鍵值對(duì)存儲(chǔ),二者之間的差異會(huì)給注冊(cè)關(guān)系同步帶來較大困難。

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

同城雙活與多活新架構(gòu)

為了實(shí)現(xiàn)多活,我們通過跨數(shù)據(jù)中心的同步服務(wù)、服務(wù)依賴梳理與邊界劃分、可控變更等技術(shù)手段和運(yùn)維理念,成功解決了以上挑戰(zhàn),設(shè)計(jì)了如下一套新的架構(gòu)來實(shí)現(xiàn)多活,如下圖所示:

圖二 斗魚多活新架構(gòu)

在新的架構(gòu)下,可以按域名甚至是 URL 來細(xì)粒度的調(diào)度流量,RPC 層面也具備了自動(dòng)就近調(diào)用的能力,其中注冊(cè)中心的局部架構(gòu)圖如下:

圖三 斗魚注冊(cè)中心老架構(gòu)

注冊(cè)中心多活方案選型與目標(biāo)

在注冊(cè)中心多活改造過程中,我們面臨多個(gè)方案,如下表所示:

由于歷史原因,我們有 ZooKeeper(以下簡稱 zk)和 etcd 這 2 套注冊(cè)中心,加上我們有 Java、Go、C++、PHP 這 4 個(gè)技術(shù)棧,因此在注冊(cè)中心領(lǐng)域仍然有一些不足,希望能統(tǒng)一到 etcd 來解決痛點(diǎn)問題,并達(dá)到以下目標(biāo):

降低維護(hù)成本:此前需要運(yùn)維 zk + etcd 兩套注冊(cè)中心,更困難的是做多活解決方案時(shí)也需要適配 zk + etcd,這導(dǎo)致注冊(cè)中心多活研發(fā)成本翻倍。由于 etcd 是 Kubernetes 的一部分,運(yùn)維 etcd 又不可避免,這是選擇 etcd 的第 1 個(gè)原因。

擁抱更繁榮的生態(tài):etcd 有云原生托管解決方案,有廠商通過 etcd 管理 10K Node 級(jí)別的 Kubernetes 集群,etcd 還自帶 proxy、cache、mirror 等各種周邊工具,Java 側(cè) Dubbo 也支持以 etcd 作為注冊(cè)中心,etcd 相對(duì)于 zk 來說發(fā)展前景更好,這是選擇 etcd 的第 2 個(gè)原因。

增強(qiáng)跨語言能力:etcd 可基于 http 或 gRPC 協(xié)議通訊,并且支持長輪詢,具有較強(qiáng)的跨語言能力。而 zk 需要引入專用客戶端,除 java 客戶端之外,其它語言客戶端尚不成熟。而我們有 Java、Go、C++、PHP 等 4 種研發(fā)語言,這是選擇 etcd 的第 3 個(gè)原因。

基于以上原因,我們選擇了方案四,方案四大新架構(gòu)如下圖所示:

圖四 斗魚注冊(cè)中心新架構(gòu)

注冊(cè)中心多活難點(diǎn)與挑戰(zhàn)

為了實(shí)現(xiàn)新注冊(cè)中心,達(dá)到我們期望的設(shè)計(jì)目標(biāo),注冊(cè)中心在改造過程中,面臨以下難點(diǎn)與挑戰(zhàn):

  • 如何解決 zk 的多數(shù)據(jù)中心同步問題?尤其是 zookeeper watch 機(jī)制是不可靠的,可能出現(xiàn)丟失 watch 事件的問題?(正確性)

  • 如何解決 etcd 的多數(shù)據(jù)中心同步問題?從下面方案選型中,我們可以看到社區(qū)目前并無任何成熟、生產(chǎn)環(huán)境可用的解決方案。(正確性)

  • 如何解決跨數(shù)據(jù)中心讀的性能問題?(性能)

  • 如何解決跨數(shù)據(jù)中心的服務(wù)穩(wěn)定性問題?網(wǎng)絡(luò)鏈路上,比如內(nèi)網(wǎng)專線若中斷了怎么辦?同步服務(wù)設(shè)計(jì)上,是否會(huì)導(dǎo)致 etcd/zk 同步服務(wù)進(jìn)入性能極慢的全同步邏輯,同步服務(wù)本身是否具備高可用等等?容災(zāi)測(cè)試上,我們又該如何設(shè)計(jì)測(cè)試用例驗(yàn)證?運(yùn)維上,我們又該如何快速發(fā)現(xiàn)隱患、消除潛在的故障,建設(shè)可視化、靈活的多活運(yùn)維系統(tǒng)?(穩(wěn)定性、可運(yùn)維性)

注冊(cè)中心多活難點(diǎn)分析

遷移過程中如何保證新舊服務(wù)互通?

開發(fā) zk2etcd

我們很多 Java 開發(fā)的業(yè)務(wù)使用 Dubbo 框架做服務(wù)治理,注冊(cè)中心是 ZooKeeper,我們希望 Java 和 Go 開發(fā)的業(yè)務(wù)全部都統(tǒng)一使用 etcd 作為注冊(cè)中心,也為跨語言調(diào)用的可能性做好鋪墊。

由于業(yè)務(wù)眾多,改造和遷移的周期會(huì)很長,預(yù)計(jì)持續(xù) 1~2 年,在此過程中我們需要將 zookeeper 中的注冊(cè)數(shù)據(jù)同步到 etcd 中,實(shí)時(shí)同步,而且要保證數(shù)據(jù)一致性以及高可用,當(dāng)前市面上沒有找到滿足我們需求的工具,于是我們和騰訊云 TKE 團(tuán)隊(duì)合作開發(fā)了一個(gè) zk2etcd 來同步實(shí)現(xiàn) ZooKeeper 數(shù)據(jù)到 etcd,并且已將其開源,整體方案落地篇我們將詳細(xì)介紹。

如何實(shí)現(xiàn) etcd 異地容災(zāi)?

通過 zk2etcd 同步服務(wù),我們成功解決了 ZooKeeper 數(shù)據(jù)遷移問題,使得新老業(yè)務(wù)的注冊(cè)中心數(shù)據(jù)都使用 etcd 來存儲(chǔ)。

因此,etcd 的重要性不言而喻,它的可用性決定著我們的整體可用性,而斗魚直播目前的部署架構(gòu)又嚴(yán)重依賴某核心機(jī)房,一旦核心機(jī)房出現(xiàn)故障,將導(dǎo)致整體不可用。因此斗魚直播下一個(gè)痛點(diǎn)就是提升 etcd 的可用性,期望實(shí)現(xiàn) etcd 跨城容災(zāi)、異地容災(zāi)能力。

斗魚直播理想中的 etcd 跨城同步服務(wù)應(yīng)該具備如下特性:

  • etcd 跨城容災(zāi)部署后,讀寫性能不顯著下降,能滿足業(yè)務(wù)場(chǎng)景基本訴求。

  • 同步組件達(dá)到生產(chǎn)環(huán)境可用級(jí)別,具備完備的一致性檢測(cè)、日志、Metrics 監(jiān)控等。

  • 對(duì)數(shù)據(jù)一致性要求不強(qiáng)的業(yè)務(wù)可就近訪問同地區(qū)的 etcd 集群服務(wù)、強(qiáng)一致訴求業(yè)務(wù)可訪問主 etcd 集群。

  • 主集群故障后,業(yè)務(wù)運(yùn)維能根據(jù)一致性監(jiān)控等,快速將備集群提升為主集群。

那么有哪些方案呢?各個(gè)方案又有哪些優(yōu)缺點(diǎn)呢?最終評(píng)估了如下幾種方案:

  • 單集群多地部署方案

  • etcd 社區(qū) make-mirror 方案

  • etcd 社區(qū) learner 方案

  • 騰訊云 etcd-syncer 方案

單集群多地部署方案

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

在此方案中,etcd Leader 節(jié)點(diǎn)通過 Raft 協(xié)議將數(shù)據(jù)復(fù)制到各個(gè)地域的 Follower 節(jié)點(diǎn)。

此方案它的優(yōu)點(diǎn)如下:

  • 各地域網(wǎng)絡(luò)互通后,部署簡單,無需運(yùn)維額外組件

  • 數(shù)據(jù)跨城強(qiáng)一致同步,3 節(jié)點(diǎn)部署場(chǎng)景中,可容忍任一城市故障,并且不丟失任何數(shù)據(jù)

介紹完它的優(yōu)點(diǎn)后,我們?cè)倏纯此娜秉c(diǎn),如下所示:

  • 在 3 節(jié)點(diǎn)部署的場(chǎng)景下,任意寫請(qǐng)求至少需要兩個(gè)節(jié)點(diǎn)應(yīng)答確認(rèn),而不同節(jié)點(diǎn)部署在各地,ping 延時(shí)會(huì)從幾毫秒上升到 30ms 左右(深圳 - 上海),因此會(huì)導(dǎo)致寫性能急劇下降。

  • etcd 默認(rèn)的讀請(qǐng)求是線性讀,當(dāng) Follower 節(jié)點(diǎn)收到 Client 發(fā)起的讀請(qǐng)求后,它也需要向 Leader 節(jié)點(diǎn)獲取相關(guān)信息,確認(rèn)本地?cái)?shù)據(jù)追趕上 Leader 后才能返回?cái)?shù)據(jù)給 client,避免讀取到舊數(shù)據(jù)等,在這過程中也會(huì)導(dǎo)致 etcd 讀延時(shí)上升、吞吐量下降。

  • 跨城部署網(wǎng)絡(luò)之間質(zhì)量也較容易波動(dòng),導(dǎo)致服務(wù)質(zhì)量抖動(dòng)等。

  • client 訪問 etcd 集群的配置,為了防止單點(diǎn)故障,必須配置多個(gè) etcd 節(jié)點(diǎn),而這又可能導(dǎo)致 client 訪問到異地的 etcd 節(jié)點(diǎn),導(dǎo)致服務(wù)請(qǐng)求延時(shí)增大等。

etcd 社區(qū) make-mirror 方案

介紹完單集群多地部署方案后,我們?cè)倏纯?etcd 社區(qū)提供的 make-mirror 方案,它的原理圖如下:

在此方案中,我們分別在不同城市部署了一套獨(dú)立的 etcd 集群,通過 etcd 社區(qū)提供的 make-mirror 工具實(shí)現(xiàn)跨城數(shù)據(jù)復(fù)制。

make-mirror 工具原理如下:

  • 指定數(shù)據(jù)同步的前綴后,通過 etcd Range 讀接口從主集群遍歷此前綴下的所有數(shù)據(jù),寫入到目的 etcd。(全量同步)

  • 隨后通過 etcd Watch 接口指定讀請(qǐng)求返回的“版本號(hào)”,監(jiān)聽從此版本號(hào)后的所有變更事件。

  • make-mirror 收到主 etcd 集群推送的 key-value 變化事件后,通過 txn 事務(wù)接口將數(shù)據(jù)寫入到熱備集群。(增量同步)

此方案它的優(yōu)點(diǎn)如下:

  • 主 etcd 集群讀寫性能高,整體上不受跨地域網(wǎng)絡(luò)延時(shí)、網(wǎng)絡(luò)質(zhì)量波動(dòng)影響

  • 若業(yè)務(wù)可容忍短暫不一致,可就近訪問距離最近的 etcd 集群

  • 若業(yè)務(wù)要求強(qiáng)一致,可通過內(nèi)網(wǎng)專線訪問主 etcd 集群

  • 不依賴高版本 etcd

介紹完它的優(yōu)點(diǎn)后,我們?cè)倏纯此娜秉c(diǎn),如下所示:

  • 當(dāng)寫請(qǐng)求較大的時(shí)候,備集群可能存在一定的數(shù)據(jù)落后,可能讀到臟數(shù)據(jù)。

  • 社區(qū)自帶的 make-mirror 同步鏈路中斷后,退出重啟會(huì)再次進(jìn)入全量同步模式,性能較差,無法滿足生產(chǎn)環(huán)境訴求。

  • 社區(qū)自帶的 make-mirror 工具缺少 leader 選舉、數(shù)據(jù)一致性檢測(cè)、日志、Metrics 等一系列特性,不具備生產(chǎn)環(huán)境可用性。

  • 不支持同步非 key-value 數(shù)據(jù),如 auth 鑒權(quán)相關(guān)數(shù)據(jù)、lease 數(shù)據(jù)等。

etcd 社區(qū) Learner 方案

介紹完 etcd 社區(qū)的 make-mirror 方案后,我們?cè)倏纯?etcd 社區(qū)提供的 learner 方案,它的原理圖如下:

它的核心原理如下:

  • etcd raft 算法庫在 2017 年的時(shí)候就已經(jīng)支持了 Learner 節(jié)點(diǎn),詳情可參考 pr 8751。

  • etcd 社區(qū)在 2019.8 月推出的 3.4 版本中,正式支持 Learner 節(jié)點(diǎn),它作為非投票(Non-Voting)的成員節(jié)點(diǎn)加入集群,不參與集群選舉等投票,只進(jìn)行數(shù)據(jù)復(fù)制。

  • Leader 收到寫請(qǐng)求后,將日志同步給 Follower 和 Learner 節(jié)點(diǎn),并在內(nèi)存中使用一個(gè)名為 Progress 的數(shù)據(jù)結(jié)構(gòu),維護(hù) Follower 和 Learner 節(jié)點(diǎn)的日志同步進(jìn)展信息。

  • 當(dāng) Learner 節(jié)點(diǎn)的數(shù)據(jù)與 Leader 數(shù)據(jù)差距較小的時(shí)候,它就可以被提升為可投票的成員節(jié)點(diǎn)加入集群。

此方案它的優(yōu)點(diǎn)如下:

  • 各地域網(wǎng)絡(luò)互通后,部署簡單,只需往 etcd 集群中添加一個(gè) Learner 節(jié)點(diǎn),無需運(yùn)維額外組件

  • Learner 節(jié)點(diǎn)可同步任意類型數(shù)據(jù),如 key-value、auth 鑒權(quán)數(shù)據(jù)、lease 數(shù)據(jù)

介紹完它的優(yōu)點(diǎn)后,我們?cè)倏纯此娜秉c(diǎn),如下所示:

  • Learner 節(jié)點(diǎn)只允許串行讀,也就是業(yè)務(wù)如果就近讀,會(huì)讀到舊數(shù)據(jù)。

  • 依賴高版本 etcd,etcd 3.4 及以上版本才支持 Learner 特性,并且只允許一個(gè) Learner 節(jié)點(diǎn)。

  • 主集群全面故障后,無法快速將 Learner 節(jié)點(diǎn)提升為可寫的獨(dú)立 etcd 集群。

介紹完已有的幾種方案后,我們發(fā)現(xiàn)它們都無法滿足業(yè)務(wù)生產(chǎn)環(huán)境訴求,于是我們自研完成了生產(chǎn)環(huán)境可用的 etcd 同步服務(wù)落地,在整體方案落地章節(jié)將詳細(xì)介紹。

如何確保 etcd 和 ZooKeeper 同步服務(wù)的穩(wěn)定性、可運(yùn)維性?

為了確保 etcd、ZooKeeper 同步服務(wù)的穩(wěn)定性,模擬 5 類常見的故障,檢驗(yàn)服務(wù)在這些典型故障場(chǎng)景下的自愈能力,詳細(xì)測(cè)試方案如下。

故障場(chǎng)景

  • Redis 閃斷(zk2etcd 服務(wù)依賴),例如:Redis 版本升級(jí)、非平滑擴(kuò)容。

  • zk2etcd 離線,例如:OOM、容器驅(qū)逐、宿主機(jī)故障。

  • etcd2etcd 離線?,例如:OOM、容器驅(qū)逐、宿主機(jī)故障

  • 網(wǎng)絡(luò)閃斷,例如:OOM、容器驅(qū)逐、宿主機(jī)故障。

  • 弱網(wǎng)環(huán)境,例如:專線斷掉后臨時(shí)用公網(wǎng)頂替。

  • 上述 5 種場(chǎng)景的實(shí)際觸發(fā)原因有多種多樣,只需要模擬出一種情況。

    演練方案

  • Redis 閃斷:通過改 host 模擬 Redis 不可達(dá),此時(shí)自動(dòng)訂正停止;模擬 Redis 恢復(fù)后,自動(dòng)訂正亦自動(dòng)恢復(fù)。

  • zk2etcd 離線:通過殺容器節(jié)點(diǎn)模擬 zk2etcd 掛掉,15 秒內(nèi) Kubernetes 自動(dòng)拉起,拉起完成后同步正常、數(shù)據(jù)一致。

  • etcd2etcd 離線:通過殺容器節(jié)點(diǎn)模擬 zk2etcd 掛掉,15 秒內(nèi) Kubernetes 自動(dòng)拉起,拉起完成后同步正常、數(shù)據(jù)一致。

  • 網(wǎng)絡(luò)閃斷:通過改 host 模擬 ZooKeeper、etcd 不可達(dá),此時(shí)同步中斷,后去掉 host 模擬網(wǎng)絡(luò)恢復(fù),恢復(fù)后同步正常、數(shù)據(jù)一致。

  • 弱網(wǎng)環(huán)境:通過切公網(wǎng)模擬弱網(wǎng)環(huán)境,切公網(wǎng)后同步效率降低在 4 倍以內(nèi),1 次全量同步仍然可在 1 分鐘內(nèi)完成。

  • 另外針對(duì)可運(yùn)維性問題,無論是 etcd 還是 ZooKeeper 同步服務(wù),都提供了詳細(xì)的 Metrics、日志,我們針對(duì)各個(gè)核心場(chǎng)景、異常場(chǎng)景都配置了可視化的觀測(cè)視圖,并配置了告警策略。

    整體方案落地

    整體架構(gòu)

    etcd 集群多活架構(gòu)圖如下所示:

    說明:

    • 黑實(shí)線:正常情況下的專線訪問

    • 黑虛線:切公網(wǎng)方式訪問

    • 紅實(shí)線:etcd 集群發(fā)生主備切換后的專線訪問

    • 紅虛線:etcd 集群發(fā)生主備切換后的公網(wǎng)訪問

    etcd2etcd/zk2etcd 數(shù)據(jù)同步服務(wù)圖如下所示:

    ZooKeeper 同步服務(wù)工程化實(shí)踐

    ZooKeeper 與 etcd 存儲(chǔ)結(jié)構(gòu)不一致,加大了同步的實(shí)現(xiàn)難度。ZooKeeper 存儲(chǔ)是樹狀結(jié)構(gòu),而 etcd v3 是扁平結(jié)構(gòu)。ZooKeeper 無法像 etcd 一樣按照 prefix 來 list 所有 key;etcd 無法像 ZooKeeper 一樣通過 list chilren 來查詢某個(gè)目錄下的子節(jié)點(diǎn),也加大了實(shí)現(xiàn)同步的難度。

    如何感知 ZooKeeper 中的數(shù)據(jù)變化?ZooKeeper 的 watch 不像 etcd 一樣可以簡單的感知到任意 key 的新增,需要遞歸的 watch 所有的節(jié)點(diǎn),收到 ChildrenChanged 事件后拿到該事件對(duì)應(yīng)節(jié)點(diǎn)下的所有子節(jié)點(diǎn),再與 etcd 中的數(shù)據(jù)進(jìn)行比對(duì),就可以得到新增的數(shù)據(jù),并將其同步 put 到 etcd 中。類似的,可以用遞歸的方法 watch 所有節(jié)點(diǎn)的刪除事件,并同步刪除 etcd 中的數(shù)據(jù)。

    另外 ZooKeeper 的 watch 有著先天性的缺陷,watch 是一次性的,所以每次收到事件后又必須重新 watch,兩次 watch 之間理論上是可能丟事件的,主要是在同一個(gè) key 連續(xù)多次變更的時(shí)候可能會(huì)發(fā)生。如果丟事件發(fā)生就會(huì)破壞了數(shù)據(jù)一致性,我們引入了自動(dòng) diff 和訂正的能力,即計(jì)算 ZooKeeper 和 etcd 中數(shù)據(jù)存在的差異,每次都會(huì)經(jīng)過兩輪 diff 計(jì)算,因?yàn)樵陬l繁變更數(shù)據(jù)的情況下,一輪 diff 計(jì)算往往存在一些因不是強(qiáng)一致性同步導(dǎo)致的"偽差異",當(dāng) diff 計(jì)算出了結(jié)果就會(huì)自動(dòng) fix 掉這些差異。

    如何解決與 etcd2etcd 共存?當(dāng)同一個(gè)路徑下,即有 etcd2etcd 同步寫入的數(shù)據(jù),又有 zk2etcd 寫入的數(shù)據(jù),在 zk2etcd 的自動(dòng)訂正邏輯里面,會(huì)計(jì)算出差異并訂正差異,但我們不希望因此而誤刪 etcd2etcd 寫入的數(shù)據(jù)。我們通過為 zk2etcd 引入了 Redis 來存儲(chǔ)狀態(tài)解決了這個(gè)問題,在 zk2etcd 往 etcd 中同步寫入或刪除數(shù)據(jù)時(shí),也同步在 Redis 中記錄和刪除:

    然后 zk2etcd 在自動(dòng)訂正計(jì)算差異的時(shí)候,只考慮本工具寫入過的數(shù)據(jù),避免誤刪其它同步工具寫入的數(shù)據(jù)。

    etcd2etcd 工程化實(shí)踐

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

    etcd-syncer 之 mirror-plus 版

    首先我們介紹下 etcd-syncer 的 mirror-plus 方案,顧名思義,它是 etcd 社區(qū) make-mirror 的加強(qiáng)版。為了解決 make-mirror 的各種缺陷,它實(shí)現(xiàn)了以下特性、優(yōu)點(diǎn):

    • 支持多種同步模式,全量同步、斷點(diǎn)續(xù)傳,不再擔(dān)憂專線、公網(wǎng)網(wǎng)絡(luò)質(zhì)量抖動(dòng)

    • 高可用,負(fù)責(zé)同一數(shù)據(jù)路徑復(fù)制的實(shí)例支持多副本部署, 一副本故障后,其他副本將在 5 秒后獲得鎖,在之前實(shí)例同步的進(jìn)度基礎(chǔ)上,進(jìn)行快速恢復(fù)

    • 支持一致性檢查(全量數(shù)據(jù)檢查、快照檢查)

    • 支持多實(shí)例并發(fā)復(fù)制提升性能(不同實(shí)例負(fù)責(zé)不同的路徑),建議生產(chǎn)環(huán)境配置多實(shí)例,每個(gè)實(shí)例負(fù)責(zé)不同路徑

    • 良好的運(yùn)維能力,基于 Kubernetes Deployment 一鍵部署,豐富的 Metrics、日志,完備的 e2e 測(cè)試用例覆蓋核心場(chǎng)景(http/https 場(chǎng)景,服務(wù)異常中斷、網(wǎng)絡(luò)異常等)

    那么它的缺點(diǎn)是什么呢?因?yàn)樗诵脑硪廊皇且蕾?etcd 的 mvcc+watch 特性,因此數(shù)據(jù)無法保證強(qiáng)一致性和只同步 key-value 數(shù)據(jù)。

    • 斷點(diǎn)續(xù)傳依賴 mvcc 歷史版本保留時(shí)間,最好業(yè)務(wù)能保存至少 1 個(gè)小時(shí)的歷史數(shù)據(jù)。

    • 當(dāng)寫請(qǐng)求較大的時(shí)候,備集群可能存在一定的數(shù)據(jù)落后,可能讀到臟數(shù)據(jù)。

    • 不支持同步非 key-value 數(shù)據(jù),如 auth 鑒權(quán)相關(guān)數(shù)據(jù)、lease 數(shù)據(jù)等。

    etcd-syncer 之 Raft 版

    為了解決所有類型的數(shù)據(jù)同步問題以及消除對(duì) etcd mvcc 歷史數(shù)據(jù)的依賴,騰訊云還可提供基于 Raft 日志的同步方案 etcd-syncer 之 Raft 版本。

    它的部署圖如下所示,etcd-syncer 同步服務(wù)作為一個(gè)類似 Learner 節(jié)點(diǎn)的身份,加入主 etcd 集群。

    主 etcd 集群 Leader 將 Raft 日志數(shù)據(jù)通過 MsgApp/Snapshot 等消息同步給 etcd-syncer,etcd-syncer 解析 Raft 日志,將 Raft 日志條目對(duì)應(yīng)的 Txn/Delete/Auth 等請(qǐng)求應(yīng)用到目的 etcd 集群。

    它具備如下優(yōu)點(diǎn):

    • 具備 etcd-syncer 之 mirror-plus 版本的所有特性和優(yōu)點(diǎn),同時(shí)不依賴 etcd mvcc 歷史數(shù)據(jù)。

    • 基于 etcd 底層的 Raft 日志同步數(shù)據(jù),可以同步 key-value、auth、lease 等各種類型的數(shù)據(jù)。

    • 不依賴高版本的 etcd。

    完備的容災(zāi)測(cè)試

    grpc-proxy

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

    寫入測(cè)試:

    直接訪問 etcd 服務(wù)的負(fù)載均衡入口:

    走 grpc-proxy 代理訪問 etcd 服務(wù)的情況:

    • grpc-proxy 代理在 endpoints 配置走專線或公網(wǎng)情況下,都能正常寫入

    • 寫入 key 總數(shù)一定的情況下,連接數(shù)和客戶端數(shù)越大,總耗時(shí)越低

    • 寫入 key 總數(shù)越大,單次寫入的平均耗時(shí)(Average)會(huì)有所增加,但仍為毫秒級(jí)

    • 當(dāng)一次寫入 key 總數(shù)為 10 萬時(shí),直連 etcdserver 會(huì)出現(xiàn) too many requests 的報(bào)錯(cuò),但 grpc-proxy 沒有

    • 公網(wǎng)情況比專線性能有所下降

    • 走 grpc-proxy 代理的平均耗時(shí)相比直連有所增加,但滿足需求

    讀取測(cè)試:

    直接訪問 etcd 服務(wù)的負(fù)載均衡入口:

    走 grpc-proxy 代理訪問 etcd 服務(wù)的情況:

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

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

    watch 測(cè)試:

    根據(jù)我們自己寫的一個(gè) etcdwatcher 服務(wù)對(duì) grpc-proxy 進(jìn)行 watch 測(cè)試:可以設(shè)置總 watcher 數(shù)量,更新頻率,以及測(cè)試時(shí)間,結(jié)束時(shí)打印出簡報(bào)報(bào):

    ./etcdwatch?-num=100?-span=500?-duration=10?-endpoint=http://grpc-proxy-addr:23791 test?done total?100?task 0?task?failed current?revision?is?631490 least?revision?is?631490 0?task?is?not?synced

    參數(shù)說明:

    • num 任務(wù)數(shù)量

    • span 更新間隔,單位毫秒

    • duration 總測(cè)試時(shí)間,單位秒

    • current revision:代表寫入的 revision

    • least revision:表示 num 個(gè)任務(wù)中同步最慢的 revision

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

    以上測(cè)試結(jié)果來看:failed 數(shù)為 0,watch 測(cè)試正常。

    zk2etcd

    我們使用的是 1.2.5 版本,通過 Kubernetes 的 Deployment 方式部署。

    1、模擬 zk server 失聯(lián)

    場(chǎng)景:

    • 通過將 hosts 中注入錯(cuò)誤解析地址

    現(xiàn)象:

    • 期間沒有發(fā)現(xiàn) zk 失聯(lián)的報(bào)錯(cuò)日志

    • 監(jiān)控指標(biāo)沒有發(fā)現(xiàn)異常

    • 此后執(zhí)行重啟,fixed 操作數(shù)沒有出現(xiàn)凸增情況(在 1.2.4 版本中,存在 full sync 雖然在定時(shí)執(zhí)行,但是并沒有感知到需要 fix 的 key 的 bug。導(dǎo)致重啟 zk2etcd 服務(wù)實(shí)例后,可能觀察到 fixed 操作凸增的現(xiàn)象)

    2、模擬 Redis 失聯(lián)

    模擬操作:

    • 09:56:49 將 hosts 中注入 Redis 錯(cuò)誤解析地址

    • 10:07:34 恢復(fù) Redis

    • 10:16:00 重啟同步服務(wù) Pod(操作重啟是為了觀察 full sync 是否正常)

    現(xiàn)象:

    • 期間 fixed operation 數(shù)量沒有增長,其他監(jiān)控指標(biāo)未發(fā)現(xiàn)明顯異常

    • 實(shí)例重啟后沒有出現(xiàn) fixed 數(shù)凸增的情況

    3、模擬 etcd 失聯(lián)

    模擬操作:

    • 16:15:10 etcd server 失聯(lián)

    • 16:30 恢復(fù)

    • 16:45 重啟 Pod

    現(xiàn)象:

    • 期間 fixed operation 數(shù)量沒有增長,其他監(jiān)控指標(biāo)未發(fā)現(xiàn)明顯異常

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

    總結(jié):

    • 只要 full sync 機(jī)制工作正常,各異常場(chǎng)景發(fā)生后,都能在下一個(gè) full sync 觸發(fā)后被恢復(fù)

    • 恢復(fù)的最小時(shí)間間隔取決于設(shè)置的 full sync 定時(shí)執(zhí)行間隔時(shí)間(默認(rèn)為 5m),業(yè)務(wù)對(duì)此間隔時(shí)間容忍情況自行調(diào)整參數(shù)

    • 此外,為了避免異常發(fā)生后,full sync 機(jī)制定時(shí)運(yùn)行但也沒能感知到情況發(fā)生,保險(xiǎn)起見事后可以第一時(shí)間重啟一下 zk2etcd 服務(wù)

    • 對(duì)于追加的 etcd 公網(wǎng)測(cè)試,full sync completed 和 zk、etcd 操作耗時(shí),相比內(nèi)網(wǎng)情況有一定(秒級(jí))增長

    etcd2etcd

    etcd2etcd 的同步服務(wù),我采用 Deployment 雙副本部署。

    1、多副本 backup 能力

    期望:

    • ?作節(jié)點(diǎn)故障后備?節(jié)點(diǎn)會(huì)在 5s 后接管同步任務(wù)

    測(cè)試方案:

    • etcd syncer 雙實(shí)例部署

    • 殺掉正在運(yùn)行的工作節(jié)點(diǎn)進(jìn)行觀察

    結(jié)論:

    不論是增量同步還是全量同步過程中,主備切換都能正常工作(需要注意的是,當(dāng)全量同步中發(fā)生主備切換后會(huì)變?yōu)樵隽客?#xff0c;從而可能導(dǎo)致比對(duì)較慢)

    2、斷點(diǎn)續(xù)傳能力

    期望:

    • 故障恢復(fù)后能從斷點(diǎn)繼續(xù)開始同步

    其實(shí)在第 1 部分,備節(jié)點(diǎn)切換為主后接管同步工作,fast_path 變?yōu)?1 也證明了斷點(diǎn)續(xù)傳能力,我們還額外補(bǔ)充幾個(gè)驗(yàn)證場(chǎng)景:

    (a) 短時(shí)間故障

    故障場(chǎng)景:中心 etcd 集群到熱備集群的同步過程中,因作為源的中心 etcd 集群中也存在 -etcd-syncer-meta- 的 key,觸發(fā)了同步服務(wù)報(bào)錯(cuò)(同 txn 中不能包含相同的 key),出現(xiàn)了數(shù)據(jù)差異

    現(xiàn)象:將同步服務(wù)運(yùn)行參數(shù)添加對(duì) -etcd-syncer-meta- 的過濾,然后觀察進(jìn)過一段時(shí)間追趕數(shù)據(jù)后,最終 miss 數(shù)降去達(dá)到一致

    (b) 長時(shí)間故障

    故障場(chǎng)景:

    • 停止同步服務(wù)的部署 deployment

    • 等待兩邊 etcd 集群產(chǎn)生數(shù)據(jù)差異,并發(fā)生一次 compact 后再啟動(dòng)同步服務(wù)

    現(xiàn)象:

    • 等產(chǎn)生數(shù)據(jù)差異,并發(fā)生 compact 后,重新啟動(dòng)同步服務(wù),其日志如下:因 compacted 發(fā)生,觸發(fā)全量同步

    • 同步服務(wù)監(jiān)控指標(biāo):(a) dst miss key 很快降下去;(b) src miss key 有所增加,并持續(xù)不降

    分析:

    • 同步服務(wù)停止以后,源 etcd 的 key 數(shù)量發(fā)生不少變化,監(jiān)控圖看出期間有下降,說明發(fā)生過 key 的刪除

    • 這里也暴露出一個(gè)小問題,當(dāng)出現(xiàn) src miss key 的時(shí)候,目前不能自動(dòng)修復(fù),需要人工接入清理多余的 key

    3、reset 觸發(fā)全量同步

    當(dāng)同步發(fā)生重大差異(如,發(fā)生 dst miss)進(jìn)行緊急修復(fù)的時(shí)候,通過配置 --reset-last-synced-rev 參數(shù)刪除斷點(diǎn)續(xù)傳信息,來觸發(fā)全量同步修復(fù)差異。

    現(xiàn)象:因某種異常,同步出現(xiàn) dst miss(圖中黃線實(shí)例)的情況。為了進(jìn)行修復(fù),新實(shí)例添加 --reset-last-synced-rev 參數(shù)后運(yùn)行。

    分析:

    • slow_path 為 1,說明觸發(fā)全量同步(圖中綠線實(shí)例)

    • 綠線實(shí)例的 dst miss 值沒有增長起來,說明已經(jīng)達(dá)到一致

    4、網(wǎng)絡(luò)故障

    兩 etcd 集群之間專線中斷:

    • 增量同步中

    • 全量同步中

    測(cè)試方案:當(dāng)專線中斷切換公網(wǎng)時(shí),需要修改運(yùn)行參數(shù)中的 etcd 集群訪問地址,即:必會(huì)發(fā)生重啟(重啟場(chǎng)景測(cè)試前面已經(jīng)涵蓋,這里不再重復(fù))。

    總結(jié):

    • etcd-syncer 同步服務(wù)有較好的主備機(jī)制,能夠及時(shí)有效的進(jìn)行切換

    • 短時(shí)間故障后的斷點(diǎn)續(xù)傳表現(xiàn)符合預(yù)期;對(duì)于長時(shí)間故障,同時(shí)發(fā)生 compact 的復(fù)雜情況時(shí),恢復(fù)同步后出現(xiàn) src miss 的情況,可能需要人工接入

    • 通過配置 --reset-last-synced-rev 參數(shù)對(duì) src miss 的異常修復(fù)有較好的效果

    作者介紹:

    • 孔令圳,斗魚首席架構(gòu)師,全面負(fù)責(zé)斗魚全站技術(shù)架構(gòu)體系規(guī)劃和建設(shè),10 余年中大型互聯(lián)網(wǎng)產(chǎn)品架構(gòu)經(jīng)驗(yàn),擅長高并發(fā)、高可用場(chǎng)景下的架構(gòu)與方案設(shè)計(jì)。

    • 于競,斗魚技術(shù)保障運(yùn)維專家,負(fù)責(zé)斗魚高可用基礎(chǔ)架構(gòu)建設(shè),擅長注冊(cè)中心、監(jiān)控體系等技術(shù)領(lǐng)域,同時(shí)也是斗魚多活基礎(chǔ)保障負(fù)責(zé)人。

    • 唐聰,騰訊云資深工程師,極客時(shí)間專欄《etcd 實(shí)戰(zhàn)課》作者,etcd 活躍貢獻(xiàn)者,主要負(fù)責(zé)騰訊云大規(guī)模 k8s/etcd 平臺(tái)、有狀態(tài)服務(wù)容器化、在離線混部等產(chǎn)品研發(fā)設(shè)計(jì)工作。

    • 陳鵬,騰訊云容器服務(wù)產(chǎn)品架構(gòu)師,多年專注云原生領(lǐng)域,幫助了大量用戶云原生容器化改造和生產(chǎn)落地,擁有豐富的一線實(shí)踐經(jīng)驗(yàn),也發(fā)表了海量的云原生技術(shù)文章。

    K8s線下實(shí)戰(zhàn)與CKA培訓(xùn)

    本次培訓(xùn)在北京開班,基于最新考綱,通過線下授課、考題解讀、模擬演練等方式,幫助學(xué)員快速掌握Kubernetes的理論知識(shí)和專業(yè)技能,并針對(duì)考試做特別強(qiáng)化訓(xùn)練,讓學(xué)員能從容面對(duì)CKA認(rèn)證考試,使學(xué)員既能掌握Kubernetes相關(guān)知識(shí),又能通過CKA認(rèn)證考試,學(xué)員可多次參加培訓(xùn),直到通過認(rèn)證。點(diǎn)擊下方圖片或者閱讀原文鏈接查看詳情。

    總結(jié)

    以上是生活随笔為你收集整理的斗鱼基于etcd和ZooKeeper的注册中心实践案例的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。