文章目錄
- 一、前言
- 二、Kafka簡介
- 2.1 Kafka簡介
- 2.2 基于分布式的Kafka
- 三、Kafka架構
- 3.1 訊息生產與消費
- 3.1.1 訊息生產與消費模型
- 3.1.2 Kafka消費單元是消費者組
- 3.1.3 Kafka只消費Partition主磁區的訊息
- 3.1.4 消費者組中的每個消費者的offset
- 3.1.5 小結
- 3.2 Partition備份與選主
- 3.3 高級特性
- 3.3.1 四個核心API
- 3.3.2 攢一波再發
- 3.3.3 普通消費模式和高級消費模式
- 3.4 Kafka整體架構
- 四、Kafka應用場景
- 4.1 Kafka應用場景:訊息
- 4.2 Kafka應用場景:跟蹤網站活動
- 4.3 Kafka應用場景:日志聚合
- 4.4 Kafka應用場景:流處理
- 4.5 Kafka應用場景:事件采集
- 4.6 Kafka應用場景:提交日志
- 五、尾聲
一、前言
本文主要介紹kafka架構與應用場景,

二、Kafka簡介
2.1 Kafka簡介
Kafka 是 linkedin 使用 Scala 撰寫具有高水平擴展和高吞吐量的分布式訊息系統,
Kafka 對訊息保存時根據 Topic 進行歸類,發送訊息者成為 Producer ,訊息接受者成為 Consumer ,此外 kafka 集群有多個 kafka 實體組成,每個實體(server)稱為 broker,
無論是 Kafka集群,還是 producer 和 consumer 都依賴于 zookeeper 來保證系統可用性,為集群保存一些 meta 資訊,
Apache Kafka? 是 一個分布式流處理平臺,流處理平臺的特性包括:
(1) 可以讓你發布和訂閱流式的記錄,這一方面與訊息佇列或者企業訊息系統類似,
(2) 可以儲存流式的記錄,并且有較好的容錯性,
(3) 可以在流式記錄產生時就進行處理,
Kafka 適合什么樣的場景?
(1) 構造實時流資料管道,它可以在系統或應用之間可靠地獲取資料, (相當于訊息佇列)
(2) 構建實時流式應用程式,對這些流資料進行轉換或者影響,
Kafka主要特性
(1) kafka作為一個集群運行在一個或多個服務器上
(2) Kafka 通過 topic 對存盤的流資料進行分類
(3) 每條記錄中包含一個 key ,一個 value 和一個 timestamp(時間戳)
2.2 基于分布式的Kafka
從普通訊息佇列到分布式訊息佇列kafka,最大的不同就是支持動態擴容,

取rabbitmq和kafka做對比,則相同點和不同點如下:
相同點:kafka和rabbitmq都是存盤佇列
不同點:
(1) 消費單元不同
在rabbitmq中,對于每個訊息,一個消費者只能消費這個訊息一次,但是這個訊息可以同時被發送給多個消費者消費;在kafka中,一個消費者組只能消費一個訊息一次,但是這個訊息可以同時被發送給多個消費者組消費
(2) 訊息消費不同
rabbitmq中,被成功消費ack的訊息就自動被洗掉了,沒有了(默認自動ack),kafka中,訊息被成功消費后,不會被洗掉,只是移動消費者的offset(消費者的offset保存在zk上),kafka默認保存7天(訊息中有一個timestamp屬性,可以用這個屬性來控制訊息保存時間),
(3) 訊息組成不同
rabbitmq中訊息 = routingkey + headers(properties) + payload
kafka中訊息 = 組態檔中log位置 (三個檔案) = index(key) + value + timestamp
index/key用來排序(順序消費)或索引,不指定默認index/key為空,value就是訊息體,timestamp用來物理洗掉訊息(kafka默認訊息存盤7天,因為消費的時候只是移動offset,沒有洗掉訊息)
(4) 組成不同
rabbitmq由exchange交換機和queue佇列構成,exchage是一個抽象概念,不存盤訊息,佇列是真實概念,是真正存盤訊息的組件
kafka由topic和partition組成,topic類似exchange,不存盤資料,但是消費者要消費資料是指定topic的,然后topic從相應的partition取出資料給消費者,partition類似rabbitmq中的queue,是真正存盤訊息的組件,
問題:為什么kafka是起碼要一個消費者組,而rabbitmq最小單元是一個消費者?
回答:因為kafka是天然分布式的,n broker 就有 n 個partition,
問題:kafka如何實作順序消費?
回答:同一個partition,所有訊息的key都為慷訓者所有訊息的key相同,
eg1: 對于kafka,消費者消費訊息可以從start開始,也可以從end開始,但是都只能從old到new,
eg2: 對于kafka,如果不指定topic數量,默認三個,
三、Kafka架構
3.1 訊息生產與消費
3.1.1 訊息生產與消費模型
kafka和其他訊息佇列一樣,訊息生產與消費模型非常簡單,如下:

服務器端(broker):用來接收生產者發送的訊息并將這些訊息路由給服務器中的佇列
消費者(Consumer):從訊息佇列中請求訊息的客戶端應用程式
生產者(Producer):向 broker 發布訊息的客戶端應用程式
3.1.2 Kafka消費單元是消費者組
在kafka中,最重要的一個組件是是topic,但是這個topic不存盤資料,真正存盤資料的是partition,topic類似rabbitmq的exchanges,topic既然不存盤資料,那么它的作用是什么,topic唯一的作用就是資料主題,是資料記錄發布的地方,可以用來區分業務系統(名為test用來測驗,名為pro用來生產),Kafka 中的 Topics 總是多訂閱者模式,即一個 topic 可以擁有一個或者多個消費者來訂閱它的資料,就是消費者組中每個消費者是找topic要訊息,而不是直接partition,topic的作用就是將partition中的訊息拿來給消費者,
對于kafka來說,producer生產資料存放到kafka是比較簡單的,主要是看訊息消費,因為kafka是天然分布式的,這里涉及到一個消費者組的概念,
比方說,生產了 message1 message2 message3,分別存盤到partition1 partition2 partition3,partition相當于佇列,有三個消費者,如何消費?這里涉及到一個消費者組的概率,消費者組誕生的意義在于一個消費者組消費所有partition(這里是三個partition)上存盤的所有訊息,一個訊息只能被一個消費組消費一次,至于拿個消費者能消費到哪些訊息,就看消費者組怎么分配,
如果consumer1自己屬于一個消費者組,consumer2和consumer3屬于另一個消費者組,則consumer1可以消費到message1 message2 message3這三個訊息,consumer2和consumer3共同消費message1 message2 message3,一個訊息只能被一個消費組消費一次,具體這個訊息被消費者組中的哪個消費者消費,就不是程式員可以決定的了,
如果consumer1屬于一個消費者組,consumer2屬于另一個消費者組,consumer3屬于第三個消費者組,則每個消費者都可以消費三個訊息,
還可以交叉覆寫,如果consumer1 consumer2屬于一個消費者組,consumer2 consumer3屬于另一個消費者組,則consumer1和consumer2可以消費三個訊息,consumer2和consumer3又可以消費這三個訊息,
這就是Kafka消費者組的概念,王道在于一個消費者組消費所有partition上存盤的所有訊息,一個訊息只能被一個消費組消費一次,消費者與partion的關系:
情況1:正常情況,一個消費者組中三個消費者對應三個partition,那么每個消費者消費一個partition;
情況2:如果消費者組中的某個消費者掛了,則一個消費者組中,兩個消費者對應三個partition,那么其中一個消費者可能就要消費兩個partition了;
情況3:如果只有三個partition,而消費者組有4個消費者,則一個消費者組中,四個消費者對應三個partition,那么一個消費者會空閑;
情況4:如果多加入一個消費者組,則兩個消費者組對應三個partition,無論是新增的消費者組還是原本的消費者組,都能消費topic的全部資料(理由:消費者組之間從邏輯上它們是獨立的),
消費者組本質:消費者組是一個多執行緒的概念,就是多個執行緒來消費所有訊息(各個partition磁區訊息總和),消費者實體可以分布在多個行程中或者多個機器上,
(1)消費者組這個概念是必須的,只有一個消費者那么消費者組就只有一個消費者,有N個消費者那么消費者組就只有N個消費者;
(2)消費者組必須消費所有partition主磁區的訊息:組中消費者不夠,一個消費者就要消費多個partition,因為消費者組有義務將Partition上的message消費完;如果組中消費者多了,就有人可以不用干事了;
(3)同一個消費組中,一個訊息message只被消費一次,
消費者使用一個消費組名稱來進行標識,發布到 topic 中的每條記錄被分配給訂閱消費組中的一個消費者實體,消費者實體可以分布在多個行程中或者多個機器上,如果所有的消費者實體在同一消費組中,訊息記錄會負載平衡到每一個消費者實體,如果所有的消費者實體在不同的消費組中,每條訊息記錄會廣播到所有的消費者行程,如下圖:

