Kafka權威指南 讀書筆記之(八)跨集群數據鏡像


不同的集群之間相互依賴,管理員需要不停地在集群間制數據。大部分數據庫都支持復制 ( replication ),也就是持續地在數據庫服務器之間復制數據
為前面已經使用過“復制”這個詞來描述在同個集群的節點間移動數據,所以我們把群間的數據復制叫作鏡像 ( mirroring )。 Kafka 內置的跨集群復制工具叫作 MirrorMaker

我們將討論跨集群的數據鏡像,它們既可以鏡像所有數據,也可以鏡像部分數據;

然后介紹這些場景所使用的構模式,以及這些架構模式各自的優缺點 ;

接下來會介紹 MirrorMaker 以及如何使用它, 部署和性能調優時要注意的項;

最后對 MirrorMaker 的些替代方案進行比較

跨集群鏡像的使用場景

區域集群和中心集群
  有多個數據中心,它們分布在不同的地理區域。這些數據中心都有自己的 Kafka 集群。有些應用程序只需要與本地的 Kafka 集群通信,
而有些則需要訪問多個數據中心的數據(否則就沒必要考慮跨數據中心的復制方案了)。一個典型的場景。該公司在每個城市都有一個數據中心,它們收集所在城市的供需信息,
並調整商品價格。這些信息將會被鏡像到一個中心集群上,業務分析員就可以在上面生成整個公司的收益報告。

冗余( DR)
  一個 Kafka 集群足以支撐所有的應用程序,不過你可能會擔心集群因某些原因變得不可用,所以你希望有第個 Kafka 集群,它與第一個集群有相同的數據,如果發生了緊急
情況,可以將應用程序重定向到第二個集群上。

雲遷移
  有很多公司將它們的業務同時部署在本地數據中心和雲端。為了實現冗余,應用程序通常會運行在雲供應商的多個服務區域里,或者使用多個雲服務。本地和每個雲
服務區域都會有個 Kafka 集群。本地數據中心和雲服務區域里的應用程序使用自己的Kafka 集群,當然也會在數據中心之間傳輸數據。例如,如果雲端部署了一個新的應用
程序,它需要訪問本地的數據。本地的應用程序負責更新數據,並把它們保存在本地的數據庫里。我們可以使用 Connect 捕獲這些數據庫變更,並把它們保存到本地的 Kafka
集群里,然后再鏡像到雲端的 Kafka 集群上。這樣有助於控制跨數據中心的流量成本,同時也有助於改進流量的監管和安全性。

 

多集群架構
  以下是在進行跨數據中心通信時需要考慮的些問題。

高延遲
  Kafka 集群之間的通信延遲隨着集群間距離的增長而增加。雖然光纜的速度是恆定的,但集群間的網絡跳轉所帶來的緩沖和堵塞會增加通信延遲。

有限的帶寬
  單個數據中心的廣域網帶寬遠比我們想象的要低得多,而且可用的帶寬時刻在發生變化。另外,高延遲讓如何利用這些帶寬變得更加困難。

高成本
  不管你是在本地還是在雲端運行 Kafka,集群之間的通信需要更高的成本。部分原因是因為帶寬有限,而增加帶寬是很昂貴的。

  Kafka 服務器和客戶端是按照單個數據中心進行設計、開發、測試和調優的。假設服務器和客戶端之間具有很低的延遲和很高的帶寬,在使用默認的超時時間和緩沖區大小時
也是基於這個前提。因此,不建議跨多個數據中心安裝 Kafka 服務器

  大多數情況下,要避免向遠程的數據中心生成數據,但如果這么做了,那么就要忍受高延遲 ,並且需要通過增加重試次數( Linkedln 曾經為跨集群鏡像設置了 32 000 多次重試
次數)和增大緩沖區來解決潛在的網絡分區問題(生產者和服務器之間臨時斷開連接 )。

  果有了跨集群復制的需求,同時又禁用了從 broker 到 broker 之間的通信以及從生產者到broker 之間的通信,允許從 broker 到消費者之間的通信。
事實上,這是最安全的跨集群通信方式。在發生網絡分區時,消費者無需從 Kafka 讀取數據,數據會駐留在Kafka 里 , 到通信恢復正常。因 此,網 絡分區不會造成任何數據丟失。
因為帶寬有限,如果個數據中心的多個應用程序需要從另個數據中心的 Kafka 服務器上讀取數據,傾向於為每個數據中心安裝個 Kafka 集群,並在這些集群間復制數據,而不
是讓不同的應用程序通過廣域網訪問數據。

