使用多數(shù)據(jù)中心部署來應(yīng)對Kafka災(zāi)難恢復(fù)(一)

譯者注:
這篇文章翻譯自 https://www.confluent.io/blog/disaster-recovery-multi-datacenter-apache-kafka-deployments 中提供的白皮書。盡管它其中推薦使用的都是Confluent Platform提供的工具,但其對相關(guān)問題處理的思路和想法我們完全可以借用,還是據(jù)有一定的參考價(jià)值。

  1. 簡介
  2. 設(shè)計(jì)
    2.1 單數(shù)據(jù)中心設(shè)計(jì)
    2.3 多數(shù)據(jù)中心設(shè)計(jì)
    2.4 數(shù)據(jù)和Metadata的復(fù)制
    2.5 MirrorMaker
    2.6 中心化的Schema管理
  3. 關(guān)鍵特性
    3.1 避免消息的循環(huán)復(fù)制
    3.2 保留時(shí)間戳
    3.3 Consumer offsets的轉(zhuǎn)換
    3.3.1 故障轉(zhuǎn)移后從什么位置開始消費(fèi)
    3.3.2 轉(zhuǎn)換后的offset的準(zhǔn)確度

使用多數(shù)據(jù)中心部署來應(yīng)對災(zāi)難恢復(fù)

簡介

數(shù)據(jù)中心宕機(jī)和數(shù)據(jù)丟失能導(dǎo)致企業(yè)損失很多收入或者完全停擺。為了將由于事故導(dǎo)致的宕機(jī)和數(shù)據(jù)丟失帶來的損失最小化,企業(yè)需要制定業(yè)務(wù)可持續(xù)性計(jì)劃和災(zāi)難恢復(fù)策略。

災(zāi)難恢復(fù)計(jì)劃經(jīng)常需要在多個(gè)數(shù)據(jù)中心部署Apache Kafka, 且這些數(shù)據(jù)中心在地理位置上是分散的。如果災(zāi)難來襲,比如說致命的硬件故障,軟件故障,電源掉電,拒絕式服務(wù)攻擊和其他任何可能的事件,導(dǎo)致一個(gè)中心數(shù)據(jù)完成無法工作,Kafka應(yīng)該繼續(xù)不間斷地運(yùn)行在另一個(gè)數(shù)據(jù)中心直至服務(wù)恢復(fù)。

這份白皮書提供了一套基于Confluent Platform平臺能力和Apache Kafka主要發(fā)行版本所作出的災(zāi)難恢復(fù)方案的概要。Confluent Platform 提供了下列構(gòu)建模塊:

  • 多數(shù)據(jù)中心設(shè)計(jì)
  • 中心化的schema管理
  • 避免消息被循環(huán)復(fù)制的策略
  • 自動(dòng)轉(zhuǎn)換consumer offset

這份白皮書將使用上述構(gòu)建模塊來介紹如何配置和啟動(dòng)基于多數(shù)據(jù)中心的Kafka集群部署,并且告訴你如果一個(gè)中心數(shù)據(jù)不可用將要作什么,如果這個(gè)中心數(shù)據(jù)又恢復(fù)了將如何作復(fù)原操作。

你可能正在考慮主-從方案(數(shù)據(jù)在kafka集群間單向復(fù)制),雙主方案(數(shù)據(jù)在kafka集群間雙向復(fù)制),客戶端可以僅從本地集群也可以從本地和遠(yuǎn)端兩個(gè)集群讀取數(shù)據(jù),服務(wù)發(fā)現(xiàn)機(jī)制允許作自動(dòng)故障轉(zhuǎn)移和基于不同地理位置提供服務(wù)等。你的架構(gòu)將非常依賴于你的商業(yè)需求,但是你可以使用這份白皮書里的構(gòu)建模塊來增強(qiáng)你的災(zāi)難恢復(fù)計(jì)劃。

設(shè)計(jì)

單一數(shù)據(jù)中心

