Sia-Minio 整合事後檢討
我在 Google 工作期間學到最有價值的事情之一,就是blame-free postmortems(無究責事後檢討)的實踐。當發生問題時,你會先等塵埃落定,再撰寫一份分析事件經過的報告。這份報告會說明問題是如何發生的,並定義團隊未來可以採取哪些具體步驟來緩解類似問題。
上週,我看到一個進行 postmortem 的絕佳機會。一項由懸賞資助的專案已正式完工,目的是將 Sia 支援整合到 Minio 中,但所花時間比預期多了好幾個月,且經歷了多次大規模重寫。
Sia 是一項去中心化雲端儲存技術。我曾撰文介紹過它,因為它是我最喜愛的技術之一。Minio 是一套開源且相容 S3 的檔案伺服器。兩者的整合意味著使用者現在可以使用任何相容於 Amazon S3 的備份軟體,將資料備份到 Sia 網路上。
這次整合是一件大事,我計畫在 Sia 十二月版本發布、軟體趨於穩定後,再撰寫更多相關文章。在此之前,我認為這是一個針對整合流程進行 postmortem 的寶貴機會。我向 Nebulous Labs 團隊提出了這個想法,他們也樂於採納。我聯繫了 Sia-Minio 整合程式碼的作者,他同樣表示支持,並同意與我共同撰寫這份報告。Nebulous Labs 與 Minio 團隊已審閱並核准發布,因此你可以在下方看到我們的完整報告:
Minio 整合懸賞 postmortem
Nebulous Labs 事件 #1
日期: 2017-12-01
作者:
- Michael Lynch(麥可·林奇) - @mtlynch - Sia 部落客兼 /r/siacoin 版主。
- David Gore(大衛·戈爾) - @dvstate - 開發者、懸賞得主
審閱者
- David Vorick(大衛·沃里克) - @taek42 - 首席開發者,Nebulous Labs
- Zach Herbert(柴克·赫伯特) - @zherbert - 營運副總裁,Nebulous Labs
- @harshavardhana - Minio 維護者
背景:什麼是 Postmortem?
Postmortem 是一種從未按計畫進行的近期經驗中學習的演練。
Postmortem 是無究責的:我們要找出的是導致不良結果的流程問題,而非試圖指認或羞辱個人。我們假設所有參與討論事件的人員都具備能力且出於善意。
詳情請參閱 SRE 書籍中的“Postmortem Culture: Learning from Failure”(《事後檢討文化:從失敗中學習》)。
摘要
7 月 19 日,Nebulous Labs 宣布提供 300,000 SC 的懸賞,徵求可運作的 Sia 與 Minio(開源且相容 S3 的檔案伺服器)整合方案。開發者大衛·戈爾(@dvstate)於五天後發布了概念驗證,並在不到十天後獲頒全額獎金。
整合程式碼又花了三個月的時間才被合併到 Minio 的儲存庫中。要讓程式碼被 Minio 接受,需要對程式碼進行全面性的重新架構,以及 @dvstate 投入大量未獲懸賞正式補償的工作。
整合功能可以運作,但要完成整合,必須加入懸賞中未預期的幾項限制:
- 僅支援有限的檔案名稱字元白名單,比 Sia 允許的範圍更為嚴格。
- 不支援分段檔案傳輸。
- 僅有兩個簡單的函式具備自動化測試覆蓋。
影響
這些事件最重大的影響,是與關鍵夥伴的整合被延遲了好幾個月。Sia 獲得 S3 相容性是一個巨大的里程碑,但由於過程過於冗長,我們感覺這項成就的力道被削弱了。
過程中的波折也讓外界對 Sia 產生了負面觀感:
- 與 Sia 整合很困難且需要重複投入,即使使用 Sia 原生語言 Go 也是如此。
- 完成 Sia 懸賞很困難,因為驗收標準不明確。
經驗教訓
哪些部分進展順利
- Sia 已成功整合到 Minio 中。
- Sia 社群成員使用多種 S3 客戶端,在不同情境下參與測試 Minio 整合。
哪些部分出了問題
- 對於功能與需求的溝通不良,導致整合程式碼被多次重寫。
- Minio 維護者的審查與 PR 更新之間存在長時間的延遲(在某些情況下長達數週)。
- @dvstate 不得不花費相當多的時間來解決合併衝突,原因是 Sia 整合 PR 審查期間 Minio 程式碼庫持續變動。
我們在哪些地方算是幸運
- @dvstate 在 Nebulous 支付懸賞後,仍自願花費數月時間持續投入整合工作。
- @dvstate 自願啟動、設定並自費提供了一台 Sia 測試伺服器供 Minio 測試使用。
- Minio 維護者慷慨地投入時間,持續數月審查同一個 PR。
時程
- 2017-07-19:Nebulous Labs 宣布一系列 Sia 懸賞,首項懸賞為將 Sia 與 Minio 整合。
- 2017-07-24:@dvstate 發布概念驗證整合。
- 2017-08-03:Nebulous Labs 將全額懸賞頒給 @dvstate。
- 2017-08-09:@dvstate 提交第一個 PR,將 Sia 整合至 Minio 原始碼。
- 2017-08-09:@harshavardhana 要求 @dvstate 重寫 PR,改用 BoltDB 而非 SQLite。
- 2017-08-13:@harshavardhana 同意接受 Sia-Minio 整合。
- 2017-08-16:@dvstate 完成改用 BoltDB 的重寫。
- 2017-08-28:程式碼審查期間,@harshavardhana 要求 @dvstate 完全移除資料庫,並在不使用快取層的情況下重寫 PR。
- 2017-09-26:在 PR 數週無進展後,@zherbert 與 @mtlynch 請求更新進度。
- 2017-10-19:@dvstate 完成移除快取層的 PR 重寫。
- 2017-10-24:@harshavardhana 向 @dvstate 發送了一個 patch。
- 2017-10-25:@dvstate 關閉原始 PR 並開啟一個新的 PR,以回應 Minio 的要求並整合 @harshavardhana 的 patch。
- 2017-10-26 - 2017-11-21:@dvstate 佈建並自費提供 Sia-Minio 測試節點,並向 @harshavardhana 開放存取。兩人使用 Minio 網頁應用程式、s3cmd 與 mc 命令列工具手動測試整合。
- 2017-11-22:Minio PR 合併完成。
觀察到的問題
需求不明確
懸賞說明中未定義 Sia-Minio 整合的許多細節。說明中僅指出「使用者必須能夠使用 Minio 客戶端上傳/下載 Sia 檔案」,但未提及來自 Minio 維護者的任何限制或要求。
此外,有數位 Sia 使用者透過 Sia Slack 的 #bounties 頻道或私訊聯繫 @dvstate 要求新增功能。由於沒有權威的需求定義,@dvstate 擔心若忽略這些要求可能會喪失懸賞資格,因此實作了這些額外功能。
因此,@dvstate、Minio 維護者與 Sia 使用者之間對於以下問題產生了混淆:
- 哪些第三方函式庫是可接受的
- Sia 整合是否被允許在檔案系統上維護快取以保存狀態資訊與詮釋資料
- Sia 整合是否必須實作分段檔案傳輸
- Sia 整合是否必須支援儲存貯體政策設定
- 需要支援哪些 S3 客戶端應用程式(例如 mc、s3cmd)
- 需要何種程度的手動測試來證明功能正常運作
- Sia 整合被允許使用多少個 Sia 專屬的環境變數
- 需要多少測試覆蓋率
- 需要/允許對 Minio UI 進行哪些變更
- 需要對 Minio 文件進行哪些變更
@dvstate 為了回應 Minio 維護者提出、但未在原始懸賞說明中載明的要求,最終撰寫了三個截然不同版本的整合程式碼(第一版、第二版、第三版)。
建議處理事項:
對於未來的 Sia 懸賞,事先與第三方維護者合作確立需求,並將其納入懸賞獲獎標準。
為懸賞建立客觀的驗收測試。例如:
佈建一台已安裝 siad 且 allowance 為 500 SC 的伺服器。
客戶端使用下列指令啟動 minio:
export MINIO_ACCESS_KEY=minioaccesskey export MINIO_SECRET_KEY=miniosecretkey ./minio gateway sia客戶端機器在
~/test-data資料夾中擁有 100 個檔案,大小從 1 KB 到 10 GB 不等,總計不超過 4 TB。這些檔案包含巢狀資料夾,資料夾深度最多為 3 層。客戶端機器成功執行下列指令:
SERVER=insert.server.hostname # replace with actual server mc config host add minio-sia \ "http://${SERVER}" minioaccesskey miniosecretkey S3v4 mc mb minio-sia/sia-test-bucket # Upload test files. mc cp --recursive ~/test-data/* minio-sia/sia-test-bucket/ # Download test files. mc cp --recursive \ minio-sia/sia-test-bucket/* ~/test-data-downloaded/下載檔案的 SHA-1 雜湊值與原始檔案的 SHA-1 雜湊值相符
若在懸賞公告中發現含糊之處,應在整個競賽期間持續更新公告,並附上變更日誌以標示修改內容。
明確指出懸賞的問題追蹤器是贏得懸賞所需條件的權威來源。
懸賞參賽者無需滿足出現在官方懸賞追蹤器以外的要求。
懸賞依概念驗證而非成功整合發放
Nebulous 在經過 Sia 核心開發者審查後、但尚未取得 Minio 維護者核准前,就頒發了懸賞。懸賞的真正目標是整合到 Minio 的儲存庫中,否則使用者會不願意部署來自 @dvstate 未維護分支的程式碼。
Sia 很幸運 @dvstate 在其責任結束後仍持續處理 PR,但懸賞真正目標的完成不應依賴得獎者的善意。
在懸賞頒發前,存在爭取獎金的急迫感——要求的變更會在數小時或數天內完成。頒發後,延遲則增加到數週。
這是可預期且合理的,因為 @dvstate 是以志工、盡力而為的方式投入工作。Sia 能獲得小於無限大的延遲,已算幸運。
建議處理事項:
- 根據成功整合而非概念驗證來發放懸賞。
- 將成功合併到目標儲存庫列為未來懸賞的明確要求。
Minio 整合重複了 siac 命令列客戶端的邏輯
Minio 整合程式碼中約有 30-40% 僅是用於實作 Sia API 的邏輯。這與Sia 核心儲存庫中已存在的程式碼重複,因為 siac 命令列客戶端已實作了相同的功能。
目前沒有任何語言的官方 Sia API 綁定,包含 Sia 原生語言 Go 在內。
建議處理事項:
- 為 Sia API 建立官方 Go 客戶端函式庫。讓
siac成為此函式庫的參考客戶端。重構 Minio 整合以使用此函式庫。 - 對於未來需要非 Go 程式碼的懸賞,要求投稿作品建立一個用於實作必要 Sia API 功能的函式庫。此函式庫應獨立於應用程式特定程式碼之外。
Minio 整合的測試覆蓋率極低
僅有兩個簡單的函式具備測試覆蓋,使得難以偵測對 Sia Minio 程式碼的變更是否會破壞 Minio 功能。
建議處理事項:
- 將自動化測試列為未來 Sia 懸賞的必要條件。
審查期間的資訊孤島化
關於 PR 所需變更的關鍵討論都是私下進行的。除了 @dvstate 或 @harshavardhana 之外,沒有人能追蹤進度或協助推動 PR。
建議處理事項:
- 根據成功整合而非概念驗證來發放懸賞。
- 要求討論在集中地點進行(例如懸賞的 Github issue),讓所有懸賞申請者都能取得相同資訊。
「先完成者得」懸賞造成反誘因
懸賞計畫的規則指出:
懸賞僅會針對一份投稿支付一次,除非另有說明,否則將支付給第一位符合懸賞所有條件的個人或團隊。
這會誘使懸賞投稿者將解決方案最佳化以最小化實作成本,進而抑制其在可讀性、可維護性或清晰文件上投入時間。
以 Minio 整合為例,程式碼雖然有詳盡的文件,但缺乏測試,且將 Sia 邏輯與 Minio 邏輯混雜在一起,未來在可維護性上可能會帶來挑戰。
此制度也會抑制協作或改進。若有開發者發布了解決方案,其他開發者就沒有動力再嘗試,因為懸賞很可能會頒給第一位投稿者。也沒有途徑可在另一位申請者的投稿基礎上進行改進,因為規則並未涵蓋該情境。
建議處理事項:
- 採用無差別的「投稿窗口」
- 明定一段投稿速度不影響評選的窗口期(例如,懸賞競賽前兩週內收到的所有投稿均視為同等)。
- 申請者可以提早投稿,但允許他人 fork 並改進其作品(必須是實質性的改進,而非僅重新命名某些符號)。在此情況下,懸賞將由 Nebulous 酌情在貢獻的開發者之間分配。
- 初始投稿窗口結束後,獎項頒給第一份有效的投稿。
第三方驗證的困難
Minio 團隊先前沒有使用 Sia 的經驗。在 Minio 安心合併 PR 之前,@dvstate 必須自費佈建測試伺服器,並與 Minio 維護者合作執行一系列先前未公布的手動驗證步驟。
建議處理事項:
- 對於未來第三方整合的懸賞,由懸賞主辦方負責驗證解決方案,並與第三方夥伴合作協助其驗證。
- 為懸賞建立客觀的驗收測試。(參見「需求不明確」)。
隨機一篇部落格