干货|为什么Kafka不支持读写分离
在 Kafka 中,生產(chǎn)者寫入消息、消費(fèi)者讀取消息的操作都是與 leader 副本進(jìn)行交互的,從 而實(shí)現(xiàn)的是一種主寫主讀的生產(chǎn)消費(fèi)模型。數(shù)據(jù)庫(kù)、Redis 等都具備主寫主讀的功能,與此同時(shí)還支持主寫從讀的功能,主寫從讀也就是讀寫分離,為了與主寫主讀對(duì)應(yīng),這里就以主寫從讀來稱呼。Kafka 并不支持主寫從讀,這是為什么呢?
從代碼層面上來說,雖然增加了代碼復(fù)雜度,但在 Kafka 中這種功能完全可以支持。對(duì)于 這個(gè)問題,我們可以從“收益點(diǎn)”這個(gè)角度來做具體分析。主寫從讀可以讓從節(jié)點(diǎn)去分擔(dān)主節(jié) 點(diǎn)的負(fù)載壓力,預(yù)防主節(jié)點(diǎn)負(fù)載過重而從節(jié)點(diǎn)卻空閑的情況發(fā)生。但是主寫從讀也有 2 個(gè)很明 顯的缺點(diǎn):
-
(1)數(shù)據(jù)一致性問題。數(shù)據(jù)從主節(jié)點(diǎn)轉(zhuǎn)到從節(jié)點(diǎn)必然會(huì)有一個(gè)延時(shí)的時(shí)間窗口,這個(gè)時(shí)間 窗口會(huì)導(dǎo)致主從節(jié)點(diǎn)之間的數(shù)據(jù)不一致。某一時(shí)刻,在主節(jié)點(diǎn)和從節(jié)點(diǎn)中 A 數(shù)據(jù)的值都為 X, 之后將主節(jié)點(diǎn)中 A 的值修改為 Y,那么在這個(gè)變更通知到從節(jié)點(diǎn)之前,應(yīng)用讀取從節(jié)點(diǎn)中的 A 數(shù)據(jù)的值并不為最新的 Y,由此便產(chǎn)生了數(shù)據(jù)不一致的問題。
-
(2)延時(shí)問題。類似 Redis 這種組件,數(shù)據(jù)從寫入主節(jié)點(diǎn)到同步至從節(jié)點(diǎn)中的過程需要經(jīng) 歷網(wǎng)絡(luò)→主節(jié)點(diǎn)內(nèi)存→網(wǎng)絡(luò)→從節(jié)點(diǎn)內(nèi)存這幾個(gè)階段,整個(gè)過程會(huì)耗費(fèi)一定的時(shí)間。而在 Kafka 中,主從同步會(huì)比 Redis 更加耗時(shí),它需要經(jīng)歷網(wǎng)絡(luò)→主節(jié)點(diǎn)內(nèi)存→主節(jié)點(diǎn)磁盤→網(wǎng)絡(luò)→從節(jié) 點(diǎn)內(nèi)存→從節(jié)點(diǎn)磁盤這幾個(gè)階段。對(duì)延時(shí)敏感的應(yīng)用而言,主寫從讀的功能并不太適用。
現(xiàn)實(shí)情況下,很多應(yīng)用既可以忍受一定程度上的延時(shí),也可以忍受一段時(shí)間內(nèi)的數(shù)據(jù)不一 致的情況,那么對(duì)于這種情況,Kafka 是否有必要支持主寫從讀的功能呢?
主讀從寫可以均攤一定的負(fù)載卻不能做到完全的負(fù)載均衡,比如對(duì)于數(shù)據(jù)寫壓力很大而讀 壓力很小的情況,從節(jié)點(diǎn)只能分?jǐn)偤苌俚呢?fù)載壓力,而絕大多數(shù)壓力還是在主節(jié)點(diǎn)上。而在 Kafka 中卻可以達(dá)到很大程度上的負(fù)載均衡,而且這種均衡是在主寫主讀的架構(gòu)上實(shí)現(xiàn)的。我們來看 一下 Kafka 的生產(chǎn)消費(fèi)模型,如下圖所示。
在 Kafka 集群中有 3 個(gè)分區(qū),每個(gè)分區(qū)有 3 個(gè)副本,正好均勻地分布在 3個(gè) broker 上,灰色陰影的代表 leader 副本,非灰色陰影的代表 follower 副本,虛線表示 follower 副本從 leader 副本上拉取消息。當(dāng)生產(chǎn)者寫入消息的時(shí)候都寫入 leader 副本,對(duì)于圖 8-23 中的 情形,每個(gè) broker 都有消息從生產(chǎn)者流入;當(dāng)消費(fèi)者讀取消息的時(shí)候也是從 leader 副本中讀取 的,對(duì)于圖 8-23 中的情形,每個(gè) broker 都有消息流出到消費(fèi)者。
我們很明顯地可以看出,每個(gè) broker 上的讀寫負(fù)載都是一樣的,這就說明 Kafka 可以通過 主寫主讀實(shí)現(xiàn)主寫從讀實(shí)現(xiàn)不了的負(fù)載均衡。上圖展示是一種理想的部署情況,有以下幾種 情況(包含但不僅限于)會(huì)造成一定程度上的負(fù)載不均衡:
-
(1)broker 端的分區(qū)分配不均。當(dāng)創(chuàng)建主題的時(shí)候可能會(huì)出現(xiàn)某些 broker 分配到的分區(qū)數(shù) 多而其他 broker 分配到的分區(qū)數(shù)少,那么自然而然地分配到的 leader 副本也就不均。
-
(2)生產(chǎn)者寫入消息不均。生產(chǎn)者可能只對(duì)某些 broker 中的 leader 副本進(jìn)行大量的寫入操 作,而對(duì)其他 broker 中的 leader 副本不聞不問。
-
(3)消費(fèi)者消費(fèi)消息不均。消費(fèi)者可能只對(duì)某些 broker 中的 leader 副本進(jìn)行大量的拉取操 作,而對(duì)其他 broker 中的 leader 副本不聞不問。
-
(4)leader 副本的切換不均。在實(shí)際應(yīng)用中可能會(huì)由于 broker 宕機(jī)而造成主從副本的切換, 或者分區(qū)副本的重分配等,這些動(dòng)作都有可能造成各個(gè) broker 中 leader 副本的分配不均。
對(duì)此,我們可以做一些防范措施。針對(duì)第一種情況,在主題創(chuàng)建的時(shí)候盡可能使分區(qū)分配 得均衡,好在 Kafka 中相應(yīng)的分配算法也是在極力地追求這一目標(biāo),如果是開發(fā)人員自定義的 分配,則需要注意這方面的內(nèi)容。對(duì)于第二和第三種情況,主寫從讀也無(wú)法解決。對(duì)于第四種 情況,Kafka 提供了優(yōu)先副本的選舉來達(dá)到 leader 副本的均衡,與此同時(shí),也可以配合相應(yīng)的 監(jiān)控、告警和運(yùn)維平臺(tái)來實(shí)現(xiàn)均衡的優(yōu)化。
在實(shí)際應(yīng)用中,配合監(jiān)控、告警、運(yùn)維相結(jié)合的生態(tài)平臺(tái),在絕大多數(shù)情況下 Kafka 都能 做到很大程度上的負(fù)載均衡??偟膩碚f,Kafka 只支持主寫主讀有幾個(gè)優(yōu)點(diǎn):可以簡(jiǎn)化代碼的 實(shí)現(xiàn)邏輯,減少出錯(cuò)的可能;將負(fù)載粒度細(xì)化均攤,與主寫從讀相比,不僅負(fù)載效能更好,而 且對(duì)用戶可控;沒有延時(shí)的影響;在副本穩(wěn)定的情況下,不會(huì)出現(xiàn)數(shù)據(jù)不一致的情況。為此, Kafka 又何必再去實(shí)現(xiàn)對(duì)它而言毫無(wú)收益的主寫從讀的功能呢?這一切都得益于 Kafka 優(yōu)秀的 架構(gòu)設(shè)計(jì),從某種意義上來說,主寫從讀是由于設(shè)計(jì)上的缺陷而形成的權(quán)宜之計(jì)。
總結(jié)
以上是生活随笔為你收集整理的干货|为什么Kafka不支持读写分离的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MySQL性能突发事件问题排查技巧
- 下一篇: 【分享】怎样学习一门新技术?