首先,讓我們一起看下在單數(shù)據(jù)中心部署的Kafka集群是如何提供消息的持久化的。下面的圖顯示了單數(shù)據(jù)中心的架構(gòu):


kafka-single.png

在單數(shù)據(jù)中心情況下,Kafka集群內(nèi)部的數(shù)據(jù)復(fù)制是實(shí)現(xiàn)消息持久化的基本方法。生產(chǎn)者寫入數(shù)據(jù)到集群,然后消費(fèi)者從partition的leader讀取數(shù)據(jù)。數(shù)據(jù)從主節(jié)點(diǎn)同步復(fù)制到從節(jié)點(diǎn)以確保消息在不同的broker上有多份拷貝。Kafka生產(chǎn)者能夠通過設(shè)置Ack這個(gè)寫入配置參數(shù)來控制寫入一致性的級別。

生產(chǎn)者設(shè)置Ack=All, 將為數(shù)據(jù)的復(fù)制提供了最強(qiáng)有效的保證,它確保在leader broker給生產(chǎn)者發(fā)送response前,集群里其他的作為復(fù)本的broker都Ack了接收到的數(shù)據(jù)。如果leader broker故障,其余的follower broker將重新選舉出主,此時(shí)這個(gè)Kafka集群將恢復(fù)并且客戶端將能夠通過新的leader繼續(xù)讀取消息。在 Kafka 0.11版本中,引入了 KIP-101 這個(gè)改進(jìn),它加強(qiáng)了集群內(nèi)部的數(shù)據(jù)復(fù)制協(xié)議,解決了之前存在的一些問題,提供了容錯(cuò)能力。

另外,客戶端可以通過任何的broker集合連接到Kafka集群,這個(gè)用于連接的broker集群叫作bootstrap brokers,因?yàn)榧簝?nèi)任一臺broker上都緩存了整個(gè)集群完整的meta data信息,所以客戶端連接到任何一臺,都可以收取到所有的meta data。如果客戶端使用某一臺具體的broker連接到集群,但這臺broker正好發(fā)生故障,那客戶端依然可以使用這組bootstrap brokers中的其他broker連接到該集群。

對于Zookeeper, 我們建議至少部署3個(gè)節(jié)點(diǎn)來維護(hù)在有節(jié)點(diǎn)發(fā)生故障時(shí)的高可用性。

最后,我們還需一個(gè)Confluent Schema Registry , 它用于保存客戶端的所有schemas的歷史版本,可以運(yùn)行多個(gè)實(shí)例。其中一個(gè)Schema Registry實(shí)例被選舉為主,負(fù)責(zé)注冊新的schemas, 其余的作為從節(jié)點(diǎn)。從節(jié)點(diǎn)實(shí)例可以處理讀請求并且將寫請求轉(zhuǎn)發(fā)到主節(jié)點(diǎn)。如果主節(jié)點(diǎn)有故障發(fā)生,則從節(jié)點(diǎn)重新選舉出新的主節(jié)點(diǎn),看起來它可以用一個(gè)Zookeeper或etcd集群來實(shí)現(xiàn)都沒有問題(譯者添加)。

上面這些合在一起,為單數(shù)據(jù)中心設(shè)計(jì)方案提供了在broker故障的情況下的強(qiáng)大保護(hù)。更多的如何配置和監(jiān)控kafka集群消息持久化和高可用的信息,可詳見Optimizing Your Apache Kafka Deployment 白皮書。

多數(shù)據(jù)中心

在多數(shù)據(jù)中心的設(shè)計(jì)中,有多個(gè)或更多的數(shù)據(jù)中心中部署有Kafka集群。雖然多數(shù)據(jù)中心Kafka集群的方式有多種,但我們在這份白皮書里只關(guān)注于兩個(gè)數(shù)據(jù)中心的災(zāi)難恢復(fù)。

考慮兩個(gè)Kafka集群,每一個(gè)都部署在地理位置獨(dú)立的不同的數(shù)據(jù)中心中。它們中的一個(gè)或兩個(gè)可以部署在Confluent Cloud上或者是部分橋接到cloud。每個(gè)數(shù)據(jù)中心都有自已的一套組件:

  • Kafka 集群, 在本地?cái)?shù)據(jù)中心中的所有broker構(gòu)成一個(gè)集群,完全不依賴遠(yuǎn)端數(shù)據(jù)中心中的broker;
  • Zookeeper集群僅服務(wù)于本地的集群;
  • 客戶端僅連接到本地集群。


    kafka-multicenter.png

在多數(shù)據(jù)中心設(shè)計(jì)中,其目的是為了跨區(qū)域同步數(shù)據(jù)。Confluent Replicator是Confluent Platform的高級功能,是這種設(shè)計(jì)的關(guān)鍵所在。Replicator從其中的一個(gè)集群中讀取數(shù)據(jù),然后將消息完整地寫入到另一個(gè)集群,并且提供了一個(gè)跨數(shù)據(jù)中心復(fù)制的中心配置。新的Topic可以自動(dòng)被感知并復(fù)制到目標(biāo)集群。如果吞吐量增加,這個(gè)Replicator將自動(dòng)擴(kuò)容以適應(yīng)這個(gè)增加的負(fù)載。

這個(gè)Replicator可以應(yīng)用在多種不同的用戶場景,這里我們關(guān)注它在兩個(gè)Kafka集群作災(zāi)難恢復(fù)時(shí)的使用。如果一個(gè)數(shù)據(jù)中心發(fā)生部分或徹底的災(zāi)難,那么應(yīng)用程序?qū)⒛軌蚬收限D(zhuǎn)移到另一個(gè)數(shù)據(jù)中心。

在下面的主-從設(shè)計(jì)中,Replicator運(yùn)行在一側(cè)(通過應(yīng)該是運(yùn)行在目標(biāo)集群一側(cè)),從主集群DC-1拷貝數(shù)據(jù)和配置到從集群DC-2。


kafka-.png

生產(chǎn)者只寫數(shù)據(jù)到主集群。依賴于整體的架構(gòu),消費(fèi)者僅從主集群來讀取數(shù)據(jù),而從集群僅僅是作為災(zāi)難恢復(fù)用。當(dāng)然,消費(fèi)者同樣也可以從兩個(gè)集群都讀取數(shù)據(jù),用于創(chuàng)建基于本地地理位置的本地緩存。在穩(wěn)定狀態(tài)下,當(dāng)兩個(gè)數(shù)據(jù)中心正常運(yùn)行時(shí),DC-1是主集群,因此所有生產(chǎn)者只寫入數(shù)據(jù)到DC-1。這是一種有效的策略,但對從集群的資源利用不夠高效。如果災(zāi)難事件發(fā)生導(dǎo)致DC-1故障,企業(yè)需要確定客戶端應(yīng)用程序?qū)⑷绾雾憫?yīng)??蛻舳藨?yīng)用程序可以故障轉(zhuǎn)移到DC-2。當(dāng)DC-1恢復(fù)后,作為故障恢復(fù)過程的一部分,DC-2中所有的最終狀態(tài)信息也要復(fù)制回之前的主集群。

在下面的主-主(多主)設(shè)計(jì)中,部署兩個(gè)Replicator, 一個(gè)將數(shù)據(jù)和配置從DC-1復(fù)制到DC-2, 另一個(gè)從DC-2復(fù)制到DC-1。


kafka-multi-replicator.png

