天天看點

《apache kafka 實戰》讀書筆記<第一章 認識apache kafka><第二章 kafka發展曆史><第三章 kafka線上環境部署><第四章 producer開發><第五章 consumer開發><第六章 kafka 設計原理>

斷斷續續看了點書,寫個部落格記錄下,圖檔是百科找的,部落格内容都是我比較感興趣的,書裡很多内容都特别詳細,感興趣的可以去買來閱讀。

《apache kafka 實戰》讀書筆記<第一章 認識apache kafka><第二章 kafka發展曆史><第三章 kafka線上環境部署><第四章 producer開發><第五章 consumer開發><第六章 kafka 設計原理>

<第一章 認識apache kafka>

kafka核心功能?

高性能的消息發送與高性能的消息消費

消息引擎系統?

1.消息隊列模型,提供了點對點的消息傳遞方式

生産者釋出一條消息隻能被一個消費者消費

2.釋出/訂閱模型(kafka 引入消費者組來支援這種模型)

生成者釋出一條消息可以被多個消費者消費

kafka為什麼高吞吐,低延時?

1.持久化資料隻是将資料寫入到OS的頁緩存,由OS決定資料什麼時候寫入磁盤,頁緩存在記憶體中配置設定,寫入速度快,不直接與磁盤打交道,都交給了OS

2.寫入操作采用追加(append)方式,隻能在日志檔案啊末尾追加消息,順序寫磁盤速度快

3.消費者讀取消息時,會優先從頁緩存中讀取,"命中"的話直接網絡發送socket。大量使用頁緩存,"命中率"高。

基本術語?

1,消息:由消息頭部(CRC碼,時間戳,key長度,value長度等等),key,value組成,key用來對該條消息進行partition,決定該消息儲存在topic的哪個partition

2,topic:邏輯概念,代表一類消息,可以了解為;消息被生産者發送到的地方

3,partition:一個topic可以由一個或多個partition,單純地為了提升系統的吞吐量,做分布式用,每個partition有自己的唯一的下标,從0開始

4,offset:partition每條消息都有一個唯一的偏移量,從0開始遞增(與消費者維護的offset不一樣)

5,replica:副本,防止資料丢失,分為leader和follower,follower不響應用戶端的消息寫入和消息消費請求,隻是被動的向leader同步資料,一旦leader挂掉,從follower選舉出新leader

6.ISR:同步副本集合,kafka為每個partition動态的維護一個replica集合,隻有該集合中的replica才能被選舉成leader,正常情況下,partition所有的replica都在ISR中,當某些replica進度"落後"leader大于某個值時,會被提出ISR,當重新追上時,會再次加入到ISR中

<第二章 kafka發展曆史>

kafka版本遷移?

版本 功能變化 說明
0.8 增加了備份機制 使kafka成為分布式消息引擎解決方案
0.9.x 使用java重寫了consumer 消費者組的offset可以不用通過zk儲存,存在topic中
0.10.x 增加了kafka streams元件 增加流式資料處理功能
0.11.x 增加了對事務的支援以及精準一次處理語義 正式支援Exactly-Once

0.9.x版本的producer?

将待發送的消息封裝成一個ProducerRecord對象,然後使用KafkaProducer.send()進行發送,KafkaProducer拿到消息後,先對其進行序列化,然後根據中繼資料資訊确定目标分區,最後寫入記憶體緩沖區,同時,KafkaProducer還有一個專門的Sender I/O線程,負責将緩沖區資料分批次發給broker。

producer較舊版本優點?

1,發送過程分為兩個線程,一個主線程和Sender I/O線程

2,完全異步發送,回調機制用來判斷發送是否成功

3,分批次發送,提高吞吐量

4,更合理的分區政策,舊版本對于沒key的消息,會發送到固定分區,0.9.x采用輪詢方式

0.9.x版本的consumer?

消費者組的offset不依賴于zk舊版,大量的zk I/O會成為系統瓶頸,将消息封裝到ConsumerRecord對象,然後使用KafkaConsumer.poll()進行拉取資料,

consumer較舊版本優點?

