kafka 筆記

miss201發表於2019-01-09

AMQP

  • Advanced Message Queueing Protocol(高階訊息佇列協議)
  • 是一個標準開放的應用層的訊息中介軟體(Message Oriented Middleware)協議。
    AMQP定義了通過網路傳送的位元組流的資料格式。因此相容性非常好,
    任何實現AMQP協議的程式都可以和與AMQP協議相容的其他程式互動,可以很容易做到跨語言,跨平臺。

介紹:

  • apache kafka 是一個分散式流媒體平臺。
    • 功能:
    • 1.釋出和訂閱訊息流,類似於訊息佇列和企業級訊息系統。這也是kafka歸結為訊息佇列框架的原因。
    • 2.以容錯的方式來記錄訊息流,kafka以檔案的方式來儲存訊息流。
    • 3.可以在訊息釋出的時候進行處理。

使用場景:

  • 日誌收集:
  • 訊息佇列:解耦和生產者,消費者,訊息快取。
  • 使用者活動跟蹤
  • 運營指標:
  • 流式處理:
  • 事件源:

基本概念:

  • broker: kafka以整合的方式執行,可以有一個或者多個服務組成,每個服務就叫一個broker.
  • producer:往broker的topic中生產訊息。
  • consumer:往broker的某個topic中讀取訊息。
  • topic:kafka訊息的分類方式,每一類的訊息稱為一個topic。
  • partition:topic物理上的分組,一個topic可以分為多個partition。
  • replication: 副本partition的備份,保證partition的高可用。
  • segment: partition物理上由多個segment組成。
  • message:也叫record,是有一個key, value和時間戳組成的。
  • controller:負責管理分割槽和副本的狀態並執行,以及這些分割槽的重新分配。
  • ISR:同步副本組
  • leader:replication的一個角色,producer和consumer只跟leader進行互動。
  • follower:replication的一個角色,從leader中複製資料。
  • controller:kafka叢集中的一個broker,用來進行leader選舉以及各種failover
  • zookeeper:kafka 通過 zookeeper 來儲存叢集的 meta 資訊。

設計思想:

broker controller

  • 在早期的版本中,對於分割槽和副本的狀態管理依賴於zookeeper的watcher和佇列。每一個broker都會在zookeeper註冊Watcher。
    所以,就會出現大量的watcher,如果當機的broker上的partition比較多,會造成多個watcher的觸發,造成叢集內大規模的調整。
    每一個replica都要去再次zookeeper上註冊監視器,當叢集規模很大的時候,zookeeper負擔很重。
    這種設計很容易出現腦裂和羊群效應以及zookeeper叢集過載。
  • 新版本該變了這種設計,使用KafkaController。
    Leader會向zookeeper上註冊Watcher,其他broker幾乎不用監聽zookeeper的狀態變化。
  • 當broker啟動時,都會建立broker controller,但是叢集中只有一個broker controller對外提供服務。
    這些每個節點上的KafkaController會在指定的zookeeper路徑下建立臨時節點,
    只有第一個成功建立的節點的KafkaController才可以成為leader,其餘的都是follower。
    當leader故障後,所有的follower會收到通知,再次競爭在該路徑下建立節點從而選舉新的leader
  • Kafka叢集中多個broker,有一個會被選舉為controller leader,負責管理整個叢集中分割槽和副本的狀態,
    比如partition的leader 副本故障,由controller 負責為該partition重新選舉新的leader 副本;
    當檢測到ISR列表發生變化,有controller通知叢集中所有broker更新其MetadataCache資訊;
    或者增加某個topic分割槽的時候也會由controller管理分割槽的重新分配工作

    producer生產訊息:

    • 1.producer採用push模式講訊息傳送到broker,每條訊息都被append到partition中,屬於順序寫磁碟。
      (順序寫入的效率比隨機寫入的效率要高,保障kafka的吞吐率。)
    • 2.訊息傳送到broker時,會根據分割槽演算法選擇將其儲存到哪一個 partition。
      • 其演算法為
      • 2.1 指定了partition,則直接使用
      • 2.2 沒有指定partition,指定了key,則使用key的value,進行hash取餘選出一個partition.
      • 2.3 key和partition都沒有指定,就採用輪詢的方法選出一個partition.
    • 3.kafka接收到proucer傳送過來的訊息之後,將其持久化到硬碟,並設定保留訊息的時長。不關注訊息是否被消費者消費。
    • 4.consumer從kafka叢集中pull資料,並記錄offset。