生產(chǎn)者可以寫數(shù)據(jù)到兩個(gè)集群,DC-1的生產(chǎn)者寫數(shù)據(jù)到本地DC-1的topic中,DC-2的生產(chǎn)者寫數(shù)據(jù)到本地DC-2的topic中。DC-1的消費(fèi)者可以消費(fèi)本地DC-1的生產(chǎn)者生產(chǎn)的數(shù)據(jù),也可以消費(fèi)從DC-2中同步過來的數(shù)據(jù),反之亦然。消費(fèi)者能夠通過具體的topic名字和統(tǒng)配符來訂閱多個(gè)topic。因此,兩個(gè)數(shù)據(jù)中心的資源都得到了很多的利用。如果災(zāi)難事件導(dǎo)致DC-1故障,已經(jīng)存在的DC-2的生產(chǎn)者和消費(fèi)者將繼續(xù)它們的操作,它本質(zhì)上不受影響。當(dāng)DC-1恢復(fù)后,作為故障恢復(fù)過程的一部分,客戶端應(yīng)用程序可以直接回到之前的主集群。

數(shù)據(jù)和Metadata的復(fù)制

單Kafka集群內(nèi)部的數(shù)據(jù)復(fù)制是同步進(jìn)行的,這意味著在數(shù)據(jù)被復(fù)制到本地的其他broker后,生產(chǎn)者才會收到ack。與此同時(shí),Replicator在兩個(gè)數(shù)據(jù)中心之間異步復(fù)制數(shù)據(jù)。這意味著生產(chǎn)數(shù)據(jù)到本地集群的客戶端應(yīng)用不會等待數(shù)據(jù)復(fù)制到遠(yuǎn)端集群就可以收到ack。這個(gè)異步復(fù)制使得對消費(fèi)者消費(fèi)到有效數(shù)據(jù)的延遲最小化。異步復(fù)制的另一個(gè)好處是你不用在兩個(gè)不同集群之間創(chuàng)建相互依賴。即使兩個(gè)集群之間的連接失敗或者你需要維護(hù)遠(yuǎn)端數(shù)據(jù)中心,生產(chǎn)者發(fā)送數(shù)據(jù)到本地集群仍將是成功的。

Replicator復(fù)制的不僅僅是topic的數(shù)據(jù)還有metadata。比如topic metadata或者partition個(gè)數(shù)在原集群發(fā)生變化,Replicator同樣可以將這種變化同步到目標(biāo)集群。為了維護(hù)kafka topic的配置選項(xiàng)在多個(gè)集群一致,topic metadata必須在原始集群和目標(biāo)集群保持相同。這個(gè)是由Replicator自動(dòng)完成的。在topic準(zhǔn)備階段,它創(chuàng)建一個(gè)初始的topic配置,然后它在兩個(gè)集群間現(xiàn)步這個(gè)topic的metadata。比如,如果你在DC-1中更新了一個(gè)topic的配置屬性,Replicator將相應(yīng)的配置更新到DC-2上對應(yīng)的topic上。

MirrorMaker

你可以也聽說過Kafka提供了一個(gè)單獨(dú)的工具叫“MirrorMaker“,它可以用來在兩個(gè)Kafka集群間復(fù)制數(shù)據(jù)。但是,MirrorMaker有很多的不足之處,使它在構(gòu)建和維護(hù)多數(shù)據(jù)中心部署時(shí)面臨很大的挑戰(zhàn),包括以下幾點(diǎn):

  • 復(fù)制時(shí)為了過濾topic,需要繁瑣的配置
  • 在目標(biāo)集群創(chuàng)建的topic使用的配置可能和原始集群不匹配
  • 缺少內(nèi)建的重新配置topic名字來避免循環(huán)復(fù)制數(shù)據(jù)的能力
  • 沒有能力根據(jù)kafka流量增加來自動(dòng)擴(kuò)容
  • 不能監(jiān)控端到端的跨集群延遲

Confluent Replicator解決了上面這些問題,提供了可靠的數(shù)據(jù)復(fù)制功能。Replicator提供了更好的跨多個(gè)數(shù)據(jù)中心數(shù)據(jù)和metadata同步的功能。它整合了Kafka Connect,提供了優(yōu)秀的可用性和伸縮性。

另外,Confluent Control Center還可以管理和監(jiān)控Replicator的性能,吞吐量和延遲。為了監(jiān)控Replicator的性能,你需要配置 Confluent Monitoring interceptors

kafka-monitor.png

