iT邦幫忙

2024 iThome 鐵人賽

DAY 20
0
Software Development

每天罵爆一隻 Kafka Pull Request系列 第 20

KAFKA-17674 Fix bug on update positions of newly added partitions

  • 分享至 

  • xImage
  •  

https://github.com/apache/kafka/pull/17342

背景故事

昨天的抒情廢文沒有半點技術內涵,我深刻反省。所以今天這篇回歸正題,來談一個跟Kafka使用者非常非常有關的題目!

大家有沒有用過Consumer的群組機制?如果沒有的話這裡很快介紹一下,Group機制目的是降低使用者在大量部署Consumer的痛苦,最有名的痛苦有兩個,首先是Consumer大量部署時要如何去分配任務、第二個就是Consumer開開關關後如何延續之前的進度?

針對第一個痛苦,Group機制會自動將任務分配給屬於同一個Group下的Consumers們,例如總共有partition_0partition_1兩個資料區段需要處理,此時Group內總共有兩個Consumer的話,那麼此機制就會讓兩個Consumer各自負責一個partition,和樂融融大家都有事情做。所以使用者可以很放心的在Group內加入更多Consumer,不用擔心會不會有人沒事做有人做太多,Group機制會努力的把事情分配好不讓人當薪水小偷。

那麼第二個痛苦呢?大量Consumer總是會有開開關關重開機升級的時刻,沒有人喜歡重複做同樣的工作、當然也沒人想要讀取重複的資料,Group機制自然體貼的會幫忙把各個partition的讀取紀錄保存下來,當consumer重啟後要來繼續拉取partition資料時,Group機制會先從伺服器端把上次的讀取進度找回來,然後Consumer就可以著讀取,就像是我們在串流電影一樣,電視看完移動到床上用平板接著看順暢舒服。

接著拉回今天的主題,Consumer實際上是如何找到上次的讀取紀錄呢?這裏給兩個關鍵字:OffsetFetchRequestListOffsetsRequest,是不是看到名字就立刻聯想到做法了?沒錯,小編這就來把各位讀者腦袋裡的想法描繪出來。

首先,Consumer會先送出OffsetFetchRequest來查詢上次的讀取進度,這句敲完大家是不是覺得那不就完事了嘛?怎麼還會需要ListOffsetsRequest?這是為了處理一個情境,這個情境叫做這個partition上完全沒有畫面紀錄,沒錯嘛,可能這是一個新的partition又或是上一個傢伙當薪水小偷都沒辦事,那這時候該怎麼辦?自然就是ListOffsetsRequest該出場了,Consumer會根據使用者的參數設定說當沒有記錄時要從哪裡開始讀取,可以從頭或是從最新等等,然後就會使用ListOffsetsRequest來把對應的紀錄拿回來,接著Consumer就可以開始上工了!

聽起來一切很美好吧?但是上述的流程其實可能會有一個問題,這個問題就是上述的流程其實需要與伺服器端至少來回兩次對話,如果在對話過程中要處理的partitions有變化該怎麼辦?舉個例子,一開始送OffsetFetchRequest的時候要查partition_0partition_1,然後等到ListOffsetsRequest要上場時這個Consumer要處理的partition突然多了一個partition_2那該怎麼辦?此時的partition_2一定沒有上次的讀取紀錄,難道我們就把它當成沒有記錄嘛?當然不行,這樣很可能會出現掉資料或是重複讀取的尷尬狀況 ...

解決辦法

既然知道問題的根源,那解決辦法其實也很簡單,那就是雖然不忍心但只好讓partition_2留到下次輪詢時再來處理,也就是說ListOffsetsRequest要處理的對象只會限定於OffsetFetchRequest處理過的partition,如果是在過程中突然加入的partition就會自動被排除在外,如此就可以避免Consumer設定不正確的讀取紀錄!

廣告

歡迎訂閱全臺最鬆散的開源社群源來適你,上面不定期會有各種開源的廢文。也歡迎參加全臺最鬆散的開源討論頻道,上面有一群網友一起在刷開源技術


上一篇
KAFKA-17613 Remove ZK migration code
下一篇
KAFKA-15908: Remove deprecated Consumer.poll(long timeout)
系列文
每天罵爆一隻 Kafka Pull Request30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言