訊息寫入的流程:

  • producer從zk的"/brokers/.../state"節點找到partition對應的leader
  • producer把訊息傳送給對應的leader
  • leader把訊息寫入本地log
  • followers從leader處pull訊息,寫入本地log後,向leader傳送ACK。
  • leader收到所有ISR中的replica的ACK後,增加 HW(high watermark,最後 commit 的 offset) 並向 producer 傳送 ACK
    file

    producers的引數acks設定

    request.required.acks:

    • 0:producer不會等待broker傳送ack
    • 1:在leader已經接收到資料後,producer會得到一個ack
    • -1:所有的ISR都接收到資料後,producer才得到一個ack

topic

topic的註冊流程

  • controller在ZK的/brokers/topics節點上註冊watcher.當topic被建立時,controller會通過watcher得到該
    topic的partition和replica的分配情況。
  • controller從/brokers/ids中讀取當前可用的broker列表。對於set_p中的每一個partition.
    • 從分配給該 partition 的所有 replica(稱為AR)中任選一個可用的 broker 作為新的 leader,並將AR設定為新的 ISR
    • 將新的 leader 和 ISR 寫入 /brokers/topics/[topic]/partitions/[partition]/state
    • controller 通過 RPC 向相關的 broker 傳送 LeaderAndISRRequest。

consumer

consumer group

  • 是kafka提供的可擴充套件的具有容錯性的消費機制。
  • 組內有多個消費者或者消費者例項,共享一個group id.
  • 組內所有的消費者協調在一起來消費訂閱的topic中的所有分割槽。
  • 每一個分割槽只能由一個組內的一個消費者消費。其他的組也可以訂閱同一個topic.

rebalance

  • 其本質是一種協議,規定了consumer group下所有的consumer如何達成一致來分配訂閱topic的每個分割槽。
  • 什麼時候觸發:
    • 1.當消費組中的consumer發生變化時,(新consumer加入,有consumer主動離開,consumer崩潰)
    • 2.訂閱的主題數發生變更
    • 3.主題的分割槽數發生變化
  • 兩種策略:
    • range:將消費者的執行緒總數除以分割槽個數,如果有餘數。那麼前面幾個消費者將會多消費幾個分割槽。
      例如:一個topic有10個分割槽,有3個消費執行緒,那消費者分配的分割槽就是:
      • C1-0 將消費 0, 1, 2, 3 分割槽
      • C2-0 將消費 4, 5, 6 分割槽
      • C2-1 將消費 7, 8, 9 分割槽
    • roundrobin:

關於partition

  • 一個partition只能被同組的一個consumer消費。同組的其他的consumer起到負載的作用。
  • 可以被多個消費組消費。即一個訊息被消費多次。
  • 一個topic中partition的數量,是userGroup的最大並行數量。

    負載均衡

    • kafka叢集中的任何一個broker,都可以向producer提供metadata資訊,
      這些metadata中包含"叢集中存活的servers列表"/"partitions leader列表"等資訊。
      當producer獲取到metadata資訊之後, producer將會和Topic下所有partition leader保持socket連線;
      訊息由producer直接通過socket傳送到broker,中間不會經過任何"路由層".

    • 非同步傳送,將多條訊息暫且在客戶端buffer起來,並將他們批量傳送到broker;
      小資料IO太多,會拖慢整體的網路延遲,批量延遲傳送事實上提升了網路效率;
      不過這也有一定的隱患,比如當producer失效時,那些尚未傳送的訊息將會丟失。

關於 leader election演算法

  • 本質上是一個分散式鎖,有兩種方式實現基於ZK的分散式鎖
    • 1.節點名稱唯一性:多個客戶端建立一個臨時節點,建立成功的客戶端獲得鎖。
    • 2.臨時順序節點:所有客戶端在某個目錄下建立一個臨時節點,序號最小的那個獲得鎖。

不卑不亢,不慌不忙,這才是生活的模樣。

相關文章