kafka不支援讀寫分離

2022-07-19 08:03:12 字數 2238 閱讀 6165

** :

在 kafka 中,生產者寫入訊息、消費者讀取訊息的操作都是與 leader 副本進行互動的,從 而實現的是一種主寫主讀的生產消費模型。資料庫、redis 等都具備主寫主讀的功能,與此同時還支援主寫從讀的功能,主寫從讀也就是讀寫分離,為了與主寫主讀對應,這裡就以主寫從讀來稱呼。kafka 並不支援主寫從讀,這是為什麼呢?

從**層面上來說,雖然增加了**複雜度,但在 kafka 中這種功能完全可以支援。對於 這個問題,我們可以從「收益點」這個角度來做具體分析。主寫從讀可以讓從節點去分擔主節 點的負載壓力,預防主節點負載過重而從節點卻空閒的情況發生。但是主寫從讀也有 2 個很明 顯的缺點:

(1)資料一致性問題。資料從主節點轉到從節點必然會有乙個延時的時間視窗,這個時間 視窗會導致主從節點之間的資料不一致。某一時刻,在主節點和從節點中 a 資料的值都為 x, 之後將主節點中 a 的值修改為 y,那麼在這個變更通知到從節點之前,應用讀取從節點中的 a 資料的值並不為最新的 y,由此便產生了資料不一致的問題。

(2)延時問題。類似 redis 這種元件,資料從寫入主節點到同步至從節點中的過程需要經 歷網路→主節點記憶體→網路→從節點記憶體這幾個階段,整個過程會耗費一定的時間。而在 kafka 中,主從同步會比 redis 更加耗時,它需要經歷網路→主節點記憶體→主節點磁碟→網路→從節 點記憶體→從節點磁碟這幾個階段。對延時敏感的應用而言,主寫從讀的功能並不太適用。

現實情況下,很多應用既可以忍受一定程度上的延時,也可以忍受一段時間內的資料不一 致的情況,那麼對於這種情況,kafka 是否有必要支援主寫從讀的功能呢?

主讀從寫可以均攤一定的負載卻不能做到完全的負載均衡,比如對於資料寫壓力很大而讀 壓力很小的情況,從節點只能分攤很少的負載壓力,而絕大多數壓力還是在主節點上。而在 kafka 中卻可以達到很大程度上的負載均衡,而且這種均衡是在主寫主讀的架構上實現的。我們來看 一下 kafka 的生產消費模型,如下圖所示。

在 kafka 集群中有 3 個分割槽,每個分割槽有 3 個副本,正好均勻地分布在 3個 broker 上,灰色陰影的代表 leader 副本,非灰色陰影的代表 follower 副本,虛線表示 follower 副本從 leader 副本上拉取訊息。當生產者寫入訊息的時候都寫入 leader 副本,對於圖 8-23 中的 情形,每個 broker 都有訊息從生產者流入;當消費者讀取訊息的時候也是從 leader 副本中讀取 的,對於圖 8-23 中的情形,每個 broker 都有訊息流出到消費者。

我們很明顯地可以看出,每個 broker 上的讀寫負載都是一樣的,這就說明 kafka 可以通過 主寫主讀實現主寫從讀實現不了的負載均衡。上圖展示是一種理想的部署情況,有以下幾種 情況(包含但不僅限於)會造成一定程度上的負載不均衡:

(1)broker 端的分割槽分配不均。當建立主題的時候可能會出現某些 broker 分配到的分割槽數 多而其他 broker 分配到的分割槽數少,那麼自然而然地分配到的 leader 副本也就不均。

(2)生產者寫入訊息不均。生產者可能只對某些 broker 中的 leader 副本進行大量的寫入操 作,而對其他 broker 中的 leader 副本不聞不問。

(3)消費者消費訊息不均。消費者可能只對某些 broker 中的 leader 副本進行大量的拉取操 作,而對其他 broker 中的 leader 副本不聞不問。

(4)leader 副本的切換不均。在實際應用中可能會由於 broker 宕機而造成主從副本的切換, 或者分割槽副本的重分配等,這些動作都有可能造成各個 broker 中 leader 副本的分配不均。

對此,我們可以做一些防範措施。針對第一種情況,在主題建立的時候盡可能使分割槽分配 得均衡,好在 kafka 中相應的分配演算法也是在極力地追求這一目標,如果是開發人員自定義的 分配,則需要注意這方面的內容。對於第二和第三種情況,主寫從讀也無法解決。對於第四種 情況,kafka 提供了優先副本的選舉來達到 leader 副本的均衡,與此同時,也可以配合相應的 監控、告警和運維平台來實現均衡的優化。

在實際應用中,配合監控、告警、運維相結合的生態平台,在絕大多數情況下 kafka 都能 做到很大程度上的負載均衡。總的來說,kafka 只支援主寫主讀有幾個優點:可以簡化**的 實現邏輯,減少出錯的可能;將負載粒度細化均攤,與主寫從讀相比,不僅負載效能更好,而 且對使用者可控;沒有延時的影響;在副本穩定的情況下,不會出現資料不一致的情況。為此, kafka 又何必再去實現對它而言毫無收益的主寫從讀的功能呢?這一切都得益於 kafka 優秀的 架構設計,從某種意義上來說,主寫從讀是由於設計上的缺陷而形成的權宜之計。

為什麼kafka不支援主從分離?

為什麼不像redis和mysql可以支援主從分離呢,是因為什麼原因要這麼設計呢?首先明確一下 主從分離與否沒有絕對的優劣,它僅僅是一種架構設計,各自有適用的場景。第二 如你所說,redis和mysql都支援主從讀寫分離,我個人覺得這和它們的使用場景有關。對於那種讀操作很多而寫操作相對不頻繁的負載型別...

判斷支不支援分離編譯

為什麼模板不支援分離編譯?什麼時候會出現連線錯誤?如果是普通函式在乙個.cpp檔案中申明,在另外乙個.cpp檔案中定義時,是可以編譯且鏈結的,但是當不存在定義時,會出現連線錯誤。我們具體來分析這類的問題吧 鏈結就是把main.obj與array.obj合成.exe檔案,當鏈結找不到函式入口的時候就會...

為什麼模板不支援分離編譯?

在c 中,為了乙個專案的規範化我們通常把 歸類為三類 宣告檔案 實現檔案 測試檔案。比如,我們要實現乙個順序表,那麼規範化就是建立3個檔案 seqlist.h 順序表相關宣告 seqlist.cpp 順序表相關實現 test.cpp 順序表測試檔案 那麼普通順序表這樣寫一點問題都沒有,用模板實現成這...