3.1.3 Kafka只消費Partition主磁區的訊息
Kafka的訊息時存盤在partition上,但是每個partition有個備份,包括一個主partition和n個從partition,但是生產者在寫資料到kafka的時候,主partition和從partition的存在訊息不一致的情況,如下圖

上圖表示的是 0 1 2 3 4 5 6 7 8 9 10 11 12 ,這個圖想要告訴讀者的是,訊息存放在三個partition的時候,資料不是一致的,那么消費者如果從不同的partition拿資料,會不會拿到遺漏或者重復的資料,答案是不會,因為當消費者是找topic要訊息,而不是直接找partion要訊息,topic每次從主磁區找資料給消費者,即消費者只消費主磁區的訊息,從磁區只是同步主磁區的訊息,
kafka這個磁區資料存在不一致的情況和rabbitmq的cluster的普通模式相同,資料存在不一致,rabbitmq鏡像模式資料是一致的,
小結:消費者組只消費主磁區的,因為kafka中,生產者消費者讀寫的是主磁區,從磁區不做生產消費,而且,kakfa對于機械硬碟使用順序讀寫,就不需要尋址時間,速度接近隨機讀寫,從磁區只要按固定的策略同步主磁區的資料就好了,待主磁區宕機,在zookeeper的協調下選出新的partition,供生產和消費,
3.1.4 消費者組中的每個消費者的offset
關于offset
(1)每個消費者都一個offset,相互獨立不影響
(2)每個消費者的offset存盤在zookeeper上面去,這樣即使consumer宕機下一次也可以接著消費,因為上一次的消費位置offset,zookeeper幫他記錄著,consumer重新啟動后,按照自己的offset接著消費就好了
即使是同一個消費者組,consumer1和consumer2也各有一個offset,每個消費者接入進來,都需要從zookeeper取下offset,如果消費者第一次進來,zookeeper建立從0開始,如下圖:

