日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
Kafka為什么快到根本停不下來?

Kafka為什么快到根本停不下來?

作者:白發(fā)川 2020-05-25 08:05:11

開發(fā)

架構(gòu)

開發(fā)工具

Kafka 目前來說市面上可以選擇的消息隊(duì)列非常多,像 ActiveMQ,RabbitMQ,ZeroMQ 已經(jīng)被大多數(shù)人耳熟能詳。

創(chuàng)新互聯(lián)公司專注為客戶提供全方位的互聯(lián)網(wǎng)綜合服務(wù),包含不限于成都網(wǎng)站建設(shè)、網(wǎng)站建設(shè)、同仁網(wǎng)絡(luò)推廣、成都小程序開發(fā)、同仁網(wǎng)絡(luò)營銷、同仁企業(yè)策劃、同仁品牌公關(guān)、搜索引擎seo、人物專訪、企業(yè)宣傳片、企業(yè)代運(yùn)營等,從售前售中售后,我們都將竭誠為您服務(wù),您的肯定,是我們最大的嘉獎;創(chuàng)新互聯(lián)公司為所有大學(xué)生創(chuàng)業(yè)者提供同仁建站搭建服務(wù),24小時(shí)服務(wù)熱線:13518219792,官方網(wǎng)址:www.cdcxhl.com

 目前來說市面上可以選擇的消息隊(duì)列非常多,像 ActiveMQ,RabbitMQ,ZeroMQ 已經(jīng)被大多數(shù)人耳熟能詳。

特別像 ActiveMQ 早期應(yīng)用在企業(yè)中的總線通信,基本作為企業(yè)級 IT 設(shè)施解決方案中不可或缺的一部分。

目前 Kafka 已經(jīng)非常穩(wěn)定,并且逐步應(yīng)用更加廣泛,已經(jīng)算不得新生事物,但是不可否認(rèn) Kafka 一枝獨(dú)秀如同雨后春筍,非常耀眼,今天我們仔細(xì)分解一下 Kafka,了解一下它的內(nèi)幕。

以下的內(nèi)容版本基于當(dāng)前最新的 Kafka 穩(wěn)定版本 2.4.0。文章主要包含以下內(nèi)容:

  • Kafka 為什么快
  • Kafka 為什么穩(wěn)
  • Kafka 該怎么用

該文章為開篇引導(dǎo)之做,后續(xù)會有對應(yīng)的 HBase,Spark,Kylin,Pulsar 等相關(guān)組件的剖析。

Kafka 為什么快

快是一個(gè)相對概念,沒有對比就沒有傷害,因此通常我們說 Kafka 是相對于我們常見的 ActiveMQ,RabbitMQ 這類會發(fā)生 IO,并且主要依托于 IO 來做信息傳遞的消息隊(duì)列。

像 ZeroMQ 這種基本純粹依靠內(nèi)存做信息流傳遞的消息隊(duì)列,當(dāng)然會更快,但是此類消息隊(duì)列只有特殊場景下會使用,不在對比之列。

因此當(dāng)我們說 Kakfa 快的時(shí)候,通常是基于以下場景:

  • 吞吐量:當(dāng)我們需要每秒處理幾十萬上百萬 Message 的時(shí)候,相對其他 MQ,Kafka 處理的更快。
  • 高并發(fā):當(dāng)具有百萬以及千萬的 Consumer 的時(shí)候,同等配置的機(jī)器下,Kafka 所擁有的 Producer 和 Consumer 會更多。
  • 磁盤鎖:相對其他 MQ,Kafka 在進(jìn)行 IO 操作的時(shí)候,其同步鎖住 IO 的場景更少,發(fā)生等待的時(shí)間更短。

那么基于以上幾點(diǎn),我們來仔細(xì)探討一下,為什么 Kafka 就快了。

消息隊(duì)列的推拉模型

首先,如果我們單純站在 Consumer 的角度來看“Kafka 快”,是一個(gè)偽命題,因?yàn)橄啾绕渌?MQ,Kafka 從 Producer 產(chǎn)生一條 Message 到 Consumer 消費(fèi)這條 Message 來看,它的時(shí)間一定是大于等于其他 MQ 的。

背后的原因涉及到消息隊(duì)列設(shè)計(jì)的兩種模型:

  • 推模型
  • 拉模型

如下圖所示:

對于拉模型來說,Producer 產(chǎn)生 Message 后,會主動發(fā)送給 MQ Server,為了提升性能和減少開支,部分 Client 還會設(shè)計(jì)成批量發(fā)送。

但是無論是單條還是批量,Producer 都會主動推送消息到 MQ Server。

當(dāng) MQ Server 接收到消息后,對于拉模型,MQ Server 不會主動發(fā)送消息到 Consumer,同時(shí)也不會維持和記錄消息的 Offset,Consumer 會自動設(shè)置定時(shí)器到服務(wù)端去詢問是否有新的消息產(chǎn)生。

通常時(shí)間是不超過 100ms 詢問一次,一旦產(chǎn)生新的消息則會同步到本地,并且修改和記錄 Offset,服務(wù)端可以輔助存儲 Offset,但是不會主動記錄和校驗(yàn) Offset 的合理性。

同時(shí) Consumer 可以完全自主的維護(hù) offset 以便實(shí)現(xiàn)自定義的信息讀取。

對于推模型來說,服務(wù)端收到 Message 后,首先會記錄消息的信息,并且從自己的元信息數(shù)據(jù)庫中查詢對應(yīng)的消息的 Consumer 有誰。

由于服務(wù)器和 Consumer 在鏈接的時(shí)候建立了長鏈接,因此可以直接發(fā)送消息到 Consumer。

Kafka 是基于拉模型的消息隊(duì)列,因此從 Consumer 獲取消息的角度來說,延遲會小于等于輪詢的周期,所以會比推模型的消息隊(duì)列具有更高的消息獲取延遲,但是推模型同樣又其問題。

首先,由于服務(wù)器需要記錄對應(yīng)的 Consumer 的元信息,包括消息該發(fā)給誰,Offset 是多少,同時(shí)需要向 Consumer 推送消息,必然會帶來系列的問題。

假如這一刻網(wǎng)絡(luò)不好,Consumer 沒有收到,消息沒有發(fā)成功怎么辦?假設(shè)消息發(fā)出去了,我怎么知道它有沒有收到?

因此服務(wù)器和 Consumer 之間需要首先多層確認(rèn)口令,以達(dá)到至少消費(fèi)一次,僅且消費(fèi)一次等特性。

Kafka 此類的拉模型將這一塊功能都交由 Consumer 自動維護(hù),因此服務(wù)器減少了更多的不必要的開支。

因此從同等資源的角度來講,Kafka 具備鏈接的 Producer 和 Consumer 將會更多,極大的降低了消息堵塞的情況,因此看起來更快了。

OS Page Cache 和 Buffer Cache

太陽底下無新鮮事,對于一個(gè)框架來說,要想運(yùn)行的更快,通常能用的手段也就那么幾招,Kafka 在將這一招用到了極致。

其中之一就是極大化的使用了 OS 的 Cache,主要是 Page Cache 和 Buffer Cache。

對于這兩個(gè) Cache,使用 Linux 的同學(xué)通常不會陌生,例如我們在 Linux 下執(zhí)行 free 命令的時(shí)候會看到如下的輸出:

圖片來自網(wǎng)絡(luò)

會有兩列名為 buffers 和 cached,也有一行名為“-/+ buffers/cache”,這兩個(gè)信息的具體解釋如下:

pagecache:文件系統(tǒng)層級的緩存,從磁盤里讀取的內(nèi)容是存儲到這里,這樣程序讀取磁盤內(nèi)容就會非???,比如使用 Linux 的 grep 和 find 等命令查找內(nèi)容和文件時(shí),第一次會慢很多,再次執(zhí)行就快好多倍,幾乎是瞬間。

另外 page cache 的數(shù)據(jù)被修改過后,也即臟數(shù)據(jù),等到寫入磁盤時(shí)機(jī)到來時(shí),會轉(zhuǎn)移到 buffer cache 而不是直接寫入到磁盤。

我們看到的 cached 這列的數(shù)值表示的是當(dāng)前的頁緩存(page cache)的占用量,page cache 文件的頁數(shù)據(jù),頁是邏輯上的概念,因此 page cache 是與文件系統(tǒng)同級的。

buffer cache:磁盤等塊設(shè)備的緩沖,內(nèi)存的這一部分是要寫入到磁盤里的 。

buffers 列表示當(dāng)前的塊緩存(buffer cache)占用量,buffer cache 用于緩存塊設(shè)備(如磁盤)的塊數(shù)據(jù)。塊是物理上的概念,因此 buffer cache 是與塊設(shè)備驅(qū)動程序同級的。

兩者都是用來加速數(shù)據(jù) IO,將寫入的頁標(biāo)記為 dirty,然后向外部存儲 flush,讀數(shù)據(jù)時(shí)首先讀取緩存,如果未命中,再去外部存儲讀取,并且將讀取來的數(shù)據(jù)也加入緩存。

操作系統(tǒng)總是積極地將所有空閑內(nèi)存都用作 Page Cache 和 Buffer Cache,當(dāng) OS 的內(nèi)存不夠用時(shí)也會用 LRU 等算法淘汰緩存頁。

有了以上概念后,我們再看來 Kafka 是怎么利用這個(gè)特性的。

首先,對于一次數(shù)據(jù) IO 來說,通常會發(fā)生以下的流程:

  • 操作系統(tǒng)將數(shù)據(jù)從磁盤拷貝到內(nèi)核區(qū)的 Page Cache。
  • 用戶程序?qū)?nèi)核區(qū)的 Page Cache 拷貝到用戶區(qū)緩存。
  • 用戶程序?qū)⒂脩魠^(qū)的緩存拷貝到 Socket 緩存中。
  • 操作系統(tǒng)將 Socket 緩存中的數(shù)據(jù)拷貝到網(wǎng)卡的 Buffer 上,發(fā)送數(shù)據(jù)。

可以發(fā)現(xiàn)一次 IO 請求操作進(jìn)行了 2 次上下文切換和 4 次系統(tǒng)調(diào)用,而同一份數(shù)據(jù)在緩存中多次拷貝,實(shí)際上對于拷貝來說完全可以直接在內(nèi)核態(tài)中進(jìn)行。

也就是省去第二和第三步驟,變成這樣:

正因?yàn)榭梢匀绱说男薷臄?shù)據(jù)的流程,于是 Kafka 在設(shè)計(jì)之初就參考此流程,盡可能大的利用 OS 的 Page Cache 來對數(shù)據(jù)進(jìn)行拷貝,盡量減少對磁盤的操作。

如果 Kafka 生產(chǎn)消費(fèi)配合的好,那么數(shù)據(jù)完全走內(nèi)存,這對集群的吞吐量提升是很大的。

早期的操作系統(tǒng)中的 Page Cache 和 Buffer Cache 是分開的兩塊 Cache,后來發(fā)現(xiàn)同樣的數(shù)據(jù)可能會被 Cache 兩次,于是大部分情況下兩者都是合二為一的。

Kafka 雖然使用 JVM 語言編寫,在運(yùn)行的時(shí)候脫離不了 JVM 和 JVM 的 GC,但是 Kafka 并未自己去管理緩存,而是直接使用了 OS 的 Page Cache 作為緩存。

這樣做帶來了以下好處:

  • JVM 中的一切皆對象,所以無論對象的大小,總會有些額外的 JVM 的對象元數(shù)據(jù)浪費(fèi)空間。
  • JVM 自己的 GC 不受程序手動控制,所以如果使用 JVM 作為緩存,在遇到大對象或者頻繁 GC 的時(shí)候會降低整個(gè)系統(tǒng)的吞吐量。
  • 程序異常退出或者重啟,所有的緩存都將失效,在容災(zāi)架構(gòu)下會影響快速恢復(fù)。而 Page Cache 因?yàn)槭?OS 的 Cache,即便程序退出,緩存依舊存在。