中心化的Schema管理

譯者注:
我們先簡單過一個(gè)Schema是什么,它其實(shí)就是描述了消息的格式,比如一個(gè)消息體有什么字段,是什么類型等,在生產(chǎn)者和消費(fèi)者之前達(dá)到一種消息格式的協(xié)議。Schema管理簡單說就是有個(gè)中心服務(wù),來管理全局的這些Schema,新的schema注冊到Schema管理服務(wù)后,獲取到一個(gè)唯一schema id,然后在生產(chǎn)的消息中帶上這個(gè)schema id, 消息者獲取到消息后,先解析出schema id,然后去schema管理服務(wù)上再獲取到對就在的schema, 用這個(gè)schema到消息的具體內(nèi)容解析出來。這個(gè)Schema管理服務(wù)通常是CP系統(tǒng),分布式部署,數(shù)據(jù)強(qiáng)一致。Confluent提供了這樣的一個(gè)服務(wù),詳情請見 Schema Registry

由于存儲在Kafka的消息需要跨所有集群生產(chǎn)和消費(fèi),因此Schemas需要全局有效。Schema Registry提供了中心化的schema管理并且它被設(shè)計(jì)成分布式的。多個(gè)Schema Registry實(shí)例跨數(shù)據(jù)中心部署,提供了彈性和高可用性,并且任何的一個(gè)實(shí)例都可以將schemas和schema id發(fā)送到Kafka客戶端。為了寫kafka topic而用到的所有schema信息,都作為log提供到database(類似于zookeeper, etcd等)。在單主架構(gòu)中,僅僅主Schema Registry實(shí)例可以寫針對kafka topic的新的注冊信息,從schema registry將新的注冊請求轉(zhuǎn)發(fā)給主。

在多數(shù)據(jù)中心的設(shè)計(jì)中,有多個(gè)數(shù)據(jù)中心的所有Schema Registry實(shí)例都應(yīng)滿足下列操作的要求:

  • 訪問相同的schema id
    由于DC-1中生產(chǎn)的消息可能需要在DC-2中被消費(fèi),因此Schema信息在多個(gè)數(shù)據(jù)中心中必須都是有效的。DC-1中的一個(gè)生產(chǎn)者注冊新的schema到Schema Registry并且插入schema id到消息中,然后DC-2或任意一個(gè)數(shù)據(jù)中心中的一個(gè)消費(fèi)者都可以使用這個(gè)Schema id從shema registry處查詢到對就應(yīng)的schema信息。

  • 協(xié)調(diào)主schema registry的選舉
    不論你的多數(shù)據(jù)中心是雙主還是方從模式,都需要選定一個(gè)kafka集群威群作為主Schema Registry。這個(gè)集群將從Schema Registry所有實(shí)例中選出主。在Confluent Platform 4.0版本之后,kafka Group協(xié)議和Zookeeper都可以協(xié)調(diào)這個(gè)選主過程。如果連接到Confluent云或者是無法訪問Zookeeper, 則可以使用kafka Group協(xié)議。

ele.png

Replicator也負(fù)現(xiàn)將保存有Schema 信息的kafka topic數(shù)據(jù)從主cluster同步到從cluster。多個(gè)數(shù)據(jù)中心中的所有從Schema Registry都直接訂閱當(dāng)前集群中的schema topic。需要時(shí)刻確保主Kafka集群和備選的Schema Registry實(shí)例在所有數(shù)據(jù)中心中都是合局可訪問的。

關(guān)鍵特性

避免消息的循環(huán)復(fù)制

在雙主的情況下,需要在跨集群雙向復(fù)制數(shù)據(jù),那避免消息的循環(huán)復(fù)制就變得很重要。沒人愿意看到topic的消息從DC-1復(fù)制到DC-2, 又從DC-2又復(fù)制回DC-1。