些架構原則 :
• 每個數據中心至少需要個集群。
每兩個數據中心之間的數據復制要做到每個事件僅復制次(除非出現錯誤需要重試)
• 量從遠程數據中讀取數據 ,而不是向遠程數據中心寫入數據。


Hub和 Spoke架構
這種架構適用於個中心 Kafka 集群對應多個本地 Kafka 集群的情況,如 示。

構有個簡單的變種,如果只有個本地集群領和個跟隨者,如圖 所示。

   使用這種架構,它訪問到局的數據集。這構的好處在於 ,數據只在本地的數據中生成,而且每個數據中的數據只會被像到中央數據中心次 。 
只處理單個數據中心數據的應用程序可以被部署在本地數據中心里, 而需要處理多個數據中心數據的應用程序需要被部署在中央數據中 里。
因為據復制是單向的,而且消費者總是從同個集群讀取數據,所以這種架構易於部署、配置和監控

  這種架構的簡單性也導致了些不足。一個數據中的應用程序無法訪問另個數據中心的數據 。 家銀行在不同的城市有多家分行。每個城市的 Kafka 集群上保存了用戶的信和賬號歷史數據。
把各個城市的數據復制到個中集群上 這樣銀行就可以利用這些數據進行業務分析。 在用戶訪問銀行網站或去他們所屬的分行辦理業務時,他們的請求被路由到本地集群上,
同時從本地集群讀取數據。假設個用戶去另個城市的分行辦理務 ,因為他的信息不在這個城市,所以這個分行需要與遠程集群發生交互(不建議這么做),
則根本沒有辦法訪問到這個用戶的信息(很尷尬) ,這種架構模式在數據訪問方面有所局限,因為區域數據中之間的數據是完全獨立的。

  采用這種架構時,每個區域數據中心的數據都要被鏡像到中央數據中心上。鏡像進程會讀取每個區域數據中心的數據,並將它重新生成到 中心集群上。 果多個數據中心
出現了重名的題,那這些題的數據可以被到中心集群的單個題上 ,也可以被到多個主題上


雙活架構
有兩個或個數據中心要共數據並且每個數據中心都可以生產和讀取數據時 可以使用雙活( Active-Active )架構,如圖 所示

 

  這種架構的主要好處在於,它可以為就近的用戶提供服務,具有性能上的優勢,而且不會因為數據的可用性問題(在 Hub 和 Spoke 架構中就有這種問題)在功能方面作出犧牲。第
個好處是冗余和彈性。因為每個數據中心具備完整的功能, 個數據中心發生失效,就可以把用戶重定向到另一個數據中心。這種重定向完全是網絡的重定向,因此
種最簡單、最透明的失效備援方案。

  這種架構的主要問題在於,如何在進行多個位置的數據異步讀取和異步更新時避免沖突。比如鏡像技術方面的問題一一如何確保同個數據不會被無止境地來回鏡像?而數據
性方面的問題則更為關鍵。下面是可能遇到的問題。

•  如果用戶向個數據中心發送數據,同時從第個數據中心讀取數據,那么在用戶讀數據之前,他發送的數據有可能還沒有被鏡像到第個數據中心。對於用戶來說, 這就
 好比把本書加入到購物車,但是在他點開購物車時,書卻不在里面。因此,在使用種架構時,開發人員經常會將用戶“粘”在同個數據中心上,以確保用戶在大多數
 況下使用的是同個數據中心的數據(除非他們從遠程進行連接或者數據中心不可用)

•  一個用戶在個數據中心訂購了書 A ,而第個數據中心幾乎在同時間收到了該用戶訂購書 B 的訂單,在經過數據鏡像之后,每個數據中心都包含了這兩個事件。兩個
    數據中心的應用程序需要知道如何處理這種情況。我們是否應該從中挑選個作為“確”的事件?如果是這樣,我們需要在兩個數據中心之間定義致的規則,用於確
    哪個事件才是正確的。又或者把兩個都看成是正確的事件,將兩本書都發給用 戶,然后設立個部門專門來處理退貨問題? Amazon 就是使用這種方式來處理沖突的,但
    對於股票交易部門來說,這種方案是行不通的。如何最小化沖突以及如何處理沖突要視具體情況而定。總之要記住,如果使用了這種架構,必然會遇到沖突問題,還要想
    辦注解決它們。

  如果能夠很好地處理在從多個位置異步讀取數據和異步更新數據時發生的沖突問題,那我們強烈建議使用這種架構。這種架構是我們所知道的最具伸縮性、彈性、靈活性和成
