為什么Kafka如此之快?
Kafka 是由 LinkedIn 公司推出的一個(gè)高吞吐的分布式消息系統(tǒng),通俗地說就是一個(gè)基于發(fā)布和訂閱的消息隊(duì)列,溫故而知新,反復(fù)學(xué)習(xí)優(yōu)秀的框架,定有所獲。
![為什么Kafka如此之快?](http://haohuigou.com/wp-content/themes/module/themer/assets/images/lazy.png)
應(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如此之快?](http://haohuigou.com/wp-content/themes/module/themer/assets/images/lazy.png)
Kafka 核心組件
topic 的分區(qū),一個(gè) topic 可以包含多個(gè) partition,topic 消息保存在各個(gè) partition 上。
由于一個(gè) topic 能被分到多個(gè)分區(qū)上,給 kafka 提供給了并行的處理能力,這也正是 kafka 高吞吐的原因之一。
partition 物理上由多個(gè) segment 文件組成,每個(gè) segment 大小相等,順序讀寫(這也是 kafka 比較快的原因之一,不需要隨機(jī)寫)。
![為什么Kafka如此之快?](http://haohuigou.com/wp-content/themes/module/themer/assets/images/lazy.png)
消息在日志中的位置,可以理解是消息在 partition 上的偏移量,也是代表該消息的唯一序號(hào)。
同時(shí)也是主從之間的需要同步的信息。
![為什么Kafka如此之快?](http://haohuigou.com/wp-content/themes/module/themer/assets/images/lazy.png)
管理 kafka 集群,負(fù)責(zé)存儲(chǔ)了集群 broker、topic、partition 等 meta 數(shù)據(jù)存儲(chǔ),同時(shí)也負(fù)責(zé) broker 故障發(fā)現(xiàn),partition leader 選舉,負(fù)載均衡等功能。
![為什么Kafka如此之快?](http://haohuigou.com/wp-content/themes/module/themer/assets/images/lazy.png)
服務(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ǔ)落地了。
具體流程如下:
![為什么Kafka如此之快?](http://haohuigou.com/wp-content/themes/module/themer/assets/images/lazy.png)
![為什么Kafka如此之快?](http://haohuigou.com/wp-content/themes/module/themer/assets/images/lazy.png)
![為什么Kafka如此之快?](http://haohuigou.com/wp-content/themes/module/themer/assets/images/lazy.png)
![為什么Kafka如此之快?](http://haohuigou.com/wp-content/themes/module/themer/assets/images/lazy.png)
![為什么Kafka如此之快?](http://haohuigou.com/wp-content/themes/module/themer/assets/images/lazy.png)
- 生產(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
![為什么Kafka如此之快?](http://haohuigou.com/wp-content/themes/module/themer/assets/images/lazy.png)
也就是說,磁盤的內(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è)概念。
![為什么Kafka如此之快?](http://haohuigou.com/wp-content/themes/module/themer/assets/images/lazy.png)
這里大致可以發(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)的事情。
④零拷貝的方式
![為什么Kafka如此之快?](http://haohuigou.com/wp-content/themes/module/themer/assets/images/lazy.png)
通過優(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如此之快?](http://haohuigou.com/wp-content/themes/module/themer/assets/images/lazy.png)
![為什么Kafka如此之快?](http://haohuigou.com/wp-content/themes/module/themer/assets/images/lazy.png)
![為什么Kafka如此之快?](http://haohuigou.com/wp-content/themes/module/themer/assets/images/lazy.png)
![為什么Kafka如此之快?](http://haohuigou.com/wp-content/themes/module/themer/assets/images/lazy.png)
![為什么Kafka如此之快?](http://haohuigou.com/wp-content/themes/module/themer/assets/images/lazy.png)
![為什么Kafka如此之快?](http://haohuigou.com/wp-content/themes/module/themer/assets/images/lazy.png)
![為什么Kafka如此之快?](http://haohuigou.com/wp-content/themes/module/themer/assets/images/lazy.png)
![為什么Kafka如此之快?](http://haohuigou.com/wp-content/themes/module/themer/assets/images/lazy.png)
下載 Kafka:
![為什么Kafka如此之快?](http://haohuigou.com/wp-content/themes/module/themer/assets/images/lazy.png)
安裝 Kafka:
![為什么Kafka如此之快?](http://haohuigou.com/wp-content/themes/module/themer/assets/images/lazy.png)
配置環(huán)境變量:
![為什么Kafka如此之快?](http://haohuigou.com/wp-content/themes/module/themer/assets/images/lazy.png)
啟動(dòng) Kafka:
![為什么Kafka如此之快?](http://haohuigou.com/wp-content/themes/module/themer/assets/images/lazy.png)
![為什么Kafka如此之快?](http://haohuigou.com/wp-content/themes/module/themer/assets/images/lazy.png)
作者:何永康,騰訊 CDG 后臺(tái)研發(fā)工程師。
編輯:陶家龍
文章轉(zhuǎn)載:51CTO技術(shù)棧
(版權(quán)歸原作者所有,侵刪)