Conflument Replicator 5.0.1版本引入了新的特性,可以在不強(qiáng)制使用唯一topic名字的前提下,避名消息的循環(huán)復(fù)制。如果這個(gè)特性被開啟,Replicator將針對每個(gè)消息都跟蹤消息的來源信息,包括集群和原始topic。Replicator使用Kafka header這個(gè)新特性來跟蹤來源信信息。Kafka header是在kafka 0.11及以上版本中支持,相應(yīng)的broker的配置參數(shù)為log.message.format.version, 在kafka 2.0版本它是默認(rèn)被設(shè)置的。

為了開啟Replicator這個(gè)特性,需要配置provenance.header.enable=true。Replicator將放置跟蹤信息到被復(fù)制后的消息的header中。這個(gè)跟蹤信息包括下列部分:

  • 消息被首先生產(chǎn)的初始集群的ID
  • 消息被首先生產(chǎn)的初始topic名字
  • Replicator首次復(fù)制該消息時(shí)的時(shí)間戳

默認(rèn)情況下,如果目標(biāo)集群topic名字和來源信息中的topic名字相匹配,并且目標(biāo)集群ID和在這個(gè)來源信息header中的集群ID匹配時(shí),Replicator將不復(fù)制消息。考慮下面這張圖,在原始集群和目標(biāo)集群中使用完全相同名字的topic,消息m1由初始的DC-1產(chǎn)生,消息m2由初始的DC-2產(chǎn)生。


d12png.png

當(dāng)Repicator將消息從DC-1中復(fù)制到DC-2時(shí):

  • m1 將被復(fù)制到DC-2, 因?yàn)樵贒C-1的m1消息的消息header中沒有任何的追蹤信息
  • DC-1中的m2不會被再次復(fù)制回DC-2, 因?yàn)镈C-1中的m2消息的消息header中已經(jīng)標(biāo)識出來它初始來自DC-2

通常情況下,當(dāng)Replicator能夠自動(dòng)避免循環(huán)復(fù)制消息時(shí),不同數(shù)據(jù)中心的應(yīng)用程序可以使用完全相同的topic名字來訪問topic。

客戶端應(yīng)用程序的設(shè)計(jì)需要考慮跨數(shù)據(jù)中心有相同topic名字時(shí)的影響。生產(chǎn)都不會等待消息被復(fù)制到遠(yuǎn)端集群的ACK,并且當(dāng)消息在本地集群被提交后,Replicator會異步在兩個(gè)數(shù)據(jù)中心間復(fù)制消息。如果每個(gè)數(shù)據(jù)中心的生產(chǎn)者都使用相同的topic名字,這在全局來說是無序的(即使只有一個(gè)集群,也是無序的)。如果在每個(gè)數(shù)據(jù)中心都使用相同的group id來消費(fèi)相同的topic,穩(wěn)定情況下每個(gè)數(shù)據(jù)中心的消息都將被重新處理一次。

保留時(shí)間戳

在Kafka集群內(nèi)部,Kafka cosumer會跟蹤它們已消費(fèi)的消息。為了在停止消費(fèi)后的某一刻繼續(xù)消費(fèi),Kafka使用offset來標(biāo)識下一條將要被讀取的消息。這個(gè)消費(fèi)者的offset保存在一個(gè)叫__consumer_offsets的特定的kafka topic里。

