為什么Kafka如此之快?
Kafka 是由 LinkedIn 公司推出的一個(gè)高吞吐的分布式消息系統(tǒng),通俗地說就是一個(gè)基于發(fā)布和訂閱的消息隊(duì)列,溫故而知新,反復(fù)學(xué)習(xí)優(yōu)秀的框架,定有所獲。

應(yīng)用場(chǎng)景
- 異步解構(gòu):在上下游沒有強(qiáng)依賴的業(yè)務(wù)關(guān)系或針對(duì)單次請(qǐng)求不需要立刻處理的業(yè)務(wù)。
- 系統(tǒng)緩沖:有利于解決服務(wù)系統(tǒng)的吞吐量不一致的情況,尤其對(duì)處理速度較慢的服務(wù)來說起到緩沖作用。
- 消峰作用:對(duì)于短時(shí)間偶現(xiàn)的極端流量,對(duì)后端的服務(wù)可以啟動(dòng)保護(hù)作用。
- 數(shù)據(jù)流處理:集成 spark 做實(shí)時(shí)數(shù)據(jù)流處理。
Kafka 拓?fù)鋱D(多副本機(jī)制)
Kafka 核心組件
topic 的分區(qū),一個(gè) topic 可以包含多個(gè) partition,topic 消息保存在各個(gè) partition 上。
由于一個(gè) topic 能被分到多個(gè)分區(qū)上,給 kafka 提供給了并行的處理能力,這也正是 kafka 高吞吐的原因之一。
partition 物理上由多個(gè) segment 文件組成,每個(gè) segment 大小相等,順序讀寫(這也是 kafka 比較快的原因之一,不需要隨機(jī)寫)。

消息在日志中的位置,可以理解是消息在 partition 上的偏移量,也是代表該消息的唯一序號(hào)。
同時(shí)也是主從之間的需要同步的信息。

管理 kafka 集群,負(fù)責(zé)存儲(chǔ)了集群 broker、topic、partition 等 meta 數(shù)據(jù)存儲(chǔ),同時(shí)也負(fù)責(zé) broker 故障發(fā)現(xiàn),partition leader 選舉,負(fù)載均衡等功能。

服務(wù)治理
在 Kafka 中的 Partition 有一個(gè) leader 與多個(gè) follower,producer 往某個(gè) Partition 中寫入數(shù)據(jù),是只會(huì)往 leader 中寫入數(shù)據(jù),然后數(shù)據(jù)才會(huì)被復(fù)制進(jìn)其他的 Replica 中。
而每一個(gè) follower 可以理解成一個(gè)消費(fèi)者,定期去 leader 去拉消息。而只有數(shù)據(jù)同步了后,kafka 才會(huì)給生產(chǎn)者返回一個(gè) ACK 告知消息已經(jīng)存儲(chǔ)落地了。
具體流程如下:





- 生產(chǎn)者發(fā)生消息給 leader ,這個(gè)時(shí)候 leader 完成數(shù)據(jù)存儲(chǔ),突然發(fā)生故障,沒有給 producer 返回 ack。
- 通過 ZK 選舉,其中一個(gè) follower 成為 leader ,這個(gè)時(shí)候 producer 重新請(qǐng)求新的 leader,并存儲(chǔ)數(shù)據(jù)。
Kafka 為什么這么快
①順序?qū)懘疟P
Kafka 采用了順序?qū)懘疟P,而由于順序?qū)懘疟P相對(duì)隨機(jī)寫,減少了尋地址的耗費(fèi)時(shí)間。(在 Kafka 的每一個(gè)分區(qū)里面消息是有序的)
②Page Cache

也就是說,磁盤的內(nèi)容可以讀到 cache 里面,這樣應(yīng)用程序讀磁盤就非常快。
而 buff 是作用于寫,我們開發(fā)寫磁盤都是,一般如果寫入一個(gè) buff 里面再 flush 就非常快。
而 Kafka 正是把這兩者發(fā)揮到了極致:Kafka 雖然是 scala 寫的,但是依舊在 Java 的虛擬機(jī)上運(yùn)行。
盡管如此,Kafka 它還是盡量避開了 JVM 的限制,它利用了 Page cache 來存儲(chǔ),這樣躲開了數(shù)據(jù)在 JVM 因?yàn)?GC 而發(fā)生的 STW。
另一方面也是 Page Cache 使得它實(shí)現(xiàn)了零拷貝,具體下面會(huì)講。
③零拷貝
無論是優(yōu)秀的 Netty 還是其他優(yōu)秀的 Java 框架,基本都在零拷貝減少了 CPU 的上下文切換和磁盤的 IO。
當(dāng)然 Kafka 也不例外。零拷貝的概念具體這里不作太詳細(xì)的復(fù)述,大致地給大家講一下這個(gè)概念。

這里大致可以發(fā)傳統(tǒng)的方式發(fā)生了 4 次拷貝,2 次 DMA 和 2 次 CPU,而 CPU 發(fā)生了4次的切換。
DMA 簡(jiǎn)單理解就是,在進(jìn)行 I/O 設(shè)備和內(nèi)存的數(shù)據(jù)傳輸?shù)臅r(shí)候,數(shù)據(jù)搬運(yùn)的工作全部交給 DMA 控制器,而 CPU 不再參與任何與數(shù)據(jù)搬運(yùn)相關(guān)的事情。
④零拷貝的方式

通過優(yōu)化我們可以發(fā)現(xiàn),CPU 只發(fā)生了 2 次的上下文切換和 3 次數(shù)據(jù)拷貝。
Linux 系統(tǒng)提供了系統(tǒng)事故調(diào)用函數(shù) “sendfile()”,這樣系統(tǒng)調(diào)用,可以直接把內(nèi)核緩沖區(qū)里的數(shù)據(jù)拷貝到 socket 緩沖區(qū)里,不再拷貝到用戶態(tài)。
⑤分區(qū)分段
我們上面也介紹過,Kafka 采取了分區(qū)的模式,而每一個(gè)分區(qū)又對(duì)應(yīng)到一個(gè)物理分段,查找的時(shí)候可以根據(jù)二分查找快速定位。這樣不僅提供了數(shù)據(jù)讀的查詢效率,也提供了并行操作的方式。
⑥數(shù)據(jù)壓縮
Kafka 對(duì)數(shù)據(jù)提供了:Gzip 和 Snappy 壓縮協(xié)議等壓縮協(xié)議,對(duì)消息結(jié)構(gòu)體進(jìn)行了壓縮,一方面減少了帶寬,也減少了數(shù)據(jù)傳輸?shù)南摹?/p>
①安裝 JDK








下載 Kafka:

安裝 Kafka:

配置環(huán)境變量:

啟動(dòng) Kafka:


作者:何永康,騰訊 CDG 后臺(tái)研發(fā)工程師。
編輯:陶家龍
文章轉(zhuǎn)載:51CTO技術(shù)棧
(版權(quán)歸原作者所有,侵刪)