一般來說,n broker 就有 n partition,除非所有broker都宕機,否則不會丟資料,而且還是磁盤持久化保證,
eg: offset只對消費者有用,對生產者沒用
3.1.5 小結
問題:N個消費者如何消費M個Partition如何消費?
回答:消費者組的引入解決如何消費的問題,核心是一個消費者組必須完全消費所有partion訊息,一個訊息也只能被一個消費者組中某個消費者消費,在同一個消費者組中,一個訊息永遠不會消費兩次,不會重復消費,
情況1:正常情況,一個消費者組中三個消費者對應三個partition,那么每個消費者消費一個partition;
情況2:如果消費者組中的某個消費者掛了,則一個消費者組中,兩個消費者對應三個partition,那么其中一個消費者可能就要消費兩個partition了;
情況3:如果只有三個partition,而消費者組有4個消費者,則一個消費者組中,四個消費者對應三個partition,那么一個消費者會空閑;
情況4:如果多加入一個消費者組,則兩個消費者組對應三個partition,無論是新增的消費者組還是原本的消費者組,都能消費topic的全部資料(理由:消費者組之間從邏輯上它們是獨立的),
問題:被消費的訊息洗掉了嗎?
回答:被消費的訊息只是移動offset,不洗掉,默認存盤7天(用訊息體中的timestamp可以知道訊息存了多久),offset存盤在zookeeper,因為zookeeper可以保證資料一致性,offset不可能存某個服務器的磁盤,
問題:kafka讀寫訊息、洗掉訊息需要掃描整個磁盤嗎?
回答:不需要,每個都一個timestamp欄位,kafka采用順序讀寫可以保證洗掉訊息很方便,
問題:partition有多個,生產者寫資料到kafka,存在資料不一致情況,如何保證訊息消費不重不漏?
回答:只消費主磁區保證消費訊息不重不漏,partion有主從之分,只消費主磁區,從磁區只同步作用,從而保證消費訊息不重不漏,
問題:kafka消費順序有哪些?
回答:kakfa可以從當前head消費,也可以從當前tail消費,但是只能從old到new消費,即old->new消費,不能反過來,
3.2 Partition備份與選主
每個partition還會被復制到其它服務器作為replication,這是一種冗余備份策略,如下圖:

Partition備份四個特性
(1) 同一個partition的多個replication不允許在同一broker上
(2) 每個partition的replication中,有一個leader ,零或多個follower
(3) leader處理此磁區的所有的讀寫請求, follower僅僅被動的復制資料
(4) leader宕機后,會從follower中選舉出新的leader
Partition磁區被分布到集群中的多個服務器上,每個服務器處理它分到的磁區, 根據配置每個磁區還可以復制到其它服務器作為備份容錯, 每個磁區有一個 leader,零或多個 follower,Leader 處理此磁區的所有的讀寫請求,而 follower 被動的復制資料,
如果 leader 宕機,其它的一個 follower 會被推舉為新的 leader,選主需要依賴的是zookeeper中間件來完成,zk選主的時候,哪個從磁區的資料與宕機的主磁區的資料最相近,同步時間與主磁區最接近的,被選為主磁區,一臺服務器可能同時是一個磁區的 leader,另一個磁區的 follower, 這樣可以平衡負載,避免所有的請求都只讓一臺或者某幾臺服務器處理,
3.3 高級特性
3.3.1 四個核心API
Producer API
允許一個應用程式發布一串流式的資料到一個或者多個 Kafka topic,
Consumer API
允許一個應用程式訂閱一個或多個 topic ,并且對發布給他們的流式資料進行處理,
Streams API
允許一個應用程式作為一個流處理器,消費一個或者多個 topic 產生的輸入流,然后生產一個輸出流到一個或多個 topic 中去,在輸入輸出流中進行有效的轉換,
Connector API
允許構建并運行可重用的生產者或者消費者,將Kafka topics連接到已存在的應用程式或者資料系統,比如,連接到一個關系型資料庫,捕捉表(table)的所有變更內容,
Kafka四個核心API關系如下圖:

上圖告訴我們,在Kafka中,客戶端和服務器之間的通信是通過簡單,高性能,語言無關的TCP協議完成的,即kafka可以使用java scala混編,通過 tcp/ip 網路通信實作語言無關性,此協議已版本化并保持與舊版本的向后兼容性,Kafka提供多種語言客戶端,
上圖中的 Connector 表示kafka和其他連接,例如 mysql redis 等,
3.3.2 攢一波再發
Producer向kafka發送訊息的時候,Producer會為每個partition維護一個緩沖,用來記錄還沒有發送的資料,每個緩沖區大小用 batch.size指定,默認值為16k,就是資料一定要等到滿16K才發送,就是攢一波再發,減少網路性能消耗,如下圖:

