iT邦幫忙

2024 iThome 鐵人賽

DAY 12
0
Software Development

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

KAFKA-17540: Create floating tag on trunk for CI cache

  • 分享至 

  • xImage
  •  

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

背景故事

今天我們來聊聊 Kafka CI,參與過 Apache 專案的開發者都知道Apache基金會有自己的Infra團隊,維護例如Apache mail, Jenkinsgit server,而跟我們貢獻流程最有關聯的就是 Jenkins 也就是負責跑 CI 的地方,畢竟我們都需要 CI 來降低我們合併 PR 的罪惡感。

不過隨著時代演進,各種線上CI服務越來越成熟後,Jenkins也逐漸飄出厚重繁瑣的味道,尤其在一狗票Apache專案擠在上面後,Jenkins的穩定性也著實一言難盡,在這種天時地利都沒有的狀況下,自然Kafka社群也瀰漫著一股CI不合的味道。

「要不我們試試看其他家的CI?」「好啊!」

所以我們就開始一系列GitHub CI的搬遷測試,不過講到這裡大家可能會好奇,GitHub給的免費資源真的足夠支撐像Kafka如此龐大的開發能量嗎?這裡就要感謝 [GitHub 對於 Apache 基金會的支持](GitHub Actions Policy - Apache Infrastructure Website),但畢竟這個CI資源是有限制的,如果我們想要安全無虞的待在GitHub CI的身邊,那我們就要盡可能的節省CI資源,所以該怎麼做呢?

這時候就要提到GitHub cacheGradle cache的完美配合!GitHub cache 簡單來說我們可以在 GitHub workflows 的過程中保存一些資料,可以再下次需要的時候拿出來使用。很常見的用法就是把一些非常昂貴或是耗時而產生的檔案暫存下來,這樣下次流程就可以直接拿出來用,你賺到時間又省了錢,何樂而不為。

那麼什麼是Gradle cache呢?大家在開發的過程中一定有個想法,如果我只是改了一根毛,那有必要整個專案都重新建置嗎?除非你時間很多不然我們一般都希望只建置有變動的部分,這個想法非常合理,在Gradle的世界中稱之為incremental build,然而這個機制一般來說是限制在專案內,也就是隔壁的專案無法共享已經建置過的產出,換言之就很難配合GitHub cache,因為每個PR所觸發的CI都像是隔壁的專案,無法看到用到其他建置過程中產生的結果。Gradle cache採取不同的存放方式,那些要被快取的結果可以存在放專案以外的地方,例如放在使用者目錄下、又或是放在遠端機器上,如此就能在任何專案建置時去特地位置找到快取的資料來重複使用。

講到這裡,大家一定心理已經感受到這兩者搭配的組合拳,也就是我們可以把Gradle cache的內容透過GitHub cache存放下來,然後在每次PR的流程中把之前快取的內容從GitHub cache重新放到Gradle cache,如此不管哪個PR都可以享受到之前快取的產出,進而大幅度提高CI的速度(當然前提是你的PR的變動範圍不大,讓許多快取可以重複使用)

故事到這裡應該充滿幸福美滿了吧?很可惜開源不是童話世界,開發永遠有著特殊的狀況。我們需要去思考一個問題,如果開發者的PR是基於一個還沒建立快取的提交,這個時候會不會發生大量的快取失誤?

在講這個擔憂之前,還需要提一個快取的限制,那就是我們只會針對trunk分支上的提交來建立快取,為何要這樣做?原因有二,首先GitHub Cache是有大小限制,我們不可能也沒道理針對所有的提交建立快取,其二是快取的建立只有在該次提交的測試完成後才會建立,這樣做才能讓我們避免跑那些沒有被更動過的測試,也就是我們連測試結果也會放到快取!然而這樣做的副作用就是導致trunk被更新到快取建立完成會有一個時間差!如果開發者基於最新的提交來發PR,就有可能產生大量的快取失誤,因為最新的提交的快取還沒建立完成!

解決辦法

既然知道根本原因了,解決辦法自然就是鼓勵開發者用已經建立好快取的提交來開發PR,但接下來的問題就是我們要如何讓開發者可以很輕鬆地做到這件事情?開發者要如何知道哪個提交是已經有快取?

原本社群一開始的做法是傾向建立一個trunk-cached的特別分支,該分支的推進只會基於快取成功後的提交,所以開發者就可以基於該分支來看PR,因為該分支上的每個提交都保證是有快取,當然如果GitHub cache滿了,那就會有一些舊的快取被刪掉

但是這個做法會需要額外的流程來更新trunk-cached,進而讓我們已經有些複雜的流程更加複雜。所以筆者提出了另一個做法,透過GitHub cache API來查詢最新的快取,開發者則可以透過Git指令把PR推進到該快取對應的提交,如此我們就不需要額外的分支,也不需要額外的流程來維護

後續

上面長篇大論後,大家應該注意到一件事情,我們要如何強迫開發者來遵守規則?事實上還真的不行,以社群的立場我們會把這件事情寫在PR的規範中,並且把乖乖遵守能獲得的好處用力強調出來,期待每個開發者都可以為了幫Kafka節約資源而努力!

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


上一篇
KIP-1052: Enable warmup in producer performance test
下一篇
KIP-1092: Extend Consumer#close with an option to leave the group or not
系列文
每天罵爆一隻 Kafka Pull Request13
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言