優勢的解決方案。所以,它值得我們投入精力去尋找些辦法,用於避免循環復制、把同用戶的請求粘在同個數據中心,以及在發生沖突時解決沖突。
雙活鏡像(特別是當數據中心的數量超過兩個)的挑戰之處在於,每兩個數據中心之間需要進行鏡像,而且是雙向 的。如果有 5 個數據中心 ,那么就需要維護至少 20 個鏡像進
程,還有可能達到 40 個,因為為了高可用,每個進程都需要冗余

  另外,我們還要避免循環鏡像,相同的事件不能無止境地來回鏡像。對於每個“邏輯題”,我們可以在每個數據中心里為它創建個單獨的主題,並確保不要從遠程數據中
制同名的主題。例如,對於邏輯主題“users”,我們在個數據中心為其創建“SF.users”主題,在另 個數據中心為其創建“ NYC.users”主題。鏡像進程將 SF 的“ SF.
users”鏡像到 NYC ,同時將 NYC 的" NYC.users”鏡像到 SF。這樣來,每個事件只被鏡像次,不過在經過鏡像之后,每個數據中心同時擁有了 SF.users 和 NYC.users 這
兩個主題,也就是說,每個數據中心都擁有相同的用戶數據。消費者如果要讀取所有的用數據,就需要以“* .users”的方式訂閱主題。我們也可以把這種方式理解為數據中心的
命名空間,比如在這個例子里, NYC 和 SF 就是命名空間

  在不久的將來, Kafka 將會增加記錄頭部信息。頭部信息里可以包含源數據中心的信息,們可以使用這些信息來避免循環鏡像,也可以用它們來單獨處理來自不同數據中心的數
據。當然,你也可以通過使用結構化的數據格式(比如 Avro )來實現這一特性,並用它在數據里添加標簽和頭部信息 不過在進行鏡像時,需要做些額外的工作,因為現成的鏡
像工具並不支持自定義的頭部信息格式。

主備架構
  有時候,使用多個集群只是為了達到災備的目的。你可能在同個數據中心安裝了兩個集群 ,它們包相同的數據,平常只使用其中的主備( Active-Standby )架構示
意圖如圖 所示。

  這種架構的好處是易於實現,而且可以被用於任何種場景。你可以安裝第個集群,然使用鏡像進程將第個集群的數據完整鏡像到第個集群上,不需要擔心數據的訪問和
沖突問題,也不需要擔心它會帶來像其他架構那樣的復雜性。

  這種架構的不足在於,它浪費了個集群。 Kafka 集群間的失效備援比我們想象的要難得多。 從目前的情況來看,要實現不丟失數據或無重復數據的 Kafka 集群失效備援是不可能
的。我們只能盡量減少這些問題的發生,但無法完全避免。

  讓個集群什么事也不做,只是等待災難的發生,這明顯就是對資源的浪費。有些組織嘗試減小災備集群的規模,讓它遠小於生產環境的集群規模。
這種做法具有定的風險,因為無法保證這種小規模的集群能夠在緊急情況下發揮應有的作用 。有些組織則傾向於讓災備集群在平常也能發揮作用,他們把些只讀的工作負載定向到災備集群上,
也就說,實際上運行的是 Hub 和 Spoke 架構的個簡化版本,因為架構里只有個 Spoke。那么問題來了 : 如何實現 Kafka 集群的失效備援?
不管選擇哪種失效備援方案, SRE(網站可靠性工程)團隊都必須隨時待命每季度進行次失效備援是最低限度的要求, 個高效的 SRE 團隊會更頻繁地進行失效備援。 


1. 數據丟失和不一致性
  Kafka 的各種鏡像解決方案都是異步的,所以備集群總是無法及時地獲取主集群的最新數據。我們要時刻注意災備集群與主集群之間
拉開了多少距離,並保證不要出現太大的差距。個繁忙的系統可以允許災備群與主集群之間有幾百個甚至幾千個消息的延遲。
在進行計划內的失效備援時,可以先停止主集群,等待鏡像進程將剩余的數據鏡像完畢,然后切換到災備集群,這樣可以避免數據丟失。在發生非計划內的失效備援時,可能
丟失數千個消息。目前 Kafka 還不支持事務, 就是說,如果多個主題的數據(比如銷售數據和產品數據)之間有相關性,那么在失效備援過程中, 些數據可以及時到達災
備集群,而有些則不能。那么在切換到災備集群之后,應用程序需要知道該如何處理沒有相關銷售信息的產品數據。

