Kafka系列詳解-基礎概念與核心設計(持續更新完善中)

核心概念

  • topic:對消息(message)歸類;例如,在網頁活動跟蹤中,每個活動種類(包括網頁瀏覽、搜索、點擊等)的消息都可以發佈到一個各自的topic中
  • Topic和Producer
    • 發佈給一個topic的消息可以在Kafka集羣中分割成多個 partition
    • 每個parititon都是一個log
    • log中的消息按發佈的順序排成一個消息列( message sequence )
    • Kafka不斷地向log的末尾寫入新的消息。
    • 每個partition中的消息都有一個在partition中唯一的ID,稱爲 offset,也就是相對log開頭的偏移量,Consumer在讀取消息的時候會記住當前消息的offset。
    • 通常簡單的由負載均衡機制隨機選擇分區,但也可以通過特定的分區函數選擇分區。使用的更多的是第二種
  • Consumer和Consumer Group(待理解)
  • Replication和Failover(待理解)
  • leader:負責處理消息的讀和寫,leader是從所有節點中隨機選擇的.負責處理消息的讀和寫,
  • followers則去複製leader.如果leader down了,followers中的一臺則會自動成爲leader。
  • 集羣中的每個服務都會同時扮演兩個角色:作爲它所持有的一部分分區的leader,同時作爲其他分區的followers,這樣集羣就會據有較好的負載均衡
  • replicas:列出了所有的副本節點,不管節點是否在服務中.
  • isr:是正在服務中的節點.
    • 必須選擇高質量的follower作爲leader.必須保證,一旦一個消息被提交了,但是leader down掉了,新選出的leader必須可以提供這條消息
    • Kafaka動態維護了一個同步狀態的副本的集合(a set of in-sync replicas),簡稱ISR,在這個集合中的節點都是和leader保持高度一致的,任何一條消息必須被這個集合中的每個節點讀取並追加到日誌中了,纔回通知外部這個消息已經被提交了
    • ISR中有f+1個節點,就可以允許在f個節點down掉的情況下不會丟失消息並正常提供服。ISR的成員是動態的,如果一個節點被淘汰了,當它重新達到“同步中”的狀態時,他可以重新加入ISR.這種leader的選擇方式是非常快速的,適合kafka的應用場景、
    • Kafka對於數據不會丟失的保證,是基於至少一個節點是存活的,一旦所有節點都down了,這個就不能保證了
    • 優化leader的選擇過程也是很重要的,它決定了系統發生故障時的空窗期有多久。Kafka選擇一個節點作爲“controller”,當發現有節點down掉的時候它負責在游泳分區的所有節點中選擇新的leader,這使得Kafka可以批量的高效的管理所有分區節點的主從關係。如果controller down掉了,活着的節點中的一個會備切換爲新的controller.
  • offset
    • offset有consumer來維護:一般情況下隨着consumer不斷的讀取消息,這offset的值不斷增加,但其實consumer可以以任意的順序讀取消息,比如它可以將offset設置成爲一箇舊的值來重讀之前的消息
    • 使Kafka consumers非常的輕量級:它們可以在不對集羣和其他consumer造成影響的情況下讀取消息。你可以使用命令行來"tail"消息而不會對其他正在消費消息的consumer造成影響
    • 將日誌分區可以達到以下目的:首先這使得每個日誌的數量不會太大,可以在單個服務上保存。另外每個分區可以單獨發佈和消費,爲併發操作topic提供了一種可能。

設計

  • 每個partition在存儲層面是append log文件。任何發佈到此partition的消息都會被直接追加到log文件的尾部,每條消息在文件中的位置稱爲offset(偏移量),offset爲一個long型數字,它是唯一標記一條消息。它唯一的標記一條消息。kafka並沒有提供其他額外的索引機制來存儲offset,因爲在kafka中幾乎不允許對消息進行“隨機讀寫”
  • 事實上consumer可以使用任意順序消費消息,它只需要將offset重置爲任意值..(offset將會保存在zookeeper中
  • kafka集羣幾乎不需要維護任何consumer和producer狀態信息,這些信息有zookeeper保存;因此producer和consumer的客戶端實現非常輕量級,它們可以隨意離開,而不會對集羣造成額外的影響
  • partitions的設計目的有多個.最根本原因是kafka基於文件存儲.通過分區,可以將日誌內容分散到多個server上,來避免文件尺寸達到單機磁盤的上限,每個partiton都會被當前server(kafka實例)保存;可以將一個topic切分多任意多個partitions,來消息保存/消費的效率.此外越多的partitions意味着可以容納更多的consumer,有效提升併發消費的能力
  • 如果producer發佈消息時發生了網絡錯誤,但又不確定實在提交之前發生的還是提交之後發生的,這種情況雖然不常見,但是必須考慮進去,現在Kafka版本還沒有解決這個問題,將來的版本正在努力嘗試解決。
  • 所有的副本都有相同的日誌文件和相同的offset,consumer維護自己消費的消息的offset,如果consumer不會崩潰當然可以在內存中保存這個值,當然誰也不能保證這點。如果consumer崩潰了,會有另外一個consumer接着消費消息,它需要從一個合適的offset繼續處理。
  • Producer消息發送
    • producer直接將數據發送到broker的leader(主節點),不需要在多個節點進行分發。爲了幫助producer做到這點,所有的Kafka節點都可以及時的告知:哪些節點是活動的,目標topic目標分區的leader在哪。這樣producer就可以直接將消息發送到目的地了
    • 客戶端控制消息將被分發到哪個分區。可以通過負載均衡隨機的選擇,或者使用分區函數。Kafka允許用戶實現分區函數,指定分區的key,將消息hash到不同的分區上(當然有需要的話,也可以覆蓋這個分區函數自己實現邏輯).比如如果你指定的key是user id,那麼同一個用戶發送的消息都被髮送到同一個分區上。經過分區之後,consumer就可以有目的的消費某個分區的消息
    • 異步發送:批量發送可以很有效的提高發送效率。Kafka producer的異步發送模式允許進行批量發送,先將消息緩存在內存中,然後一次請求批量發送出去。這個策略可以配置的,比如可以指定緩存的消息達到某個量的時候就發出去,或者緩存了固定的時間後就發送出去(比如100條消息就發送,或者每5秒發送一次)。這種策略將大大減少服務端的I/O次數
    • Kafka採用了不同的策略。Topic被分成了若干分區,每個分區在同一時間只被一個consumer消費。這意味着每個分區被消費的消息在日誌中的位置僅僅是一個簡單的整數:offset。這樣就很容易標記每個分區消費狀態就很容易了,僅僅需要一個整數而已。這樣消費狀態的跟蹤就很簡單了
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章