eg: 還有一個引數 linger.ms,這個引數表示buffer中的資料在達到batch.size前,需要等待的時間,
3.3.3 普通消費模式和高級消費模式
普通消費模式:Kafka Simple Consumer
Simple Cnsumer 位于kafka.javaapi.consumer包中,不提供負載均衡、容錯的特性每次獲取資料都要指定topic、partition、offset、fetchSize,
高級消費模式:High-level Consumer
該客戶端透明地處理kafka broker例外,透明地切換consumer的partition,通過和broker互動來實作consumer group級別的負載均衡,如下圖:

輔助理解: 普通消費模式類似匯編語言 C語言,啥都沒有,需要程式員自己指定;高級消費模式類似Java語言 Python語言,很多都配好了,程式員直接用就好了,
一般都是都是使用高級消費模式,
3.4 Kafka整體架構
對于kafka整體架構,只要知道topic和partition的這個兩個最關鍵的組件,可以了,如下圖:

eg: 上圖中zookeeper,用來保存每個消費者的offset,
四、Kafka應用場景
4.1 Kafka應用場景:訊息
kafka 更好的替換傳統的訊息系統,訊息系統被用于各種場景(解耦資料生產者,快取未處理的訊息),與大多數訊息系統比較,kafka 有更好的吞吐量,內置磁區,副本和故障轉移等功能,這有利于處理大規模的訊息,
根據官方的經驗,通常訊息傳遞使用較低的吞吐量,但可能要求較低的端到端延遲,kafka 提供強大的持久性來滿足這一要求,在這方面,Kafka 可以與傳統的訊息傳遞系統(ActiveMQ 和 RabbitMQ)相媲美,
4.2 Kafka應用場景:跟蹤網站活動
kafka 的最初始作用就是是將用戶活動跟蹤管道重建為一組實時發布-訂閱源, 把網站活動(瀏覽網頁、搜索或其他的用戶操作)發布到中心 topic,其中每個活動型別有一個 topic, 這些訂閱源提供一系列用例,包括實時處理、實時監視、對加載到Hadoop或離線資料倉庫系統的資料進行離線處理和報告等,
每個用戶瀏覽網頁時都生成了許多活動資訊,因此活動跟蹤的資料量通常非常大,這就非常使用使用 kafka,
4.3 Kafka應用場景:日志聚合
許多人使用 kafka來替代日志聚合解決方案,日志聚合系統通常從服務器收集物理日志檔案,并將其置于一個中心系統(可能是檔案服務器或HDFS)進行處理,
kafka 從這些日志檔案中提取資訊,并將其抽象為一個更加清晰的訊息流, 這樣可以實作更低的延遲處理且易于支持多個資料源及分布式資料的消耗,
與 Scribe 或 Flume 等以日志為中心的系統相比,Kafka具備同樣出色的性能、更強的耐用性(因為復制功能)和更低的端到端延遲,
4.4 Kafka應用場景:流處理
從0.10.0.0開始,kafka 支持輕量,但功能強大的流處理,
kafka訊息處理包含多個階段,其中原始輸入資料是從kafka主題消費的,然后匯總,豐富,或者以其他的方式處理轉化為新主題以供進一步消費或后續處理,
例如,一個推薦新聞文章,文章內容可能從“articles”主題獲取;然后進一步處理內容,得到一個處理后的新內容,最后推薦給用戶,這種處理是基于單個主題的實時資料流,
除了Kafka Streams,還有 Apache Storm 和 Apache Samza 也是不錯的流處理框架,
4.5 Kafka應用場景:事件采集
Event sourcing是一種應用程式設計風格,按時間來記錄狀態的更改, Kafka 可以存盤非常多的日志資料,為基于 event sourcing 的應用程式提供強有力的支持,
4.6 Kafka應用場景:提交日志
kafka 可以從外部為分布式系統提供日志提交功能, 日志有助于記錄節點和行為間的資料,采用重新同步機制可以從失敗節點恢復資料, Kafka的日志壓縮 功能支持這一用法, 這一點與Apache BookKeeper 專案類似,
五、尾聲
本文主要介紹了kafka架構與應用場景,
天天打碼,天天進步!!
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/433389.html
標籤:其他
下一篇:京東、美的資料分析求職經驗