1.,摒棄了消費不同分區時采用多線程的思想,隻使用一個線程可以管理不同broker的多個socket

2,擺脫了offset對zk的依賴

<第三章 kafka線上環境部署>

暫時還不知道寫啥。

<第四章 producer開發>

暫時還不知道寫啥。

<第五章 consumer開發>

暫時還不知道寫啥。

<第六章 kafka 設計原理>

一.broker端設計

1.副本與ISR

隻有leader副本對外提供服務,而其它follower副本隻是被動地向leader副本同步資料

ISR,為partition動态維護的同步副本集合,leader副本也在ISR中,隻有ISR中的副本可以選舉leader

《apache kafka 實戰》讀書筆記&lt;第一章 認識apache kafka&gt;&lt;第二章 kafka發展曆史&gt;&lt;第三章 kafka線上環境部署&gt;&lt;第四章 producer開發&gt;&lt;第五章 consumer開發&gt;&lt;第六章 kafka 設計原理&gt;

High watermark,高水印值,超過該值的消息被視為“未送出成功”的,決定了consumer能夠擷取到的消息最大offset

uncommitted,未送出的消息,表示producer已發送到leader副本,而ISR中别的副本還未全部同步,也表示還未給用戶端發response的消息

log end offset,日志末端位移,LEO,該值表示的位置是下一條消息要寫入的位置

當leader副本接收到消息時,先更新自己的LEO,然後followe副本向leader副本請求資料後也更新follower的LEO,隻有ISR的所有副本更新了自己LEO後,leader副本才将HW值向右移動,後給用戶端發送寫入成功。

ISR副本中什麼原因導緻follower被"踢出"該隊列?

1.follower副本請求速度跟不上leader的接收速度

2.follower由于某些原因(GC等),一段時間内未向leader請求資料                                                                                                3.新增的副本

0.9.x版本之前對于ISR設定?

replica.lag.max.messages,該值檢測如果LEO落後消息數達到該值被踢出

replica.lag.time.max.ms,該值用于檢測如果follower副本多長時間以内未向leader請求資料,則被踢出

0.9.x版本之後對于ISR設定?

replica.lag.time.max.ms,該值預設10s,如果follower副本落後leader副本持續時間超過該值,被踢出

2.水印和LEO

如果把LEO和HW看作兩個指針,它們的定位是不同的,任意時刻,HW指向是實實在在的消息,而LEO總是指向下一條待寫入的消息的,也就是說LEO指向的位置是沒有的消息的,上面那張圖則表示為:HW為7,LEO為15,則消費者可消費的消息數為0-7 8條消息,而8-14是生産者已送出leader,而ISR集合别的follower還未全部請求的資料。

LEO更新機制?

1. follower副本的LEO更新機制?

follower副本的LEO屬性,一份儲存在leader副本所在的broker,另一份儲存在follower副本所在的broker,為什麼儲存兩份?kafka需要利用前者來确定leader副本的HW值,利用後者來幫助follower副本更新HW值

儲存在follower副本所在broker的follower副本LEO更新時機?

當follower副本向leader副本請求資料後,向底層log寫資料時,更新其LEO值

儲存在leader副本所在broker的follower副本LEO更新時機?

當leader處理follower資料請求時,首先從log讀取資料,然後更新LEO值,再發資料給follower。

2. leader副本LEO更新時機?

當接收到producer發的消息時,會更新自己的LEO

HW更新機制?

1.follower副本的HW更新時機?

follower副本更新LEO後,一旦寫完log資料,更新HW值,具體方法是:比較目前follower副本LEO值與剛請求資料時leader的HW值,取小值作為follower副本的HW值,也就是follower副本的HW值不會大于leader副本的HW值

2. leader副本的HW更新時機?

正常情況:producer向leader寫入資料時,更新完LEO後,檢視HW是否更新

leader處理完follower副本資料請求後,檢視HW是否更新

異常情況:某follower副本成為leader副本

某broker副本被踢出ISR時

具體方法:比較ISR中所有副本的LEO值(儲存在leader副本所在broker的follower副本LEO),取最小的值作為HW值

是以分區的HW實際上是所有ISR副本LEO的最小值