在多數(shù)據(jù)中心的情況下,如果某個(gè)數(shù)據(jù)中心發(fā)生災(zāi)難,消費(fèi)者將停止從這個(gè)集群消費(fèi)數(shù)據(jù),可能需要消費(fèi)另一個(gè)集群的數(shù)據(jù)。理想情況是新的消費(fèi)者從舊的消費(fèi)者停止消費(fèi)的位置開始繼續(xù)消費(fèi)。你可以會嘗試使用Replicator來復(fù)制consumer offsets這個(gè)topic。但是相同的offset在兩個(gè)不同的數(shù)據(jù)中心集群中指向的message可能不是同一條,在這種情部下復(fù)制consumer offsets這個(gè)topic就是不能正常工作的。這個(gè)場景包括下面各種情況:

  • 在消息被同步前,由于retention polict或者是compaction策略,原集群中的一些數(shù)據(jù)可能被清理。這通常發(fā)生在消息已經(jīng)寫入原始集群很長時(shí)間后Replicator才啟動(dòng)。在這種情況下,offsets將不再匹配。
  • 在從原始集群向目標(biāo)集群復(fù)制數(shù)據(jù)時(shí),可能會發(fā)生短暫的錯(cuò)誤,這將導(dǎo)致Replicator重送數(shù)據(jù),就可能導(dǎo)致數(shù)據(jù)重復(fù)??赡苡兄貜?fù)消息的后果就是相同的offset可能不再對應(yīng)相同的消息。
  • 數(shù)據(jù)topic的同步可能會落后consumer offset這個(gè)topic的同步。因?yàn)閏onsumer offset topic和data topic的同步是各自獨(dú)立的,所以可能會遇到這個(gè)落后的問題。當(dāng)consumer在新的集群重新啟動(dòng)時(shí),可能它嘗試讀取的offset對應(yīng)的消息還沒有被復(fù)制過來。

基于上面這些可能的場景,應(yīng)用程序不能使用consumer offsets來作為兩個(gè)集群中相同消息的標(biāo)識。實(shí)際上這個(gè)__consumer_offsetstopic不會在也兩個(gè)數(shù)據(jù)中心間被復(fù)制。當(dāng)復(fù)制Data時(shí),Replicator會保留消息中的時(shí)間戳。Kafka新版本在Message中增加了時(shí)間戳支持,并且增加了新的基于時(shí)間戳的索引,保存了時(shí)間戳到offset的關(guān)聯(lián)。

下面這張圖顯示了m1這個(gè)消息被從DC-1復(fù)制到了DC-2,這個(gè)message在兩個(gè)集群中的offset是不同的,但保留了相同的時(shí)間戳t1

time.png

當(dāng)Kafka broker在message中保存了時(shí)間戳后,consumer就重置message的消費(fèi)位置到之前的某個(gè)時(shí)間點(diǎn)。

Consumer Offset的轉(zhuǎn)換

故障轉(zhuǎn)移后從什么位置恢復(fù)消費(fèi)

如果發(fā)生災(zāi)難,consumers必須重啟已連接到新的數(shù)據(jù)中心,并且它必須從災(zāi)難發(fā)生之前在原有數(shù)據(jù)中心消費(fèi)到的topic消息的位置開始繼續(xù)消息。


12.png

故障轉(zhuǎn)移到另一個(gè)數(shù)據(jù)中心的consumers如何確定從這個(gè)topic的什么位置開始消費(fèi)呢?可以從每個(gè)topic的最舊或最新位置開始消費(fèi)。

考慮下面的情景,一個(gè)生產(chǎn)者寫了10000條消息到DC-1中的一個(gè)topoic。Replicator復(fù)制這些消息到DC-2中。由于存在復(fù)制落后的可能,當(dāng)災(zāi)難恢復(fù)時(shí),它只復(fù)制了9998條數(shù)據(jù)。在災(zāi)難發(fā)生前,原有的consumers在DC-1中只讀取了8000條數(shù)據(jù),還剩下2000條沒有讀。故障轉(zhuǎn)移到DC-2后,這個(gè)consumer看到這個(gè)topic有9998條消息,還有1998條沒有讀。那么它將從什么位置開始讀取呢?


13.png

默認(rèn)情況下,當(dāng)一個(gè)consumer在DC-2創(chuàng)建后,這個(gè)配置參數(shù)auto.offset.reset將被設(shè)置為latestearliest,如果設(shè)置為latest, 將從最新位置開始消費(fèi),將丟失掉1998條數(shù)據(jù);如果設(shè)置成earliest, 會重復(fù)消費(fèi)8000條數(shù)據(jù)。