所以 Kafka 優(yōu)化 IO 流程,充分利用 Page Cache,其消耗的時(shí)間更短,吞吐量更高,相比其他 MQ 就更快了。

用一張圖來簡述三者之間的關(guān)系如下:

當(dāng) Producer 和 Consumer 速率相差不大的情況下,Kafka 幾乎可以完全實(shí)現(xiàn)不落盤就完成信息的傳輸。

追加順序?qū)懭?/strong>

除了前面的重要特性之外,Kafka 還有一個(gè)設(shè)計(jì),就是對數(shù)據(jù)的持久化存儲采用的順序的追加寫入,Kafka 在將消息落到各個(gè) Topic 的 Partition 文件時(shí),只是順序追加,充分的利用了磁盤順序訪問快的特性。

圖片來自網(wǎng)絡(luò)

Kafka 的文件存儲按照 Topic 下的 Partition 來進(jìn)行存儲,每一個(gè) Partition 有各自的序列文件,各個(gè) Partition 的序列不共享,主要的劃分按照消息的 Key 進(jìn)行 Hash 決定落在哪個(gè)分區(qū)之上。

我們先來詳細(xì)解釋一下 Kafka 的各個(gè)名詞,以便充分理解其特點(diǎn):

  • Broker:Kafka 中用來處理消息的服務(wù)器,也是 Kafka 集群的一個(gè)節(jié)點(diǎn),多個(gè)節(jié)點(diǎn)形成一個(gè) Kafka 集群。
  • Topic:一個(gè)消息主題,每一個(gè)業(yè)務(wù)系統(tǒng)或者 Consumer 需要訂閱一個(gè)或者多個(gè)主題來獲取消息,Producer 需要明確發(fā)生消息對于的 Topic,等于信息傳遞的口令名稱。
  • Partition:一個(gè) Topic 會拆分成多個(gè) Partition 落地到磁盤,在 Kafka 配置的存儲目錄下按照對應(yīng)的分區(qū) ID 創(chuàng)建的文件夾進(jìn)行文件的存儲,磁盤可以見的最大的存儲單元。
  • Segment:一個(gè) Partition 會有多個(gè) Segment 文件來實(shí)際存儲內(nèi)容。
  • Offset:每一個(gè) Partition 有自己的獨(dú)立的序列編號,作用域僅在當(dāng)前的 Partition 之下,用來對對應(yīng)的文件內(nèi)容進(jìn)行讀取操作。
  • Leader:每一個(gè) Topic 需要有一個(gè) Leader 來負(fù)責(zé)該 Topic 的信息的寫入,數(shù)據(jù)一致性的維護(hù)。
  • Controller:每一個(gè) Kafka 集群會選擇出一個(gè) Broker 來充當(dāng) Controller,負(fù)責(zé)決策每一個(gè) Topic 的 Leader 是誰,監(jiān)聽集群 Broker 信息的變化,維持集群狀態(tài)的健康。

可以看到最終落地到磁盤都是 Segment 文件,每一個(gè) Partion(目錄)相當(dāng)于一個(gè)巨型文件被平均分配到多個(gè)大小相等 Segment(段)數(shù)據(jù)文件中。

但每個(gè)段 segment file 消息數(shù)量不一定相等,這種特性方便老的 segment file 快速被刪除。

因?yàn)?Kafka 處理消息的力度是到 Partition,因此只需要保持好 Partition 對應(yīng)的順序處理,Segment 可以單獨(dú)維護(hù)其狀態(tài)。

Segment 的文件由 index file 和 data file 組成,落地在磁盤的后綴為 .index 和 .log,文件按照序列編號生成,如下所示:

圖片來自網(wǎng)絡(luò)

其中 index 維持著數(shù)據(jù)的物理地址,而 data 存儲著數(shù)據(jù)的偏移地址,相互關(guān)聯(lián),這里看起來似乎和磁盤的順序?qū)懭腙P(guān)系不大,想想 HDFS 的塊存儲,每次申請固定大小的塊和這里的 Segment?是不是挺相似的?

另外因?yàn)橛?index 文的本身命名是以 Offset 作為文件名的,在進(jìn)行查找的時(shí)候可以快速根據(jù)需要查找的 Offset 定位到對應(yīng)的文件,再根據(jù)文件進(jìn)行內(nèi)容的檢索。

因此 Kafka 的查找流程為先根據(jù)要查找的 Offset 對文件名稱進(jìn)行二分查找,找到對應(yīng)的文件,再根據(jù) index 的元數(shù)據(jù)的物理地址和 log 文件的偏移位置結(jié)合順序讀區(qū)到對應(yīng) Offset 的位置的內(nèi)容即可。

segment index file 采取稀疏索引存儲方式,它減少索引文件大小,通過 mmap 可以直接內(nèi)存操作,稀疏索引為數(shù)據(jù)文件的每個(gè)對應(yīng) Message 設(shè)置一個(gè)元數(shù)據(jù)指針。

它比稠密索引節(jié)省了更多的存儲空間,但查找起來需要消耗更多的時(shí)間,特別是在隨機(jī)讀取的場景下,Kafka 非常不合適。所以因?yàn)?Kafka 特殊的存儲設(shè)計(jì),也讓 Kafka 感覺起來,更快。

Kafka 為什么穩(wěn)

前面提到 Kafka 為什么快,除了快的特性之外,Kafka 還有其他特點(diǎn),那就是:穩(wěn)。

Kafka 的穩(wěn)體現(xiàn)在幾個(gè)維度:

  • 數(shù)據(jù)安全,幾乎不會丟數(shù)據(jù)。
  • 集群安全,發(fā)生故障幾乎可以 Consumer 無感知切換。
  • 可用性強(qiáng),即便部分 Partition 不可用,剩余的 Partition 的數(shù)據(jù)依舊不影響讀取。
  • 流控限制,避免大量 Consumer 拖垮服務(wù)器的帶寬。

限流機(jī)制

對于 Kafka 的穩(wěn),通常是由其整體架構(gòu)設(shè)計(jì)決定,很多優(yōu)秀的特性結(jié)合在一起,就更加的優(yōu)秀,像 Kafka 的 Qutota 就是其中一個(gè)。

既然是限流,那就意味著需要控制 Consumer 或者 Producer 的流量帶寬,通常限制流量這件事需要在網(wǎng)卡上作處理,像常見的 N 路交換機(jī)或者高端路由器。

所以對于 Kafka 來說,想要操控 OS 的網(wǎng)卡去控制流量顯然具有非常高的難度,因此 Kafka 采用了另外一個(gè)特別的思路。

即:沒有辦法控制網(wǎng)卡通過的流量大小,就控制返回?cái)?shù)據(jù)的時(shí)間。對于 JVM 程序來說,就是一個(gè) Wait 或者 Seelp 的事情。

所以對于 Kafka 來說,有一套特殊的時(shí)延計(jì)算規(guī)則,Kafka 按照一個(gè)窗口來統(tǒng)計(jì)單位時(shí)間傳輸?shù)牧髁俊?/p>

當(dāng)流量大小超過設(shè)置的閾值的時(shí)候,觸發(fā)流量控制,將當(dāng)前請求丟入 Kafka 的 Qutota Manager,等到延遲時(shí)間到達(dá)后,再次返回?cái)?shù)據(jù)。

我們通過 Kafka 的 ClientQutotaManager 類中的方法來看:

這幾行代碼代表了 Kafka 的限流計(jì)算邏輯,大概的思路為:假設(shè)我們設(shè)定當(dāng)前流量上限不超過 T,根據(jù)窗口計(jì)算出當(dāng)前的速率為 O。

如果 O 超過了 T,那么會進(jìn)行限速,限速的公示為:

  
 
 
 
  1. X = (O - T)/ T * W 

X 為需要延遲的時(shí)間,讓我舉一個(gè)形象的例子,假設(shè)我們限定流量不超過 10MB/s,過去 5 秒(公示中的 W,窗口區(qū)間)內(nèi)通過的流量為 100MB,則延遲的時(shí)間為:(100-5*10)/10=5 秒。

這樣就能夠保障在下一個(gè)窗口運(yùn)行完成后,整個(gè)流量的大小是不會超過限制的。

通過 KafkaApis 里面對 Producer 和 Consumer 的 call back 代碼可以看到對限流的延遲返回:

對于 Kafka 的限流來講,默認(rèn)是按照 client id 或者 user 來進(jìn)行限流的,從實(shí)際使用的角度來說,意義不是很大,基于 Topic 或者 Partition 分區(qū)級別的限流,相對使用場景更大。

競選機(jī)制

Kafka 背后的元信息重度依賴 Zookeeper,再次我們不解釋 Zookeeper 本身,而是關(guān)注 Kafka 到底是如何使用 ZK 的。

首先一張圖解釋 Kafka 對 ZK 的重度依賴:

圖片來源于網(wǎng)絡(luò)

利用 ZK 除了本身信息的存儲之外,最重要的就是 Kafka 利用 ZK 實(shí)現(xiàn)選舉機(jī)制,其中以 Controller 為主要的介紹。

首先 Controller 作為 Kafka 的心臟,主要負(fù)責(zé)著包括不限于以下重要事項(xiàng):

也就是說 Controller 是 Kafka 的核心角色,對于 Controller 來說,采用公平競爭,任何一個(gè) Broker 都有可能成為 Controller,保障了集群的健壯性。

對于 Controller 來說,其選舉流程如下:

①先獲取 ZK 的 /Cotroller 節(jié)點(diǎn)的信息,獲取 Controller 的 broker id,如果該節(jié)點(diǎn)不存在(比如集群剛創(chuàng)建時(shí)),* 那么獲取的 controller id 為 -1。

②如果 controller id 不為 -1,即 Controller 已經(jīng)存在,直接結(jié)束流程。

③如果 controller id 為 -1,證明 Controller 還不存在,這時(shí)候當(dāng)前 Broker 開始在 ZK 注冊 Controller。

④如果注冊成功,那么當(dāng)前 Broker 就成為了 Controller,這時(shí)候開始調(diào)用 onBecomingLeader() 方法,正式初始化 Controller。

注意:Controller 節(jié)點(diǎn)是臨時(shí)節(jié)點(diǎn),如果當(dāng)前 Controller 與 ZK 的 Session 斷開,那么 Controller 的臨時(shí)節(jié)點(diǎn)會消失,會觸發(fā) Controller 的重新選舉。

⑤如果注冊失敗(剛好 Controller 被其他 Broker 創(chuàng)建了、拋出異常等),那么直接返回。

其代碼直接通過 KafkaController 可以看到:

一旦 Controller 選舉出來之后,則其他 Broker 會監(jiān)聽 ZK 的變化,來響應(yīng)集群中 Controller 掛掉的情況:

從而觸發(fā)新的 Controller 選舉動作。對于 Kafka 來說,整個(gè)設(shè)計(jì)非常緊湊,代碼質(zhì)量相當(dāng)高,很多設(shè)計(jì)也非常具有借鑒意義,類似的功能在 Kafka 中有非常多的特性體現(xiàn),這些特性結(jié)合一起,形成了 Kafka 整個(gè)穩(wěn)定的局面。

Kafka 該怎么用

雖然 Kafka 整體看起來非常優(yōu)秀,但是 Kafka 也不是全能的銀彈,必然有其對應(yīng)的短板,那么對于 Kafka 如何,或者如何能用的更好,則需要經(jīng)過實(shí)際的實(shí)踐才能得感悟的出。

經(jīng)過歸納和總結(jié),能夠發(fā)現(xiàn)以下不同的使用場景和特點(diǎn):

①Kafka 并不合適高頻交易系統(tǒng)

Kafka 雖然具有非常高的吞吐量和性能,但是不可否認(rèn),Kafka 在單條消息的低延遲方面依舊不如傳統(tǒng) MQ,畢竟依托推模型的 MQ 能夠在實(shí)時(shí)消息發(fā)送的場景下取得先天的優(yōu)勢。

②Kafka 并不具備完善的事務(wù)機(jī)制

0.11 之后 Kafka 新增了事務(wù)機(jī)制,可以保障 Producer 的批量提交,為了保障不會讀取到臟數(shù)據(jù),Consumer 可以通過對消息狀態(tài)的過濾過濾掉不合適的數(shù)據(jù),但是依舊保留了讀取所有數(shù)據(jù)的操作。

即便如此,Kafka 的事務(wù)機(jī)制依舊不完備,背后主要的原因是 Kafka 對 Client 并不感冒,所以不會統(tǒng)一所有的通用協(xié)議,因此在類似僅且被消費(fèi)一次等場景下,效果非常依賴于客戶端的實(shí)現(xiàn)。

③Kafka 的異地容災(zāi)方案非常復(fù)雜

對于 Kafka 來說,如果要實(shí)現(xiàn)跨機(jī)房的無感知切換,就需要支持跨集群的代理。

因?yàn)?Kafka 特殊的 append log 的設(shè)計(jì)機(jī)制,導(dǎo)致同樣的 Offset 在不同的 Broker 和不同的內(nèi)容上無法復(fù)用。

也就是文件一旦被拷貝到另外一臺服務(wù)器上,將不可讀取,相比類似基于數(shù)據(jù)庫的 MQ,很難實(shí)現(xiàn)數(shù)據(jù)的跨集群同步。

同時(shí)對于 Offset 的復(fù)現(xiàn)也非常難,曾經(jīng)幫助客戶實(shí)現(xiàn)了一套跨機(jī)房的 Kafka 集群 Proxy,投入了非常大的成本。

④Kafka Controller 架構(gòu)無法充分利用集群資源

Kafka Controller 類似于 ES 的去中心化思想,按照競選規(guī)則從集群中選擇一臺服務(wù)器作為 Controller。

意味著改服務(wù)器即承擔(dān)著 Controller 的職責(zé),同時(shí)又承擔(dān)著 Broker 的職責(zé),導(dǎo)致在海量消息的壓迫下,該服務(wù)器的資源很容易成為集群的瓶頸,導(dǎo)致集群資源無法最大化。

Controller 雖然支持 HA 但是并不支持分布式,也就意味著如果要想 Kafka 的性能最優(yōu),每一臺服務(wù)器至少都需要達(dá)到最高配置。

⑤Kafka 不具備非常智能的分區(qū)均衡能力

通常在設(shè)計(jì)落地存儲的時(shí)候,對于熱點(diǎn)或者要求性能足夠高的場景下,會是 SSD 和 HD 的結(jié)合。

同時(shí)如果集群存在磁盤容量大小不均等的情況,對于 Kafka 來說會有非常嚴(yán)重的問題,Kafka 的分區(qū)產(chǎn)生是按照 Paratition 的個(gè)數(shù)進(jìn)行統(tǒng)計(jì),將新的分區(qū)創(chuàng)建在個(gè)數(shù)最少的磁盤上,見下圖:

曾經(jīng)我?guī)椭称髽I(yè)修改了分區(qū)創(chuàng)建規(guī)則,考慮了容量的情況,也就是按照磁盤容量進(jìn)行分區(qū)的選擇。

緊接著帶來第二個(gè)問題:容量大的磁盤具備更多的分區(qū),則會導(dǎo)致大量的 IO 都壓向該盤,最后問題又落回 IO,會影響該磁盤的其他 Topic 的性能。

所以在考慮 MQ 系統(tǒng)的時(shí)候,需要合理的手動設(shè)置 Kafka 的分區(qū)規(guī)則。

結(jié)尾

Kafka 并不是唯一的解決方案,像幾年前新生勢頭挺厲害的 Pulsar,以取代 Kafka 的口號沖入市場,也許會成為下一個(gè)解決 Kafka 部分痛點(diǎn)的框架,下文再講述 Pulsar。

作者:白發(fā)川

編輯:陶家龍

出處:轉(zhuǎn)載自微信公眾號 ThoughtWorks 洞見(ID:TW-Insight)


本文名稱:Kafka為什么快到根本停不下來?
網(wǎng)頁路徑:http://www.5511xx.com/article/coigggg.html