kafka原理學習

kafka:分佈式,支持分區,多副本的,基於zk協調的分佈式消息系統。
特性:高吞吐,低延遲 每秒可以處理幾十萬條消息 延遲級別在毫秒級。每個topic可以分爲多個partition,consumer group 可以對partition進行消費
可擴展性:支持熱擴展
容錯性:允許集羣中節點失敗(若副本個數爲n,則允許n-1個節點失敗
高併發:允許數千個用戶同時進行讀寫

應用場景:
日誌收集:收集各種服務的log,通過kafka以統一接口的方法開放給各種consumer.如hadoop Hbase sorl
消息系統:解耦生產者和消費者,緩存消息
流式處理:sparkStreaming 和storm
用戶活動跟蹤:記錄web用戶或者app用戶的各種活動,如瀏覽網頁,搜索,點擊等活動,這些活動
信息被各個服務器發佈到不同的topic中,通過訂閱這些topic來做實時監控分析。或者到hadoop做離線分析和數據挖掘

設計思想:
kafka broker被zookeeper管理。
1.所有的kafka broker節點會都去zk上註冊一個臨時節點,但是隻有一個能成功,成功的那個就成爲了kafka broker Controller 這個過程叫做:Controller在ZK註冊Watch.
2.Controller會監聽其他的broker的信息,如果controller宕機了,在zk上的臨時節點會消失,此時所有的
broker再次去註冊臨時節點,再次推選出Controller。還會負責分區首領的選舉
3.當一個broker宕機的時候,Controller會讀取該宕機broker上的所有partition在zk上的狀態,並選取ISR列表中的
一個replica作爲partition leader。如果ISR的全掛了,就會選取一個倖存的replica作爲leader。如果該partition的所有
replica都掛了,則將新的leader設置爲-1,等待恢復,當ISR中的任一個replica復活過來,並且選它爲leader.

consumerGroup:
1.一個parition內每個message只能被組內的一個consumer消費。如果一個partition的message被多個
consumer消費的話,那麼它們肯定是在不同的組。
注意:多個consumer的消費必須是順序讀取partition中的數據。新啓動默認從隊列的最頭端最新的地方開始阻塞的讀取。
2.如果覺得效率不高的話可以增加partition的個數橫向擴展,然後增加consumergroup個數。最佳的設計就是:consumer group下的consumer個數與partition個數一致
Consumer: 處理partition裏面的message是順序讀取的,所以需要維護上一次的offset信息。
high level api,offset維護在zk中。先拿message處理,在定時自動commit,offset+1.當message處理成功後線程掛掉,還沒commit offset+1,
重啓後就會重複消費這個message。
low level api,offset由自己維護。
3.一般情況都是一個consumer group 處理一個topic的message。最佳方案就是consumer個數等於partition個數
4.線上的分佈式多個service服務,每個service裏面的kafka consumer數量都應該小於topic的partition數量,但是所有的
服務的consumer數量之和應該等於partition的個數,因爲分佈式服務的所有consumer都來自一個consumer group.如果來自
不同的group,就會造成重複消費數據。一般情況都是兩個不同的業務邏輯,纔會啓動兩個group來消費一個topic.

Producer:
producer先將message發送到partition leader, 在有partition leader 發送到follower
發送方式:異步發送,同步發送
消息投遞的可靠性:ack機制 -1/all 就是leader和follower 0 不等待 1 等待leader
1.如何處理某個replica不工作的情況:如果這個replica不在ISR列表中,就是message發送到leader,leader發送給follower但是沒有響應,不會影響這個系統
如果在ISR列表中,leader會一直等待到timeout,返回失敗,將這個replica從ISR中剔除。
2.怎麼處理failed replica恢復過來的情況:如果不在ISR列表中,啓動後重新接受zk的管理即可。如果在的話,需要手動
添加到ISR列表中。
producer端的消息投遞保證:
at least once 至少一次 數據可能會重複,但是不會丟失 (默認)
at most once 至多一次 數據可能會丟失,但不會重複 | 通過設置異步可以實現
at exactly once 精準一次 數據只被傳輸一次。|通過主鍵冪等性實現
生產者需要處理的錯誤包括兩部分:一部分是生產者可以自動處理的錯誤,一部分是需要手動處理的錯誤
錯誤可以通過重試來解決 生產者自動處理這些錯誤。LEADER_NOT_AVAILABLE 剛好遇到正在選舉首領
但是會存在存入重複的信息。現實中在消息中加入唯一標識符,用於檢測重複消息。還可以做到消息的冪等性。
不可重試錯誤 INVALID_CONFIG

kafka判斷一個節點是否存活需要有兩個條件:
1.節點必須可以維護和zk的連接。心跳機制
2.如果節點事follower,他必須能及時的同步leader的數據,延時不能太久

在partition中如何通過offset查找message?
1.查找segment file .index最開始的文件 以起始偏移量0開始,第二個文件命名方式爲第一個文件的最大偏移量,則第二個
文件的消息的起始偏移量爲 名字+1.使用二分法查找,就可以快速定位到具體文件segment。
2.通過對應的log順序查找。

kafka的消息都是kv類型。當k爲null時,分區器採用了輪詢的方式。不爲null時採用key.hash%分區數

提交偏移量:
自動提交:enable.auto.commit=true 默認5s 問題:當在5s內觸發了再均衡的話,會造成數據重複消費
手動提交:
同步提交:commitSync() 處理完所有記錄後調用。
在broker對提交請求做出迴應之前,應用程序會一直堵塞,會限制吞吐量。可以降低提交頻率但是會增加重複消費的數量
如果發生了再均衡,從最近一批消息到再均衡之間的所有消息都被重複處理
異步提交:commitAsync():無需等待broker的響應。

消費者只能看到已經複製到ISR的消息。高水位

消費者做到 exactly once最簡單最常用的方法就是將結果存儲到支持唯一鍵的系統裏。在這種情況下,
要麼消息本身包含一個唯一鍵,要麼使用主題分區偏移量組合來創建一個唯一鍵。還可以使用事務機制

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章