有些應(yīng)用可以接受從最新或最舊開始消費(fèi)。但是,有些應(yīng)用這兩種方式都不能接受,它們期望的行為是從第8000條消息開始消費(fèi)且僅消費(fèi)1998條數(shù)據(jù),就像下面這張圖顯示的。


14.png

為了滿足這個(gè)需求,consumer需要在新集群中將conusmer offset重置到某些有意義的點(diǎn)。就像在保留時(shí)間戳這一節(jié)討論的,consumers不能完全依靠offsets來重置消費(fèi)的offset,因?yàn)檫@個(gè)offset在兩個(gè)集群之間標(biāo)識的消息可能是不同的。Offsets在兩個(gè)數(shù)據(jù)中心間可能不同,但時(shí)間戳是一致的。在消息中保留的時(shí)間戳,在兩個(gè)集群間有相同的意義,并且可以將這個(gè)時(shí)間戳對應(yīng)的消息的offset作為開始消費(fèi)的位置。

Confluent Platform 5.0版本引入了一個(gè)新的特性,可以使用時(shí)間戳自動(dòng)轉(zhuǎn)換offsets,因此consumers能夠在故障轉(zhuǎn)移到新的數(shù)據(jù)中心后,從原始集群中記錄的消費(fèi)位置開始繼續(xù)消費(fèi)。為了使用這個(gè)能務(wù),需要使用一個(gè)叫Consumer Timestamps Interceptor的攔截器來配置java消費(fèi)程序,它會保存已消費(fèi)的消息對應(yīng)的metadata信息,包括:

  • Consumer group ID
  • Topic名字
  • Partiton
  • 已提交的offset
  • 已提交的offset對應(yīng)的時(shí)間戳

這個(gè)Consumer的時(shí)間戳信息是保存在原始kafka集群中一個(gè)叫__consumer_timestamps的topic里。Replicator不會復(fù)制這個(gè)topic,因?yàn)樗挥斜镜氐募褐杏幸饬x。

Confluent Replicator將數(shù)據(jù)從一個(gè)數(shù)據(jù)中心復(fù)制到另一個(gè)的同時(shí),還并行地完成下面的工作:

  • 從原始集群的__consumer_timestampstopic中讀取consumer offset和對應(yīng)的時(shí)間戳信息來了解當(dāng)前這個(gè)consumer group的消費(fèi)進(jìn)度
  • 轉(zhuǎn)換這個(gè)原始集群中的提交的offset到目標(biāo)集群中對應(yīng)的offset
  • 只要沒有這個(gè)group中的consumer邊接到這個(gè)目標(biāo)集群,就將轉(zhuǎn)換得到的offset寫入到目標(biāo)集__consuer_offsetstopic中

當(dāng)Replicator將轉(zhuǎn)換后的offset寫入到目標(biāo)集群的__consumer_offsetstopic時(shí),它需要知道每個(gè)offset對應(yīng)的topic名字,這個(gè)topic名字按照topic.rename.format的配置被重命名。

如果已經(jīng)有相應(yīng)的consumer group中的consumer連接到了目標(biāo)集群,Replicator將不會寫入offset到這個(gè)__consumer_offsetstopic。不論是哪些方案,當(dāng)一個(gè)消費(fèi)者故障轉(zhuǎn)移到備份集群時(shí),它將使用正常的機(jī)制查看并找到先前提交的offsets。

轉(zhuǎn)換后的Offset的準(zhǔn)確度

使用上一節(jié)中介紹的Consumer時(shí)間戳攔截器,故障轉(zhuǎn)移到新數(shù)據(jù)中心后的conusmer group就可以從故障的集群中已提交的offset的位置開始消費(fèi)了。消費(fèi)都將不會少消費(fèi)任何的消息。但是依賴于影響轉(zhuǎn)換offset的若干因素,消費(fèi)者可能會重復(fù)消費(fèi)一些消息。

影響轉(zhuǎn)換offset的若干因素有:

  • 復(fù)制的落后情況
  • offset的提交周期
  • 有相同時(shí)間戳的記錄的數(shù)量
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容