斷斷續續看了點書,寫個部落格記錄下,圖檔是百科找的,部落格内容都是我比較感興趣的,書裡很多内容都特别詳細,感興趣的可以去買來閱讀。
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiAzNfRHLGZkRGZkRfJ3bs92YsYTMfVmepNHL9ElaNdXRUN2c5cVWvB3MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnL2AjM1QzNxcTM0AjMxgTMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
<第一章 認識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
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的最小值