1.深入理解Kaffka:核心設計與實踐原理

1.Kafka之所以受到越來越多的青睞,與它所“扮演”的三大角色是分不開的:

· 消息系統:Kafka 和傳統的消息系統(也稱作消息中間件)都具備系統解耦、冗餘存儲、流量削峯、緩衝、異步通信、擴展性、可恢復性等功能。與此同時,Kafka 還提供了大多數消息系統難以實現的消息順序性保障及回溯消費的功能。

· 存儲系統:Kafka 把消息持久化到磁盤,相比於其他基於內存存儲的系統而言,有效地降低了數據丟失的風險。也正是得益於Kafka 的消息持久化功能和多副本機制,我們可以把Kafka作爲長期的數據存儲系統來使用,只需要把對應的數據保留策略設置爲“永久”或啓用主題的日誌壓縮功能即可。

· 流式處理平臺:Kafka 不僅爲每個流行的流式處理框架提供了可靠的數據來源,還提供了一個完整的流式處理類庫,比如窗口、連接、變換和聚合等各類操作

2.基本概念

一個典型的 Kafka 體系架構包括若干 Producer、若干 Broker、若干 Consumer,以及一個ZooKeeper集羣,如圖1-1所示。其中ZooKeeper是Kafka用來負責集羣元數據的管理、控制器的選舉等操作的。Producer將消息發送到Broker,Broker負責將收到的消息存儲到磁盤中,而Consumer負責從Broker訂閱並消費消息。

整個Kafka體系結構中引入了以下3個術語。

(1)Producer:生產者,也就是發送消息的一方。生產者負責創建消息,然後將其投遞到Kafka中。

(2)Consumer:消費者,也就是接收消息的一方。消費者連接到Kafka上並接收消息,進而進行相應的業務邏輯處理。

(3)Broker:服務代理節點。對於Kafka而言,Broker可以簡單地看作一個獨立的Kafka服務節點或Kafka服務實例。大多數情況下也可以將Broker看作一臺Kafka服務器,前提是這臺服務器上只部署了一個Kafka實例。一個或多個Broker組成了一個Kafka集羣。一般而言,我們更習慣使用首字母小寫的broker來表示服務代理節點

在Kafka中還有兩個特別重要的概念—主題(Topic)與分區(Partition)。Kafka中的消息以主題爲單位進行歸類,生產者負責將消息發送到特定的主題(發送到Kafka集羣中的每一條消息都要指定一個主題),而消費者負責訂閱主題並進行消費。主題是一個邏輯上的概念,它還可以細分爲多個分區,一個分區只屬於單個主題,很多時候也會把分區稱爲主題分區(Topic-Partition)。同一主題下的不同分區包含的消息是不同的,分區在存儲層面可以看作一個可追加的日誌(Log)文件,消息在被追加到分區日誌文件的時候都會分配一個特定的偏移量(offset)。offset是消息在分區中的唯一標識,Kafka通過它來保證消息在分區內的順序性,不過offset並不跨越分區,也就是說,Kafka保證的是分區有序而不是主題有序。

Kafka 爲分區引入了多副本(Replica)機制,通過增加副本數量可以提升容災能力。同一分區的不同副本中保存的是相同的消息(在同一時刻,副本之間並非完全一樣),副本之間是“一主多從”的關係,其中leader副本負責處理讀寫請求,follower副本只負責與leader副本的消息同步。副本處於不同的broker中,當leader副本出現故障時,從follower副本中重新選舉新的leader副本對外提供服務。Kafka通過多副本機制實現了故障的自動轉移,當Kafka集羣中某個broker失效時仍然能保證服務可用。很多時候follower副本中的消息相對leader副本而言會有一定的滯後。

 Kafka 消費端也具備一定的容災能力。Consumer 使用拉(Pull)模式從服務端拉取消息,並且保存消費的具體位置,當消費者宕機後恢復上線時可以根據之前保存的消費位置重新拉取需要的消息進行消費,這樣就不會造成消息丟失。

分區中的所有副本統稱爲AR(Assigned Replicas)。所有與leader副本保持一定程度同步的副本(包括leader副本在內)組成ISR(In-Sync Replicas),ISR集合是AR集合中的一個子集。消息會先發送到leader副本,然後follower副本才能從leader副本中拉取消息進行同步,同步期間內follower副本相對於leader副本而言會有一定程度的滯後。前面所說的“一定程度的同步”是指可忍受的滯後範圍,這個範圍可以通過參數進行配置。與leader副本同步滯後過多的副本(不包括leader副本)組成OSR(Out-of-Sync Replicas),由此可見,AR=ISR+OSR。在正常情況下,所有的 follower 副本都應該與 leader 副本保持一定程度的同步,即 AR=ISR,OSR集合爲空。

leader副本負責維護和跟蹤ISR集合中所有follower副本的滯後狀態,當follower副本落後太多或失效時,leader副本會把它從ISR集合中剔除。如果OSR集合中有follower副本“追上”了leader副本,那麼leader副本會把它從OSR集合轉移至ISR集合。默認情況下,當leader副本發生故障時,只有在ISR集合中的副本纔有資格被選舉爲新的leader,而在OSR集合中的副本則沒有任何機會(不過這個原則也可以通過修改相應的參數配置來改變)。

ISR與HW和LEO也有緊密的關係。HW是High Watermark的縮寫,俗稱高水位,它標識了一個特定的消息偏移量(offset),消費者只能拉取到這個offset之前的消息。如圖 1-4 所示,它代表一個日誌文件,這個日誌文件中有 9 條消息,第一條消息的offset(LogStartOffset)爲0,最後一條消息的offset爲8,offset爲9的消息用虛線框表示,代表下一條待寫入的消息。日誌文件的HW爲6,表示消費者只能拉取到offset在0至5之間的消息,而offset爲6的消息對消費者而言是不可見的。

LEO是Log End Offset的縮寫,它標識當前日誌文件中下一條待寫入消息的offset,圖1-4中offset爲9的位置即爲當前日誌文件的LEO,LEO的大小相當於當前日誌分區中最後一條消息的offset值加1。分區ISR集合中的每個副本都會維護自身的LEO,而ISR集合中最小的LEO即爲分區的HW,對消費者而言只能消費HW之前的消息。

爲了讓讀者更好地理解ISR集合,以及HW和LEO之間的關係,下面通過一個簡單的示例來進行相關的說明。

由此可見,Kafka 的複製機制既不是完全的同步複製,也不是單純的異步複製。事實上,同步複製要求所有能工作的 follower 副本都複製完,這條消息纔會被確認爲已成功提交,這種複製方式極大地影響了性能。而在異步複製方式下,follower副本異步地從leader副本中複製數據,數據只要被leader副本寫入就被認爲已經成功提交。在這種情況下,如果follower副本都還沒有複製完而落後於leader副本,突然leader副本宕機,則會造成數據丟失。Kafka使用的這種ISR的方式則有效地權衡了數據可靠性和性能之間的關係。


 

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