Pull Request: https://github.com/apache/kafka/pull/16885
背景故事
Kafka Consumer 曾經帶給大家無數美好的時光,不管是 poll
之間間隔太久導致被踢出群組、又或是 close
忘了送 LEAVE_GROUP
的資訊、或者是 consumers 之間分到的流量異常不平均,這些各式各樣陰陽怪氣的 bugs 雖然腦人,但同時也成了我們與 kafka consumer 之間無法斬斷的羈絆。然而歲月始終無法靜好,天下無不散的宴席,Kafka consumer
終究會成為舊人,而我們就如故事裡那些無情的男人一樣,開始瞧著新 consumer 笑了 ...
沒錯,今天的背景故事就是由嶄新的 AsyncConsumer 作為開頭,而相信大家心理第一個跳出來的疑問就是 ... 爲何要有新的 consumer? 這原因說來複雜但其實也很簡單,就跟大家工作時會遇到的狀況一樣,既有的 Kafka consumer
(後面我們稱之為 classic consumer
) 真的真的真的太難維護了,經過十幾年各種修修補補來來去去,裡頭許多千絲萬縷已經越來越匪夷所思,所以這個理由大家一定都能接受,我們要重構我們要一個乾淨好維護的新 consumer,這其中也包含 protocol,也就是在新的 consumer 宇宙觀中我們會推出一個更高效好用的協定,細節有待日後說明
為了讓大家快速進入本隻題目,我們很快帶入兩個關鍵字,application thread
以及 background thread
,前者代表使用者操作 consumer
的執行緒、後者代表 consumer
內部偷偷啟動的執行緒負責請求的處理。平常呢 application thread
會把希望 background thread
幫忙的任務包裝成 event
,然後偷偷放到 background thread
的工作佇列中,然後等待 background thread
不辭辛勞的完成,然後再把結果帶回給使用者。這樣一來一往本來呢也是過得不錯日子風調雨順,但是阿人事間的事情哪有這麼簡單的呢?總有一些時候使用者需要的東西不是一個來回就能完成,例如當使用者要知道現在資料的位置 (offset) 的時候,這個要求需要兩個請求來完成:
那兩個步驟原本是誰在主導呢?當然就是我們的 application thread
主導整個流程,然而螢幕前聰明的工程師一定注意到一件事情,如果 background thread
在處理事情,然後 application thread
三五不時就去戳一下弄一下,會不會出現 race condition 導致資料不一致?答案是肯定的,因此我們就來要看看如何處理這個問題
解決辦法
正所謂思路正確問題清楚,那自然答案就很明顯了。在這次的 PR 裡面,我們重構了這段邏輯,把原本拆成兩個互動整合成一個互動,換言之,application thread 從此飯來張口茶來伸手,本來應該要主導的流程通通交給 background thread
去處理,background thread
自己去更新 leader 資訊把過時的資料清楚,然後自己再送下一個請求給 leader 把最新的資料位置資訊拿回來,通通處理完後在跪求 application thread
把這些資訊回傳給使用者
後續
AsyncConsumer 的誕生是為取代 classic consumer 成為大家的新歡,所以大家在使用的過程如果注意到任何問題,都非常歡迎來 Kafka 社群提出你的疑問!
廣告
歡迎訂閱全臺最鬆散的開源社群源來適你,上面不定期會有各種開源的廢文。也歡迎參加全臺最鬆散的開源討論頻道,上面有一群網友一起在刷開源技術