2. 失效備援之后的起始偏移量
  在切換到災備集群的過程中,最具挑戰性的事情莫過於如何讓應用程序知道該從什么地方開始繼續處理數據。下面將介紹一些常用的方法,其中有些很簡單,但有可能會造成
額外的數據丟失或數據重復:有些則比較復雜,但可以最小化丟失數據和出現重復數據的可能性。

偏移量自動重置
  Kafka 消費者有個配置選項,用於指定在沒有上個提交偏移的情況下該作何理。消費者要么從分區的起始位置開始讀取數據,要么從分區的末尾開始讀取數據

   如果重復處理數據或者丟失一些數據不會造成太大問題 ,那么重置偏移量是最為簡單的方案。不過直接從主題的末尾開始讀取數據這種方式或許更為常

復制偏移量主題
  如果使用新的 Kafka 消費者( 0.9 或以上版本),消費者會把偏移量提交到一個 __consumer_offsets 的主題上。如果對這個主題進行了鏡像,那么當消費者開始讀
  取災備集群的數據時,它們就可以從原先的偏移量位置開始處理數據。這個看起來很簡單,不過仍然有很多需要注意的事項。

    首先, 我們並不能保證主集群里的偏移量與災備集群里的偏移量是完全匹配。假設主集群里的數據只保留 3 天,而你在一個星期之后才開始鏡像,那么在這種情況下,主集群里
  第個可用的偏移量可能是 57 000 000 (前 4 天的舊數據已經被除了),而災備集群里的個偏移量是 0,那么當消費者嘗試從 57 000 003 處(因為這是它要讀的下個數據)
  開始讀取數據時,就會失敗。
    其次,就算在主題創建之后立即開始鏡像,讓主集群和災備集群的主題偏移量都從 0 始,生產者在后續進行重試時仍然會造成偏移量的偏離。簡而言之,目前的 Kafka 鏡像解
  決方案無法為主集群和災備集群保留偏移量。
    最后,就算偏移量被完美地保留下來,因為主集群和災備集群之間的延遲Kafka 缺乏對事務的支持,消費者提交的偏移量有可能會在記錄之前或者記錄之后到達。在發生失效
  備援之后,消費者可能會發現偏移量與記錄不匹配,或者災備集群里最新偏移量主集群里的最新偏移量小。如圖 所示。

    在這些情況下,我們需要接受一定程度的重復數據。如果災備集群最新的偏移量主集群的最新偏移量小,或者因為生產者進行重試導致災備集群的記錄偏移量主集群的記錄偏
  移量大,都會造成數據重復。你還需要知道該怎么處理最新偏移量與記錄不匹配的問題,

  此時要從主題的起始位置開始讀取還是從末尾開始讀取?
    復制偏移量主題的方式可以用於減少數據重復或數據丟失,而且實現起來很簡單,只要及時地從 0 開始鏡像數據,並持續地鏡像偏移量題就可以了 。不過一定要注意上述的
  幾個問題。

基於時間的失效備援
    如果使用的是新版本( 0.10.0 及以上版本)的 Kafka 消費者, 個消息里都包含了時間戳,這個時間戳指明了消息發送給 Kafka 的時間。 在更新版本的 Kafka (0.10.1.0
  及以上版本)里, broker 提供了個索引和個 API ,用於根據時間戳找偏移量。於是,假設你正在進行失效備援 , 並且知道失效事件發生在凌4:05 ,那么就可以讓消費
  者從 4:03 的位置開始處理數據。在兩分鍾的時間差里會存在些重復數據,不過這種方式仍然比其他方案要好得多,而且也很容易向其他人解釋一一 “我們將從凌晨 4:03
  的位置開始處理數據”這樣的解釋要比“我們從個不知道是不是最新的位置開始處理數據”要好得多 所以,這是種更好的折中 。問題是,如何讓消費者凌晨 4:03 的
  位置開始處理數據呢?
    可以讓應用程序來完成這件事情。 我們為用戶提供個配置參數 ,用於指定從什么時間點開始處理數據。如果用戶指定了時間,應用程序可以通過新的 API 獲取指定時間的
  偏移量,然后從這個位置開始處理數據如果應用程序在開始就是這么設計的,那么使用這種方案就再好不過了。但果應用程序在開始不是這么設計的呢?開發個這樣的小工具也並不難一一接收個時間
  戳,使用新的 API 獲取相應的偏移,然后提交偏移量。 我們希望在未來的 Kafka 版里添加這樣的工具,不過你也可以自己寫一。在運行這個工具,應該先關閉消費者
  群組 在工具完成任務之后再啟動它們。該方案適用於那些使用了新版 Kafka、對失效備援有明確要求並且喜歡自己開發工具的人

偏移量外部映射
    鏡像偏移量主題的個最大問題在於主集群和災備集群的偏移量會發生偏差。因此, 些組織選擇使用外部數據存儲(比如 Apache Cassandra ) 來保存集群之間
  的偏移量映射。他們自己開發鏡像工具,在個數據被鏡像到災備集群之后,主集群和災備集群的偏移量被保存到外部數據存儲上。或者只有當兩邊的偏移量差值發生變
  化時,才保存這兩個偏移量。 比如, 主集群的偏移495 被映射到災備集群的偏移量500 ,在外部存儲上記錄為( 495,500 )。如果之后因為消息重復導差值發生變 化,
  移量 596 被映射為 600,那么就保留新的映射( 569,600 ) 他們沒有必要保留 495 596 之間的所有偏移映射,他們假設差值都是樣的,所以主集群的偏移量 550 會映
  射到災備集群的偏移555。那么在發生失效備援時,他們將主集群的偏移量與災備集群的偏移量映射起來,而不是在時間戳(通常會有點不准確)和偏移量之間做映射。他
  們通過上述技術手段之來強制消費者使用映射中的偏移量。 些在數據記錄之前達到的偏移量或者沒有及時被鏡像到災備集群的偏移量來說,仍然會有問題一一不過
  這至少已經滿足了部分場景的求。
  
3 . 在失效備援之后
  假設失效備援進行得很順利,災備集群也運行得很正常,現在需要對主集群做些改動,比如把它變成災備集群。
如果能夠通過簡單地改變鏡像進程的方向,讓它將數據從新的主集群鏡像到舊的主集群上情就完美了 !不過,這里還存在兩個問題。
•   怎么知道該從哪里開始鏡像?我們同樣需要解決與鏡像程序里的消費者相關的問題。而且不要忘了,所有的解決方案都有可能出現重復數據或者丟失數據,或者兩者兼有。
•   之前討論過,舊的主集群可能會有些數據沒有被鏡像到災備集群上,如果在這個時把新的數據鏡像回來,那么歷史遺留數據還會繼續存在,兩個集群的數據就會出現
基於上述的考慮,最簡單的解決方案是清理舊的主集群,刪掉所有的數據和偏移量,然后從新主集群上把數據鏡像回來,這樣可以保證兩個集群的數據是致的

4 . 關於集群發現
  在設計災備集群時,需要考慮個很重要的問題,就是在發生失效備援之后,應用程序需要知道如何與災備集群發起通信。不建議把主集群的主機地址硬編碼在生產者和消費
者的配置屬性文件里大多數組織為此創建了 DNS 別名,將其指向主集群,一旦發生緊急情況 ,可以將其指向災備集群。有些組織則使用服務發現工具,比如 Zookkeeper、 Etcd
或 Consul。這些服務發現工具(DNS 或其他)沒有必要將所有 broker 的信息都包含在內,Kafka 客戶端只需要連接到其中的一個 broker ,就可以獲取到整個集群的元數據,並發現
集群里的其他 broker。 般提供 3 個 broker 的信息就可以了。除了服務發現之外,在大多數情況下,需要重啟消費者應用程序,這樣它們才能找到新的可用偏移量,然后繼續讀取
數據。


延展集群
  在主備架構里, Kafka 集群發生失效時,可以將應用程序重定向到另個集群上,以保證業務的正常運行。而在整個數據中心發生故障時,可以使用延展集群( stretch cluster)
來避免 Kafka 集群失效。延展集群就是跨多個數據中心安裝的單個 Kafka 集群。

  延展集群與其他類型的集群有本質上的區別。首先,延展集群並非多個集群,而是單個集群,因此不需要對延展集群進行鏡像。延展集群使用 Kafka 內置的復制機制在集群的broker 之間同步數據。
我們可以通過配置打開延展集群的同步復制功能,生產者會在消息成功寫入到其他數據中心之后收到確認。同步復制功能要求使用機架信息,確保每個分區
在其他數據中心都存在副本,還需要配置 min. isr和 acks=all ,確保每次寫入消息時都可以收到至少兩個數據中心的確認。

  同步復制是這種架構的最大優勢。有些類型的業務要求災備站點與主站點保持 100% 的同 步,這是種合規性需求,可以應用在公司的任何個數據存儲上,包括 Kafka 本身。這
種架構的另個好處是,數據中心及所有 broker 都發揮了作用,不存在像備架構那樣的資源浪費。

  這種架構的不足之處在於,它所能應對的災難類型很有限,只能對數據中心的故法應對應用程序或者 Kafka 故障。運維的復雜性是它的另個不足之處,它所要的物
