一. Kafka 的元素,組成,架構
1.1 Kafka 的基本組成
Kafka將消息以topic爲單位進行歸納
將向Kafka topic發佈消息的程序成爲producers.
將預訂topics並消費消息的程序成爲consumer.
Kafka以集羣的方式運行,可以由一個或多個服務組成,每個服務叫做一個broker.
producers通過網絡將消息發送到Kafka集羣,集羣向消費者提供消息
1.2 Kafka 分區的 HW, LEO
HW (High Watermark),高水位,它標識了一個特定的消息偏移量,消費者只能拉取到這個 offset 之前的消息。HW 是針對於分區的概念,對消費者而言,只能消費 HW 之前的消息。
LEO (Log End Offset),待寫入日誌偏移量,它標識了當前日誌文件中下一條待寫入的消息的 offset。LEO 是針對於ISR 集合中分區副本的概念,ISR 集合中每個分區的副本都會維護自身的 LEO。此外,ISR 集合中最小的 LEO,即爲分區的 HW。
上圖表示一個日誌分區副本文件,這個日誌分區副本文件中只有 9 條消息,第一條消息的 offset 爲 0,最右一條消息的 offset 爲8。offset 爲 9 的消息使用虛線表示的,代表下一條待寫入的消息。
日誌分區副本文件的 HW 爲 6,表示消費者只能拉取 offset 在 0 到 5 之間的消息,offset 爲 6 的消息對消費者而言是不可見的。
上圖中 offset 爲 9 的位置即爲當前日誌分區副本文件的 LEO,LEO 的大小相當於當前日誌分區副本中,最後一條消息的 offset + 1。
下面具體分析一下 ISR 集合和 HW、LEO的關係。
如下圖所示,假設某分區的 ISR 集合中有 3 個副本,即一個 leader 副本和 2 個 follower 副本,此時分區的 LEO 和 HW 都分別爲 3 。消息 3 和消息 4 從生產者出發之後,先被存入 leader 副本。在消息被寫入 leader 副本之後,follower 副本會發送拉取請求來拉取消息 3 和消息 4 進行消息同步。
在同步過程中不同的副本同步的效率不盡相同,如下圖所示。在某一時刻 follower1 完全跟上了 leader 副本而 follower2 只同步了消息 3,如此 leader 副本的 LEO 爲 5,follower1 的 LEO 爲 5,follower2 的LEO 爲 4。當前分區的 HW 取 ISR 集合中 LEO 的最小值,即當前分區的 HW 爲 4,即消費者可以消費到 offset0 至 3 之間的消息。
當所有副本都成功寫入消息 3 和消息 4 之後,整個分區的 HW 和 LEO 都變爲 5,因此消費者可以消費到 offset 爲 4 的消息了。圖略。
由此可見 kafka 的複製機制既不是完全的同步複製,也不是單純的異步複製。事實上,同步複製要求所有能工作的 follower 副本都複製完,這條消息纔會被確認已成功提交,這種複製方式極大的影響了性能。而在異步複製的方式下,follower 副本異步的從 leader 副本中複製數據,數據只要被 leader 副本寫入,就會被認爲已經成功提交。在這種情況下,如果 follower 副本都還沒有複製完而落後於 leader 副本,然後 leader 副本宕機,則會造成數據丟失。
最終,kafka 使用這種 ISR 的方式有效的權衡了數據可靠性和性能之間的關係。