Kafka使用領(lǐng)域非常廣泛,在大數(shù)據(jù)時(shí)代kafka使用真香,LinkedIn、Microsoft和Netflix每天都用Kafka處理萬億級的信息。本文就讓我們一起來大白話kafka的架構(gòu)原理,感興趣的朋友一起看看吧
?kafka 架構(gòu)原理
大數(shù)據(jù)時(shí)代來臨,如果你還不知道Kafka那就真的out了!據(jù)統(tǒng)計(jì),有三分之一的世界財(cái)富500強(qiáng)企業(yè)正在使用Kafka,包括所有TOP10旅游公司,7家TOP10銀行,8家TOP10保險(xiǎn)公司,9家TOP10電信公司等等。LinkedIn、Microsoft和Netflix每天都用Kafka處理萬億級的信息。本文就讓我們一起來大白話kafka的架構(gòu)原理。
kafka官網(wǎng):http://kafka.apache.org/
01 kafka簡介
Kafka最初由Linkedin公司開發(fā),是一個(gè)分布式的、分區(qū)的、多副本的、多訂閱者,基于zookeeper協(xié)調(diào)的分布式日志系統(tǒng)(也可以當(dāng)做MQ系統(tǒng)),常用于web/nginx日志、訪問日志、消息服務(wù)等等,Linkedin于2010年貢獻(xiàn)給了Apache基金會(huì)并成為頂級開源項(xiàng)目。
02 kafka的特性
- 高吞吐量、低延遲:kafka每秒可以處理幾十萬條消息,它的延遲最低只有幾毫秒;
- 可擴(kuò)展性:kafka集群支持熱擴(kuò)展;
- 持久性、可靠性:消息被持久化到本地磁盤,并且支持?jǐn)?shù)據(jù)備份防止丟失;
- 容錯(cuò)性:允許集群中的節(jié)點(diǎn)失敗(若分區(qū)副本數(shù)量為n,則允許n-1個(gè)節(jié)點(diǎn)失敗);
- 高并發(fā):單機(jī)可支持?jǐn)?shù)千個(gè)客戶端同時(shí)讀寫;
03 kafka的應(yīng)用場景
- 日志收集:一個(gè)公司可以用Kafka收集各種服務(wù)的log,通過kafka以統(tǒng)一接口開放給各種消費(fèi)端,例如hadoop、Hbase、Solr等。
- 消息系統(tǒng):解耦生產(chǎn)者和消費(fèi)者、緩存消息等。
- 用戶活動(dòng)跟蹤:Kafka經(jīng)常被用來記錄web用戶或者app用戶的各種活動(dòng),如瀏覽網(wǎng)頁、搜索記錄、點(diǎn)擊等活動(dòng),這些活動(dòng)信息被各個(gè)服務(wù)器發(fā)布到kafka的topic中,然后訂閱者通過訂閱這些topic來做實(shí)時(shí)的監(jiān)控分析,或者裝載到hadoop、數(shù)據(jù)倉庫中做離線分析和挖掘。
- 運(yùn)營指標(biāo):Kafka也經(jīng)常用來記錄運(yùn)營監(jiān)控?cái)?shù)據(jù)。
- 流式處理
04 kafka架構(gòu)(重頭戲!)
下面是一個(gè)kafka的架構(gòu)圖,
整體來看,kafka架構(gòu)中包含四大組件:生產(chǎn)者、消費(fèi)者、kafka集群、zookeeper集群。對照上面的結(jié)構(gòu)圖,我們先來搞清楚幾個(gè)很重要的術(shù)語,(看圖!對照圖理解~)
1、broker
kafka 集群包含一個(gè)或多個(gè)服務(wù)器,每個(gè)服務(wù)器節(jié)點(diǎn)稱為一個(gè)broker。
2、topic
每條發(fā)布到kafka集群的消息都有一個(gè)類別,這個(gè)類別稱為topic,其實(shí)就是將消息按照topic來分類,topic就是邏輯上的分類,同一個(gè)topic的數(shù)據(jù)既可以在同一個(gè)broker上也可以在不同的broker結(jié)點(diǎn)上。
3、partition
分區(qū),每個(gè)topic被物理劃分為一個(gè)或多個(gè)分區(qū),每個(gè)分區(qū)在物理上對應(yīng)一個(gè)文件夾,該文件夾里面存儲(chǔ)了這個(gè)分區(qū)的所有消息和索引文件。在創(chuàng)建topic時(shí)可指定parition數(shù)量,生產(chǎn)者將消息發(fā)送到topic時(shí),消息會(huì)根據(jù) 分區(qū)策略 追加到分區(qū)文件的末尾,屬于順序?qū)懘疟P,因此效率非常高(經(jīng)驗(yàn)證,順序?qū)懘疟P效率比隨機(jī)寫內(nèi)存還要高,這是Kafka高吞吐率的一個(gè)很重要的保證)。
上面提到了分區(qū)策略,所謂分區(qū)策略就是決定生產(chǎn)者將消息發(fā)送到哪個(gè)分區(qū)的算法。Kafka 為我們提供了默認(rèn)的分區(qū)策略,同時(shí)它也支持自定義分區(qū)策略。kafka允許為每條消息設(shè)置一個(gè)key,一旦消息被定義了 Key,那么就可以保證同一個(gè) Key 的所有消息都進(jìn)入到相同的分區(qū),這種策略屬于自定義策略的一種,被稱作"按消息key保存策略",或Key-ordering 策略。
同一主題的多個(gè)分區(qū)可以部署在多個(gè)機(jī)器上,以此來實(shí)現(xiàn) kafka 的伸縮性。同一partition中的數(shù)據(jù)是有序的,但topic下的多個(gè)partition之間在消費(fèi)數(shù)據(jù)時(shí)不能保證有序性,在需要嚴(yán)格保證消息順序消費(fèi)的場景下,可以將partition數(shù)設(shè)為1,但這種做法的缺點(diǎn)是降低了吞吐,一般來說,只需要保證每個(gè)分區(qū)的有序性,再對消息設(shè)置key來保證相同key的消息落入同一分區(qū),就可以滿足絕大多數(shù)的應(yīng)用。
4、offset
partition中的每條消息都被標(biāo)記了一個(gè)序號,這個(gè)序號表示消息在partition中的偏移量,稱為offset,每一條消息在partition都有唯一的offset,消息者通過指定offset來指定要消費(fèi)的消息。
正常情況下,消費(fèi)者在消費(fèi)完一條消息后會(huì)遞增offset,準(zhǔn)備去消費(fèi)下一條消息,但也可以將offset設(shè)成一個(gè)較小的值,重新消費(fèi)一些消費(fèi)過的消息,可見offset是由consumer控制的,consumer想消費(fèi)哪一條消息就消費(fèi)哪一條消息,所以kafka broker是無狀態(tài)的,它不需要標(biāo)記哪些消息被消費(fèi)過。
5、producer
生產(chǎn)者,生產(chǎn)者發(fā)送消息到指定的topic下,消息再根據(jù)分配規(guī)則append到某個(gè)partition的末尾。
6、consumer
消費(fèi)者,消費(fèi)者從topic中消費(fèi)數(shù)據(jù)。
7、consumer group
消費(fèi)者組,每個(gè)consumer屬于一個(gè)特定的consumer group,可為每個(gè)consumer指定consumer group,若不指定則屬于默認(rèn)的group。
同一topic的一條消息只能被同一個(gè)consumer group內(nèi)的一個(gè)consumer消費(fèi),但多個(gè)consumer group可同時(shí)消費(fèi)這一消息。這也是kafka用來實(shí)現(xiàn)一個(gè)topic消息的廣播和單播的手段,如果需要實(shí)現(xiàn)廣播,一個(gè)consumer group內(nèi)只放一個(gè)消費(fèi)者即可,要實(shí)現(xiàn)單播,將所有的消費(fèi)者放到同一個(gè)consumer group即可。
用consumer group還可以將consumer進(jìn)行自由的分組而不需要多次發(fā)送消息到不同的topic。
8、leader
每個(gè)partition有多個(gè)副本,其中有且僅有一個(gè)作為leader,leader會(huì)負(fù)責(zé)所有的客戶端讀寫操作。
9、follower
follower不對外提供服務(wù),只與leader保持?jǐn)?shù)據(jù)同步,如果leader失效,則選舉一個(gè)follower來充當(dāng)新的leader。當(dāng)follower與leader掛掉、卡住或者同步太慢,leader會(huì)把這個(gè)follower從ISR列表中刪除,重新創(chuàng)建一個(gè)follower。
10、rebalance
同一個(gè)consumer group下的多個(gè)消費(fèi)者互相協(xié)調(diào)消費(fèi)工作,我們這樣想,一個(gè)topic分為多個(gè)分區(qū),一個(gè)consumer group里面的所有消費(fèi)者合作,一起去消費(fèi)所訂閱的某個(gè)topic下的所有分區(qū)(每個(gè)消費(fèi)者消費(fèi)部分分區(qū)),kafka會(huì)將該topic下的所有分區(qū)均勻的分配給consumer group下的每個(gè)消費(fèi)者,如下圖,
rebalance表示"重平衡",consumer group內(nèi)某個(gè)消費(fèi)者掛掉后,其他消費(fèi)者自動(dòng)重新分配訂閱主題分區(qū)的過程,是 Kafka 消費(fèi)者端實(shí)現(xiàn)高可用的重要手段。如下圖Consumer Group A中的C2掛掉,C1會(huì)接收P1和P2,以達(dá)到重新平衡。同樣的,當(dāng)有新消費(fèi)者加入consumer group,也會(huì)觸發(fā)重平衡操作。
05 對kafka架構(gòu)的幾點(diǎn)解釋
- 一個(gè)典型的kafka集群中包含若干producer,若干broker(Kafka支持水平擴(kuò)展,一般broker數(shù)量越多,集群吞吐率越高),若干consumer group,以及一個(gè)zookeeper集群。kafka通過zookeeper協(xié)調(diào)管理kafka集群,選舉分區(qū)leader,以及在consumer group發(fā)生變化時(shí)進(jìn)行rebalance。
- kafka的topic被劃分為一個(gè)或多個(gè)分區(qū),多個(gè)分區(qū)可以分布在一個(gè)或多個(gè)broker節(jié)點(diǎn)上,同時(shí)為了故障容錯(cuò),每個(gè)分區(qū)都會(huì)復(fù)制多個(gè)副本,分別位于不同的broker節(jié)點(diǎn),這些分區(qū)副本中(不管是leader還是follower都稱為分區(qū)副本),一個(gè)分區(qū)副本會(huì)作為leader,其余的分區(qū)副本作為follower。其中l(wèi)eader負(fù)責(zé)所有的客戶端讀寫操作,follower不對外提供服務(wù),僅僅從leader上同步數(shù)據(jù),當(dāng)leader出現(xiàn)故障時(shí),其中的一個(gè)follower會(huì)頂替成為leader,繼續(xù)對外提供服務(wù)。
- 對于傳統(tǒng)的MQ而言,已經(jīng)被消費(fèi)的消息會(huì)從隊(duì)列中刪除,但在Kafka中被消費(fèi)的消息也不會(huì)立馬刪除,在kafka的server.propertise配置文件中定義了數(shù)據(jù)的保存時(shí)間,當(dāng)文件到設(shè)定的保存時(shí)間時(shí)才會(huì)刪除,
# 數(shù)據(jù)的保存時(shí)間(單位:小時(shí),默認(rèn)為7天)
log.retention.hours=168
因?yàn)镵afka讀取消息的時(shí)間復(fù)雜度為O(1),與文件大小無關(guān),所以這里刪除過期文件與提高Kafka性能并沒有關(guān)系,所以選擇怎樣的刪除策略應(yīng)該考慮磁盤以及具體的需求。
- 點(diǎn)對點(diǎn)模式 VS 發(fā)布訂閱模式
傳統(tǒng)的消息系統(tǒng)中,有兩種主要的消息傳遞模式:點(diǎn)對點(diǎn)模式、發(fā)布訂閱模式。
①點(diǎn)對點(diǎn)模式?
生產(chǎn)者發(fā)送消息到queue中,queue支持存在多個(gè)消費(fèi)者,但是對一個(gè)消息而言,只可以被一個(gè)消費(fèi)者消費(fèi),并且在點(diǎn)對點(diǎn)模式中,已經(jīng)消費(fèi)過的消息會(huì)從queue中刪除不再存儲(chǔ)。
②發(fā)布訂閱模式
生產(chǎn)者將消息發(fā)布到topic中,topic可以被多個(gè)消費(fèi)者訂閱,且發(fā)布到topic的消息會(huì)被所有訂閱者消費(fèi)。而kafka就是一種發(fā)布訂閱模式。
① push方式:由消息中間件主動(dòng)地將消息推送給消費(fèi)者;
優(yōu)點(diǎn):優(yōu)點(diǎn)是不需要消費(fèi)者額外開啟線程監(jiān)控中間件,節(jié)省開銷。
缺點(diǎn):無法適應(yīng)消費(fèi)速率不相同的消費(fèi)者。因?yàn)橄⒌陌l(fā)送速率是broker決定的,而消
費(fèi)者的處理速度又不盡相同,所以容易造成部分消費(fèi)者空閑,部分消費(fèi)者堆積,造成緩
沖區(qū)溢出。
② pull方式:由消費(fèi)者主動(dòng)向消息中間件拉取消息;
優(yōu)點(diǎn):消費(fèi)端可以按處理能力進(jìn)行拉??;
缺點(diǎn):消費(fèi)端需要另開線程監(jiān)控中間件,有性能開銷;
對于Kafka而言,pull模式更合適。pull模式可簡化broker的設(shè)計(jì),Consumer可自主控制消費(fèi)消息的速率,同時(shí)Consumer可以自己控制消費(fèi)方式,既可批量消費(fèi)也可逐條消費(fèi),同時(shí)還能選擇不同的提交方式從而實(shí)現(xiàn)不同的傳輸語義。
06 kafka和rabbitMQ對比
RabbitMQ
|
Kafka
|
開發(fā)語言
|
erlang
|
scala,Java
|
架構(gòu)模型
|
① 遵循AMQP;
② 生產(chǎn)者、消費(fèi)者、broker。
③ broker由exchange、binding、queue組成;
④ consumer消費(fèi)位置由broker通過確認(rèn)機(jī)制保存;
|
① 不遵循AMQP;
② 生產(chǎn)者、消費(fèi)者、kafka集群、zookeeper集群;
③ kafka集群由多個(gè)broker節(jié)點(diǎn)組成,消息按照topic分類,每個(gè)topic又劃分為多個(gè)partition;
④ broker無狀態(tài),offset由消費(fèi)者指定;
|
可靠性
|
|
RabbitMQ可靠性更好,支持事務(wù),支持消息確認(rèn)機(jī)制
|
高可用
|
采用鏡像隊(duì)列,即主從模式,數(shù)據(jù)是異步同步的,當(dāng)消息過來,主從全部寫完后,回ack,這樣保障了數(shù)據(jù)的一致性。
|
每個(gè)分區(qū)都有一個(gè)或多個(gè)副本,這些副本保存在不同的broker上,其中有且僅有一個(gè)分區(qū)副本作為leader,其余的作為follower,當(dāng)leader不可用時(shí),會(huì)選舉follower作為新leader繼續(xù)提供服務(wù)。
只有l(wèi)eader提供讀寫服務(wù),follower從leader同步拉取數(shù)據(jù)然后備份。
|
吞吐量
|
kafka更高
|
|
是否支持事務(wù)
|
支持
|
不支持
|
負(fù)載均衡
|
需要外部支持才能實(shí)現(xiàn)(如:loadbalancer)
|
kafka利用zk和分區(qū)機(jī)制實(shí)現(xiàn)負(fù)載均衡
|
是否支持消費(fèi)者Push
|
不支持
|
支持
|
是否支持消費(fèi)者Pull
|
支持
|
支持
|
適用場景
|
kafka的優(yōu)勢主要體現(xiàn)在吞吐量上,它主要用在高吞吐量的場景。比如日志采集。
|
具有較高的嚴(yán)謹(jǐn)性,數(shù)據(jù)丟失的可能性更小,同時(shí)具備較高的實(shí)時(shí)性,用在對實(shí)時(shí)性、可靠性要求較高的消息傳遞上。
|
07 kafka吞吐量為什么這么高
1、順序讀寫磁盤
Kafka是將消息持久化到本地磁盤中的,一般人會(huì)認(rèn)為磁盤讀寫性能差,可能會(huì)對Kafka性能提出質(zhì)疑。實(shí)際上不管是內(nèi)存還是磁盤,快或慢的關(guān)鍵在于尋址方式,磁盤分為順序讀寫與隨機(jī)讀寫,內(nèi)存一樣也分為順序讀寫與隨機(jī)讀寫?;诖疟P的隨機(jī)讀寫確實(shí)很慢,但基于磁盤的順序讀寫性能卻很高,一般而言要高出磁盤的隨機(jī)讀寫三個(gè)數(shù)量級,一些情況下磁盤順序讀寫性能甚至要高于內(nèi)存隨機(jī)讀寫,這里貼一張著名學(xué)術(shù)期刊 ACM Queue 上的一張性能對比圖:
2、page cache
為了優(yōu)化讀寫性能,Kafka利用了操作系統(tǒng)本身的Page Cache,就是利用操作系統(tǒng)自身的內(nèi)存而不是JVM空間內(nèi)存。這樣做是因?yàn)椋?/div>
JVM中一切皆對象,對象的存儲(chǔ)會(huì)帶來額外的內(nèi)存消耗;
使用JVM會(huì)受到GC的影響,隨著數(shù)據(jù)的增多,垃圾回收也會(huì)變得復(fù)雜與緩慢,降低吞吐量;
另外操作系統(tǒng)本身對page cache做了大量優(yōu)化,通過操作系統(tǒng)的Page Cache,Kafka的讀寫操作基本上是基于系統(tǒng)內(nèi)存的,讀寫性能也得到了極大的提升。
3、零拷貝
零拷貝是指Kafka利用 linux 操作系統(tǒng)的 "zero-copy" 機(jī)制在消費(fèi)端做的優(yōu)化。首先來看一下消費(fèi)端在消費(fèi)數(shù)據(jù)時(shí),數(shù)據(jù)從broker磁盤通過網(wǎng)絡(luò)傳輸?shù)较M(fèi)端的整個(gè)過程:
操作系統(tǒng)從磁盤讀取數(shù)據(jù)到內(nèi)核空間(kernel space)的page cache;
應(yīng)用程序讀取page cache的數(shù)據(jù)到用戶空間(user space)的緩沖區(qū);
應(yīng)用程序?qū)⒂脩艨臻g緩沖區(qū)的數(shù)據(jù)寫回內(nèi)核空間的socket緩沖區(qū)(socket buffer);
操作系統(tǒng)將數(shù)據(jù)從socket緩沖區(qū)復(fù)制到硬件(如網(wǎng)卡)緩沖區(qū);
整個(gè)過程如上圖所示,這個(gè)過程包含4次copy操作和2次系統(tǒng)上下文切換,而上下文切換是CPU密集型的工作,數(shù)據(jù)拷貝是I/O密集型的工作,性能其實(shí)非常低效。
零拷貝就是使用了一個(gè)名為sendfile()的系統(tǒng)調(diào)用方法,將數(shù)據(jù)從page cache直接發(fā)送到Socket緩沖區(qū),避免了系統(tǒng)上下文的切換,消除了從內(nèi)核空間到用戶空間的來回復(fù)制。從上圖可以看出,"零拷貝"并不是說整個(gè)過程完全不發(fā)生拷貝,而是站在內(nèi)核的角度來說的,避免了內(nèi)核空間到用戶空間的來回拷貝。
4、分區(qū)分段
Kafka的message是按topic分類存儲(chǔ)的,topic中的數(shù)據(jù)又是按照一個(gè)一個(gè)的partition即分區(qū)存儲(chǔ)到不同broker節(jié)點(diǎn)。每個(gè)partition對應(yīng)了操作系統(tǒng)上的一個(gè)文件夾,partition實(shí)際上又是按照segment分段存儲(chǔ)的。這也非常符合分布式系統(tǒng)分區(qū)分桶的設(shè)計(jì)思想。
通過這種分區(qū)分段的設(shè)計(jì),Kafka的message消息實(shí)際上是分布式存儲(chǔ)在一個(gè)一個(gè)小的segment中的,每次文件操作也是直接操作的segment。為了進(jìn)一步的查詢優(yōu)化,Kafka又默認(rèn)為分段后的數(shù)據(jù)文件建立了索引文件,就是文件系統(tǒng)上的.index文件。這種分區(qū)分段+索引的設(shè)計(jì),不僅提升了數(shù)據(jù)讀取的效率,同時(shí)也提高了數(shù)據(jù)操作的并行度。
總之,Kafka采用順序讀寫、Page Cache、零拷貝以及分區(qū)分段等這些設(shè)計(jì),再加上在索引方面做的優(yōu)化,另外Kafka數(shù)據(jù)讀寫也是批量的而不是單條的,使得Kafka具有了高性能、高吞吐、低延時(shí)的特點(diǎn)。
到此這篇關(guān)于深入解析kafka 架構(gòu)原理的文章就介紹到這了,更多相關(guān)kafka 架構(gòu)原理內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
idea日志亂碼和tomcat日志亂碼問題的解決方法
這篇文章主要介紹了idea日志亂碼和tomcat日志亂碼問題的解決方法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
2020-08-08