基礎設施並不是所有公司都能夠承擔得起的。

  如果能夠在至少 3 個具有高帶寬和低延遲的數據中心上安裝 Kafka (包括 Zookeeper),那么就可以使用這種架構。如果你的公司有 3 棟大樓處於同個街區,或者你的應商在
個地區有 3 個可用的區域,那么就可以考慮使用這種方案。

  為什么是 3 個數據中心? 要是因為 Zookeeper。 Zookeeper 要求集群里的節個數是奇數,而且只有當大多數節點可用時,整個集群才可用。如果只有兩個數據中心和奇數個節
點,那么其中的個數據中心將包含大多數節點,也就是說,如果這個數據中心不可用,那么 Zookeeper 和 Kafka 也不可用。如果有 3 個數據中心,那么在分配節點時,可以做
每個數據中心都不會包含大多數點。如果其中的個數據中心不可用, 他兩個數據中心包含了大多數節點,此時 Zookeeper 和 Kafka 仍然可用
  從理論上說,在兩個數據中心運行 Zookeeper 和 Kafka 是可能的,只要將 Zookeeper 的組配置成允許手動進行失效備援 不過在實際應用 中,這種做法並不常見

Kafka的 MirrorMaker
  Kafka 提供了 個簡單的工具,用於在兩個數據中心之間鏡像數據 這個 工具 MirrorMaker,它包含了 組消費者(因為歷史原因,它們在 MirrorMaker 文檔里被稱
),這些消費者屬於同個群組,並從主題上讀取數據。每個 MirrorMaker 進程都有單獨的生產者。

鏡像過程很簡單: MirrorMaker 為每個消費者分配個線程,消費源集群的主題和分區上讀取數據,然后通過公共生產者將數據發送到目標集群上。
默認情況下,消費者每 60 秒通知生產者發送所有的數據到 Kafka,並待 Kafka 的確認 后消費者再通知源集群提交這些事件相應的偏移量。
這樣可以保證不失數據(源集群提交偏之前, Kafka 對消息進行了確認),而且如果 MirrorMaker  進程發生崩潰,最多只會出現 60 秒的重復數據。見圖 

如何配置
  MirrorMaker 是高度可配置它使用了個生產者和多個消費者,生產者和消費者的相關配置參數都可以用於配置 MirrorMaker。另外, MirrorMaker 本身也有一些配
置參數,這些配置參數之間有時候會有比較復雜的依賴關系。下面將舉一些例子,並着重說明些重要的配置參數。

接下來分別說明 MirrorMaker 的基本命令行參數。
consuMer.config
  該參數用於指定消費者的配置文件。所有的消費者將共用這個配置,也就是說,只能配置個源集群和個 group.id。所有的消費者屬於同 個消費者群組,這正好與我們
  的要求不謀而合。配置文件里有兩個必選的參數 : bootstrap.servers (源集群的服務器地址)和 group.id。除了這兩個參數外,還可以為消費者指定其他任意的配置參數。
  autocommit.enable 參數 般不需要修改,用默認值 false 就行。 MirrorMaker 會在消息安全到達目標集群之后提交偏移量,所以不能使用自動提交。如果修改了這個參數,
  可能會導致數據丟失。 auto.offset.reset 參數一般需要進行修改,默認值是 latest,也就是說, MirrorMaker 只對那些在 MirrorMaker 啟動之后到達源集群的數據進行鏡像。
  如果想要鏡像之前的數據,需要把該參數設為 earliest

producer.config
  該參數用於指定生產者的配置文件。配置文件里唯一必選的參數是 bootstrap.servers(目標集群的服務器地址)。

new.consumer
  MirrorMaker 只能使用 0.8 版本或者 0.9 版本的消費者。建議使用 0.9 版本的消費者,因為它更加穩定。

num.streams
   個流就是個消費者。所有的消費者共用個生產者, MirrorMaker將會使用這些流來填充同個生產者。如果需要額外的吞吐量,就需要創建另MirrorMaker 進程。
whitelist
  這是個正則表達式,代表了需要進行鏡像的主題名字。所有與表達式匹配的題都將被鏡像。

 

在生產環境部署 MirrorMaker

  在生產環境, MirrorMaker 作為后台服務運行的,而且是以 nohup 的方式運行,並將控制台的輸出重定向到個日
文件里。這個工具有個- deamon 命令行參數。理論上,只要使用這個參數就能后台運行,不需要再做其他任何事情,但在實際當中,最近發布的些版本不能如我們所
望的那樣。

  大部分使用 MirrorMaker  的公司都有自己的啟動腳本,他們使用部署系 Ansible 、 Puppet 、 Chef 和 Salt )實現自動化的部署和配置管理。

  在 Docker 容器里運行 MirrorMaker 變得越來越流行 MirrorMaker 是完全 狀態的,也不需要磁盤存儲(所有的數據和狀態都保存在 Kafka 上) 將 MirrorMaker
裝在 Docker 里,就可以實現在單台主機上運行多個 MirrorMaker 因為 單個MirrorMaker 實例的吞吐量受限於單個生產者,所以為了提升要運行多個
MirrorMaker 實例,而 Docker 簡化了這 過程。 Docker 也讓 MirrorMaker 的伸 縮變得更加容易,在流量高峰時,可以通過增加更多的容器來提升
則減少容器。如果在雲端運行 MirrorMaker ,根據吞吐實際情況, 以通過增加額外的服務器來運行 Docker 容器。

  如果有可能,盡量讓 MirrorMaker 運行在目標數據中心里 也就是說,如要將 NYC 數據發送到 SF, MirrorMaker 應該運行在 SF 的數據中心里 因為長距離的外部網
據中心的內部網絡更加不可靠,如果發生了網絡分區,數據中心之間的斷開了連接, 那么個無法連接到集群的消費者要比個無法連接到集群的生產者要安多。 如果消費
者無法連接到集群,最多也就是無法讀取數據,數據仍然在 Kafka 集群里保留很長的一段時間,不會有丟失的風險。相反,在發生網絡分區時,如MirrorMaker 已經讀取
了數據,但無法將數據生成到目標集群上,就會造成數據丟失。 所以說, 遠程讀取比程生成更加安全。

  那么,什么情況下需要在本地讀取消息並將其生成到遠程數據中心呢?如果需要密傳輸數據,但又不想在數據中心進行加密,就可以使用這種方式。 消費者通過 SSL 連接
到 Kafka 對性能有定的影響,這個比生產者要嚴重得多,而且這種性能問題也會影響broker。如果跨數據中心流量需要加密,那么最好把 MirrorMaker 放在源數據中心, 讓它
讀取本地的非加密數據,然后通過 SSL 連接將數據生成到遠程的數據中心 這個時候, 使用 SSL 連接的是生產者,所以性能問題就不那么明顯了。在使用這種方式時, 要確
MirrorMaker 在收到目標 broker 副本的有效確認之前不要提交偏移,並在重試次數超出
限制或者生產者緩沖區植出的情況下立即停止鏡像。

  如 希望減小源集群和目標集群之間的延遲,可以在不同的機器上運行至少兩個MirrorMaker 實例,而且它們要使用相同的消費者群組。也就是說,如果關掉其中台服務
另一個 MirrorMaker 實例能夠繼續鏡像數據。


在將 MirrorMaker 部署到生產環境時,最好要對以下幾項內容進行監控。

遲監控
  我們絕對有必要知道目標集群是否落后於源集群。延遲體現在源集群最新偏移量和目標群最新偏移的差異上。見圖  。

源集群的最后個偏移量是 7 ,而目標集群的最后一個偏移量是 5 ,所以它間有兩個消息的延遲。

兩種方式可用於跟蹤延遲,不過它們都不是完美的解決方案。
•  檢查 MirrorMaker 提交到擁集群的最新偏移量。可以使用 kafka-consumer-groups 工具檢查 MirrorMaker 讀取的每個分區,查看分區的最新偏移量,也就是 MirrorMaker 提交
 的最新偏移量。不過這個偏移量並不會 100% 的准確,因為 MirrorMaker 不會每時每刻都提交偏移,默認情況下,它會每分鍾提交

