Kafka設計原理,為什麼Kafka性能高?如何保證Kafka不丟消息?

分佈式消息中間件

作用:

1. 解耦(同步調用是一種強依賴,而異步調用是一種弱依賴);

2. 削峰填谷;

3. 降低響應時間;

4. 提升吞吐量(Kafka 的吞吐量是MySQL 吞吐量的30-40倍,並且Kafka的擴展性遠高於MySQL);

Kafka 的設計原理

Kafka 是一個分佈式消息中間件,但是它並不符合JMS 規範,即使消息已經被消費,也不會被馬上刪除,當消息保留一定時間後,會被批量刪除。

在Kafka 中,消息被持久化到磁盤上,因此Kafka 堆積消息的能力非常強大。

Kafka 依賴於 Zookeeper 管理元數據。

Kafka 架構圖

Kafka設計原理,為什麼Kafka性能高?如何保證Kafka不丟消息?

Broker

Kafka的服務端,負責接收數據,並持久化數據,Broker 可以有多個,每個Broker 可以包含多個 Topic,Broker 並不保存 Offset(消費者消費的位置)數據,由 Consumer 自己負責保存,默認保存在 ZooKeeper 中。

Producer 生產者

生產數據發送到Broker 存儲數據。Producer 直連 Broker,不經過任何代理,Producer 將會和 Topic 下所有 Partition Leader 保持 Socket 連接。通常 Producer 是一個包含 Kafka客戶端的業務服務。

Consumer 消費者

業務服務從 Broker 訂閱Topic,並從 Topic 中接收數據。

每個消費者都屬於某個消費者組,一個組裡的消費者訂閱的是同一個Topic,同一個組的消費者分別訂閱同一個 Topic下的不同 Partition 的數據。

需要注意的是,每個 Partition 只能被一個消費者訂閱,一個消費者可以訂閱多個 Partition,用這種方式避免一定的重複消費。

當一個消費者掛掉之後,會重新進行負載均衡。

Topic 主題

相當於數據庫找那個的表名,生產者和消費者之間通過 Topic 建立對應關係。

Topic 更像一個邏輯概念,每個 Topic 下包含了多個 Partition,所有元數據都存儲在 ZooKeeper 中。

Partition 分區

Kafka 為了擴展性,提升性能,可以將一個 Topic 拆分為多個分區,每個分區可以獨立放到一個 Broker 中。

ZooKeeper

Kafka將元數據信息保存在Zookeeper中,但是發送給Topic本身的數據是不會發到ZooKeeper上。

Kafka 使用Zookeeper來實現動態的集群擴展,不需要更改客戶端(producer和consumer)的配置。Broker會在Zookeeper註冊並保持相關的元數據(topic,partition信息等)更新。

而客戶端會在Zookeeper上註冊相關的watcher。一旦zookeeper發生變化,客戶端能及時感知並作出相應調整。這樣就保證了添加或去除Broker時,各Broker間仍能自動實現負載均衡。

這裡的客戶端指的是Kafka的消息生產端(Producer)和消息消費端(Consumer)。Producer端使用Zookeeper用來"發現"broker列表,以及和Topic下每個partition的Leader建立socket連接併發送消息。也就是說每個Topic的partition是由Leader角色的Broker端使用Zookeeper來註冊Broker信息,以及監測partition leader存活性。Consumer端使用Zookeeper用來註冊Consumer信息,其中包括Consumer 消費的partition列表等,同時也用來發現broker列表,並和partition leader建立socket連接,並獲取消息。

ZooKeeper 在Kafka 集群中承擔的作用

  • Zookeeper管理著Kafka集群中的若干個Broker,保存著一份完整的Broker列表。
  • 維護Topic信息,比如Partitions、Replication Factor、ISR(In-sync Replica)等。
  • Zookeeper幫助選舉Partition的Leader。
  • 當有任何變動時,由Zookeeper給Kafka發送通知,比如添加一個新的Topic、Broker掛掉了、刪除Topic等等。
  • Zookeeper集群中也有Leader和Follower的概念。Leader負責寫數據,Follower負責讀數據.
  • 存儲Kafka集群ID。
  • 存儲訪問控制列表(ACL,Access Control List)。控制Topic、Consumer Group、User等訪問權限。
Kafka設計原理,為什麼Kafka性能高?如何保證Kafka不丟消息?

為什麼 Kafka 性能高?

  • 順序寫磁盤,媲美內存隨機訪問的性能。

順序寫磁盤的性能是隨機寫入的性能的6000倍的提升,磁盤不再是瓶頸點。

  • 零拷貝技術,減少上下文切換和拷貝次數。

如何保證Kafka 不丟消息?

1. ACK 機制

通過 ACK 機制保證消息送達。Kafka 採用的是至少一次(At least once),消息不會丟,但是可能會重複傳輸。

2. 複製機制

Kafka 保證可靠性依賴的是複製機制,因為單機容易出現故障。Kafka 以Topic 為單位進行設置複製因子,以 Partition 為單位進行復制,允許一份數據複製到集群中的多個節點上。通過複製,Kafka 在Broker 集群中的部分節點掛掉的情況下,仍然可以繼續發送和接收消息。

Kafka設計原理,為什麼Kafka性能高?如何保證Kafka不丟消息?

3. 消息刪除機制

Broker 端刪除消息有一個配置策略,默認是7天,如果7天消息還沒有消費,則有可能被刪除,也就是丟消息了。

4. 發送消息

為了得到更好的性能,Kafka 支持在生產者一側進行本地buffer,也就是累積到一定的條數才發送,如果這裡設置不當是會丟消息的。

生產者端設置 producer.type=async, sync,默認是 sync。

當設置為 async,會大幅提升性能,因為生產者會在本地緩衝消息,並適時批量發送。

如果對可靠性要求高,那麼這裡可以設置為 sync 同步發送。

5. 消費消息

如果更注重可靠性,則需要顯示提交 Offset,也就是當所有業務都處理完成的時候,再提交 Offset。這樣會導致重複消費,需要提供冪等性接口。


分享到:


相關文章: