阿里大牛實戰歸納——Kafka架構原理
對於kafka的架構原理我們先提出幾個問題?
1.Kafka的topic和分割槽內部是如何儲存的,有什麼特點?
2.與傳統的訊息系統相比,Kafka的消費模型有什麼優點?
3.Kafka如何實現分散式的資料儲存與資料讀取?
Kafka架構圖
1.kafka名詞解釋
在一套kafka架構中有多個Producer,多個Broker,多個Consumer,每個Producer可以對應多個Topic,每個Consumer只能對應一個ConsumerGroup。
整個Kafka架構對應一個ZK叢集,通過ZK管理叢集配置,選舉Leader,以及在consumer group發生變化時進行rebalance。
名稱解釋
Broker
訊息中介軟體處理節點,一個Kafka節點就是一個broker,一個或者多個Broker可以組成一個Kafka叢集
Topic
主題,Kafka根據topic對訊息進行歸類,釋出到Kafka叢集的每條訊息都需要指定一個topic
Producer
訊息生產者,向Broker傳送訊息的客戶端
Consumer
訊息消費者,從Broker讀取訊息的客戶端
ConsumerGroup
每個Consumer屬於一個特定的Consumer Group,一條訊息可以傳送到多個不同的Consumer Group,但是一個Consumer Group中只能有一個Consumer能夠消費該訊息
Partition
物理上的概念,一個topic可以分為多個partition,每個partition內部是有序的
2.Topic和Partition
在Kafka中的每一條訊息都有一個topic。一般來說在我們應用中產生不同型別的資料,都可以設定不同的主題。一個主題一般會有多個訊息的訂閱者,當生產者釋出訊息到某個主題時,訂閱了這個主題的消費者都可以接收到生產者寫入的新訊息。
kafka為每個主題維護了分散式的分割槽(partition)日誌檔案,每個partition在kafka儲存層面是append log。任何釋出到此partition的訊息都會被追加到log檔案的尾部,在分割槽中的每條訊息都會按照時間順序分配到一個單調遞增的順序編號,也就是我們的offset,offset是一個long型的數字,我們通過這個offset可以確定一條在該partition下的唯一訊息。在partition下面是保證了有序性,但是在topic下面沒有保證有序性。
在上圖中在我們的生產者會決定傳送到哪個Partition。
如果沒有Key值則進行輪詢傳送。
如果有Key值,對Key值進行Hash,然後對分割槽數量取餘,保證了同一個Key值的會被路由到同一個分割槽,如果想佇列的強順序一致性,可以讓所有的訊息都設定為同一個Key。
3.消費模型
訊息由生產者傳送到kafka叢集后,會被消費者消費。一般來說我們的消費模型有兩種:推送模型(psuh)和拉取模型(pull)
基於推送模型的訊息系統,由訊息代理記錄消費狀態。訊息代理將訊息推送到消費者後,標記這條訊息為已經被消費,但是這種方式無法很好地保證消費的處理語義。比如當我們把已經把訊息傳送給消費者之後,由於消費程式掛掉或者由於網路原因沒有收到這條訊息,如果我們在消費代理將其標記為已消費,這個訊息就永久丟失了。如果我們利用生產者收到訊息後回覆這種方法,訊息代理需要記錄消費狀態,這種不可取。如果採用push,訊息消費的速率就完全由消費代理控制,一旦消費者發生阻塞,就會出現問題。
Kafka採取拉取模型(poll),由自己控制消費速度,以及消費的進度,消費者可以按照任意的偏移量進行消費。比如消費者可以消費已經消費過的訊息進行重新處理,或者消費最近的訊息等等。
4.網路模型
4.1 KafkaClient –單執行緒Selector
單執行緒模式適用於併發連結數小,邏輯簡單,資料量小。
在kafka中,consumer和producer都是使用的上面的單執行緒模式。這種模式不適合kafka的服務端,在服務端中請求處理過程比較複雜,會造成執行緒阻塞,一旦出現後續請求就會無法處理,會造成大量請求超時,引起雪崩。而在伺服器中應該充分利用多執行緒來處理執行邏輯。
4.2 Kafka–server — 多執行緒Selector
在kafka服務端採用的是多執行緒的Selector模型,Acceptor執行在一個單獨的執行緒中,對於讀取操作的執行緒池中的執行緒都會在selector註冊read事件,負責服務端讀取請求的邏輯。成功讀取後,將請求放入message queue共享佇列中。然後在寫執行緒池中,取出這個請求,對其進行邏輯處理,即使某個請求執行緒阻塞了,還有後續的縣城從訊息佇列中獲取請求並進行處理,在寫執行緒中處理完邏輯處理,由於註冊了OP_WIRTE事件,所以還需要對其傳送響應。
5.高可靠分散式儲存模型
在Kafka中保證高可靠模型的依靠的是副本機制,有了副本機制之後,就算機器當機也不會發生資料丟失。
5.1高效能的日誌儲存
kafka一個topic下面的所有訊息都是以partition的方式分散式的儲存在多個節點上。同時在kafka的機器上,每個Partition其實都會對應一個日誌目錄,在目錄下面會對應多個日誌分段(LogSegment)。LogSegment檔案由兩部分組成,分別為“.index”檔案和“.log”檔案,分別表示為segment索引檔案和資料檔案。這兩個檔案的命令規則為:partition全域性的第一個segment從0開始,後續每個segment檔名為上一個segment檔案最後一條訊息的offset值,數值大小為64位,20位數字字元長度,沒有數字用0填充,如下,假設有1000條訊息,每個LogSegment大小為100,下面展現了900-1000的索引和Log:
由於kafka訊息資料太大,如果全部建立索引,即佔了空間又增加了耗時,所以kafka選擇了稀疏索引的方式,這樣的話索引可以直接進入記憶體,加快偏查詢速度。
簡單介紹一下如何讀取資料,如果我們要讀取第911條資料首先第一步,找到他是屬於哪一段的,根據二分法查詢到他屬於的檔案,找到0000900.index和00000900.log之後,然後去index中去查詢 (911-900) =11這個索引或者小於11最近的索引,在這裡通過二分法我們找到了索引是[10,1367]然後我們通過這條索引的物理位置1367,開始往後找,直到找到911條資料。
上面講的是如果要找某個offset的流程,但是我們大多數時候並不需要查詢某個offset,只需要按照順序讀即可,而在順序讀中,作業系統會對記憶體和磁碟之間新增page cahe,也就是我們平常見到的預讀操作,所以我們的順序讀操作時速度很快。但是kafka有個問題,如果分割槽過多,那麼日誌分段也會很多,寫的時候由於是批量寫,其實就會變成隨機寫了,隨機I/O這個時候對效能影響很大。所以一般來說Kafka不能有太多的partition。針對這一點,RocketMQ把所有的日誌都寫在一個檔案裡面,就能變成順序寫,通過一定優化,讀也能接近於順序讀。
可以思考一下:
1.為什麼需要分割槽,也就是說主題只有一個分割槽,難道不行嗎?2.日誌為什麼需要分段
5.2副本機制
Kafka的副本機制是多個服務端節點對其他節點的主題分割槽的日誌進行復制。當叢集中的某個節點出現故障,訪問故障節點的請求會被轉移到其他正常節點(這一過程通常叫Reblance),kafka每個主題的每個分割槽都有一個主副本以及0個或者多個副本,副本保持和主副本的資料同步,當主副本出故障時就會被替代。
在Kafka中並不是所有的副本都能被拿來替代主副本,所以在kafka的leader節點中維護著一個ISR(In sync Replicas)集合,翻譯過來也叫正在同步中集合,在這個集合中的需要滿足兩個條件:
節點必須和ZK保持連線
在同步的過程中這個副本不能落後主副本太多
另外還有個AR(Assigned Replicas)用來標識副本的全集,OSR用來表示由於落後被剔除的副本集合,所以公式如下:ISR = leader + 沒有落後太多的副本; AR = OSR+ ISR;
這裡先要說下兩個名詞:HW(高水位)是consumer能夠看到的此partition的位置,LEO是每個partition的log最後一條Message的位置。HW能保證leader所在的broker失效,該訊息仍然可以從新選舉的leader中獲取,不會造成訊息丟失。
當producer向leader傳送資料時,可以通過request.required.acks引數來設定資料可靠性的級別:
1(預設):這意味著producer在ISR中的leader已成功收到的資料並得到確認後傳送下一條message。如果leader當機了,則會丟失資料。
0:這意味著producer無需等待來自broker的確認而繼續傳送下一批訊息。這種情況下資料傳輸效率最高,但是資料可靠性確是最低的。
-1:producer需要等待ISR中的所有follower都確認接收到資料後才算一次傳送完成,可靠性最高。但是這樣也不能保證資料不丟失,比如當ISR中只有leader時(其他節點都和zk斷開連線,或者都沒追上),這樣就變成了acks=1的情況。
歡迎工作一到五年的Java工程師朋友們加入Java架構開發:744677563
本群提供免費的學習指導 架構資料 以及免費的解答
不懂得問題都可以在本群提出來 之後還會有職業生涯規劃以及面試指導
相關文章
- Kafka 原理和實戰Kafka
- 《Kafka實戰》之架構和設計邏輯Kafka架構
- 乾貨:阿里大牛淺談MySQL架構體系阿里MySql架構
- 架構實戰架構
- Kafka 架構和原理機制 (圖文全面詳解)Kafka架構
- Kafka實戰-Kafka ClusterKafka
- “阿里架構師”kafka 資料可靠性深度解讀阿里架構Kafka
- 工具歸納
- Kafka ACL實現架構以及實操案例剖析Kafka架構
- 微軟程式歸納新技術:元程式歸納微軟
- Kafka實戰-Flume到KafkaKafka
- Kafka實戰-Kafka到StormKafkaORM
- Kafka剖析:Kafka背景及架構介紹Kafka架構
- 最全的資料結構解析與歸納資料結構
- Mysql實戰:基礎架構MySql架構
- kafka核心架構詳解Kafka架構
- Apache Kafka – 叢集架構ApacheKafka架構
- Kafka實戰-KafkaOffsetMonitorKafka
- Kafka剖析(一):Kafka背景及架構介紹Kafka架構
- 廣告歸因-讓你徹底弄歸因架構實現架構
- 架構實戰--軟體架構設計的過程架構
- 金字塔原理(5)- 演繹與歸納的區別
- 安全架構評審實戰架構
- Nacos實戰一:架構及部署架構
- Kafka 概述:深入理解架構Kafka架構
- KAFKA介紹(分散式架構)Kafka分散式架構
- 《Kafka筆記》4、Kafka架構,與其他元件整合Kafka筆記架構元件
- oracle段管理歸納Oracle
- html標記歸納HTML
- kafka實戰教學Kafka
- Kafka實戰-入門Kafka
- Kafka實戰-Storm ClusterKafkaORM
- 動作遊戲戰鬥系統總結歸納&思考(中)遊戲
- 大型分散式系統現場,阿里大牛帶你實戰分散式系統分散式阿里
- 大規模分散式儲存系統:原理解析與架構實戰分散式架構
- Kafka事務實現原理Kafka
- Kafka 架構圖-輕鬆理解 kafka 生產消費Kafka架構
- 基於SpringCloud的Microservices架構實戰案例-架構拆解SpringGCCloudROS架構