•  檢查 MirrorMaker 讀取的最新偏移量(即使還未提交 。消費者通過 JMX 發布關鍵性度指標,其中有個指標是指消費者的最大延遲(基於它所讀取的所有分區計算得出的)。
 這個延遲也不是 100% 的准確,因為它只反映了消費者讀取的數據,並沒有考慮生產者否成功地將數據發送到目標集群上。

度量指標監控
  MirrorMaker 內嵌了生產者和消費者,它們都有很多可用的度量指標,所以建議對它們進行監控。 Kafka 文檔列出了所有可用的度量指標。下面列出了幾個已經被證明能夠
  升 MirrorMaker 性能的度量指標。
  消費者

生產者

同時適用於兩者

canary
  如果對所有東西都進行了監控,那么 canaη 就不是必需的,不過對於多層監控來說,can町可能還是有必要的。我們可以每分鍾往擁集群的某個特定主題上發送事件,
  然后嘗試從目標集群讀取這個事件。如果這個事件在給定的時間之后才到達,那么就出告警,說明 MirrorMaker 出現了延遲或者已經不正常了。

MirrorMaker調優

  MirrorMaker 集群的大小取決於對吞吐量的需求和對延遲的接受程度。如果不允許有任何延遲,那么 MirrorMaker 集群的容量需要能夠支撐吞吐量的上限。如果可以容忍些延遲
那么可以在 95%~99% 的時間里只使用 75%-80% 的容量。在吞吐量高峰時可以允許一些延遲,高峰期結束時,因為 MirrorMaker 些空余容量,可以很容易地消除延遲。
  
你可能想要分離比較敏感的主題,它們要求很低的延遲,所以其鏡像必須盡可能地接近源集群和 MirrorMaker 集群。這樣可以避免主題過於臃腫,或者避免出現失控的生產

者拖慢數據管道。


如果 MirrorMaker 是跨數據中心運行的,可以在 Linux 上對網絡進行優化。

 

  要注意,在 Linux 上進行網絡調優包含了太多復雜的內容。為了了解更多參數和細節,建議閱讀相關的網絡調優指南。 例如,由 Sandra K.Johnson 等人合著的 Peiformance tuning
for Linux servers 。

  除此以外,你可能還想對 MirrorMaker 里的生產者和消費者進行調優。首先,你想知道生產者或消費者是不是瓶頸所在一一生產者是否在等待消費者提更多的數,或者其他的
什么?通過查看生產者和消費者的度量指標就可以知道問題所在了 ,如果其中的個進程而另外個很忙,那么就知道該對哪個進行調優了。另外種辦怯是查看線程轉儲
(thread dump ),可以使用 jstack 獲得線程轉儲。如果 MirrorMaker 的大部分時間用在輪那么說明消費者出現了瓶頸,如果大部分時間用在發送上,那么就是生產者出現了瓶頸。
如果需要對生產者進行調優,可以使用下列參數。

max.in.flight.requests.per.connection
  默認情況下, MirrorMaker 只允許存在個處理中的請求。也就是說,生產者在發送下一個消息之前 當前發送的消息必須得到目標集群的確認。這樣會對吞吐量造成限
  制,特別是當 broker 在對消息進行確認之前出現了嚴重的延遲。 MirrorMaker 之所以要限定請求的數量,是因為有些消息在得到成功確認之前需要進行重試,而這是唯一能
  夠保證消息次序的方法。如果不在乎消息的次序,那么可以通過增加 max.in.flight.requests.per.connection 的值來提升吞吐量。

linger.msbatch.size
  如果在進行監控時發現生產者總是發送未填滿的批次(比如,度量指標 batch-size-avgbatch-size - max 的值總是比 batch.size 低,那么就可以通過增一些延遲來提升吞
  吐量。通過增加 latency.ms 可以讓生產者在發送批次之前等待幾毫秒,讓批次填充更多的數據。如果發送的數據都是搞批次的,同時還有空余的內存,那么可以配置更大的
  batch.size ,以便發送更大的批次

下面的配置用於提升消費者的吞吐量。
•  range 。 MirrorMaker 默認使用 range 策略(用於確定將哪些分區分配給哪個消費者的算法)進行分區分配。 range 策略有一定的優勢
  不過range 策略會導致不公平現象。對於 MirrorMaker 來說,最好可以略改為round robin ,特別是在鏡像大量的主題和分區的時候將策略改為round robin 算法,
  需要在消費者配置屬性文件里加上 partition.assignment.strategy=org.apache.kafka.clients.consumer.RoundRobinAssignor
•  fetch.max.bytes 。如果度盤指標顯示 fetch-size - avg 和 fetch - size-max 的數值與 fetch.max.bytes 很接近,說明消費者讀取的數據已經接近上限。如果有更多的可用內存,可
  以配置更大的 fetch.max.bytes ,消費者就可以在每個請求里讀取更多的數據
•  fetch.min.bytes 和 fetch.max.wait。如果度量指標 fetch - rate 的值很高,說明消費者發送的請求太多了,而且獲取不到足夠的數據。這個時候可以配置更大的 fetch.min.bytes 和 fetch.max.wait
 這樣消費者的每個請求就可以獲取到更多的數據, broker 等到有足夠多的可用數據時才將響應返回。


其他跨集群鏡像方案(略)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM