Sia-Minio 整合事後檢討
原文由 Michael Lynch 于 發布,訂閱此部落格
我在 Google 工作期間學到最受用的事情之一,就是無究責事後檢討的做法。當出了問題,你會等風波平息後,再撰寫一份報告來分析整個經過。這份報告會說明問題是如何發生的,並列出團隊未來可以採取哪些具體步驟來預防類似問題再度發生。
上週我看到一個很適合做事後檢討的機會。一個由懸賞資助、將 Sia 支援整合進 Minio 的專案雖然已正式完工,但比預期多花了好幾個月,而且期間經歷了多次大規模的重寫。
Sia 是一項去中心化的雲端儲存技術。我之前就寫過相關文章,因為它是我最喜歡的技術之一。Minio 則是一套開源、相容於 S3 的檔案伺服器。兩者整合後,代表使用者現在可以透過任何相容於 Amazon S3 的備份軟體,將資料備份到 Sia 網路上。
這項整合是一件大事,等 Sia 在十二月發布後的軟體趨於穩定,我打算再寫更多相關內容。在此同時,我認為這是個帶領大家對整合過程進行事後檢討的寶貴機會。我向 Nebulous Labs 團隊提出了這個想法,他們也很認同。我聯繫了 Sia-Minio 整合程式碼的作者,他也相當支持,並同意與我一起撰寫這份報告。Nebulous Labs 與 Minio 團隊都已審閱並核准發布,因此你可以在下方看到我們的完整報告:
Minio 整合懸賞事後檢討
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 維護者
背景:什麼是事後檢討?
事後檢討是一種練習,目的是從不如預期的近期經驗中學習。
事後檢討是無究責的:我們要找出的是導致不良結果的「流程」問題,而非追究或羞辱「個人」。我們假設所有參與相關事件的人都是有能力且出於善意的。
詳情請參閱《SRE 寶典》中的「Postmortem Culture: Learning from Failure」一章。
摘要
7 月 19 日,Nebulous Labs 宣布懸賞 300,000 SC,徵求可實際運作的 Sia 與 Minio(開源、相容於 S3 的檔案伺服器)整合方案。開發者 David Gore(@dvstate)在五天後就發布了概念驗證,並在不到十天後獲頒全額獎金。
然而,這項整合又花了額外三個月才被合併進 Minio 的程式碼庫。要讓程式碼被 Minio 接受,需要對程式碼進行全面性的重新架構,而 @dvstate 為此付出了大量工作,這些都未在懸賞中獲得正式報酬。
整合雖然完成了,但必須加上幾個在當初懸賞中未預期的限制:
- 僅支援有限的檔名白名單字元,比 Sia 允許的範圍更為嚴格。
- 不支援分段上傳(multipart)檔案傳輸。
- 僅有兩個極簡單的函式具備自動化測試涵蓋率。
影響
這次事件最重大的影響,是與關鍵夥伴的整合被延後了好幾個月。Sia 獲得 S3 相容性是一項巨大的里程碑,但由於整個過程被拉得太長,我們感覺這項成就的力道與氣勢也被削弱了。
過程中的波折也讓外界對 Sia 產生了負面觀感:
- 與 Sia 整合很困難,即使使用 Sia 原生的 Go 語言,也需要重複造輪子。
- 要完成 Sia 的懸賞很困難,因為驗收標準不明確。
經驗教訓
哪些方面做得好
- Sia 已成功整合至 Minio。
- Sia 社群成員使用多種 S3 用戶端,在不同情境下協助測試 Minio 整合。
哪些方面出了問題
- 對於功能與需求的溝通不良,導致整合程式碼被多次重寫。
- Minio 維護者的審查與 PR 更新之間存在很長的延遲(有些情況下長達數週)。
- 由於 Sia 整合的 PR 還在進行期間 Minio 程式碼庫本身也在變動,@dvstate 不得不花費相當多時間解決合併衝突。
哪些方面算是幸運
- 在 Nebulous 已支付懸賞後,@dvstate 仍自願投入時間,花了數個月繼續處理整合工作。
- @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 針對 Sia 整合向 Minio 原始碼提交了第一個 PR。
- 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 傳送一個 patch 給 @dvstate。
- 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 整合是否必須支援儲存桶(bucket)政策設定
- 需要支援哪些 S3 用戶端應用程式(例如 mc、s3cmd)
- 需要何種程度的手動測試來證明功能正常
- Sia 整合可使用多少個 Sia 專屬的環境變數
- 需要多少測試涵蓋率
- 對 Minio UI 需要/允許做哪些變更
- 對 Minio 文件需要做哪些變更
@dvstate 最終因應 Minio 維護者提出、但未在原始懸賞說明中載明的要求,寫了三個截然不同的整合版本(第一版、第二版、第三版)。
建議行動項目:
對於未來的 Sia 懸賞,應事先與第三方維護者合作確立需求,並將其納入懸賞的獲獎標準。
為懸賞建立客觀的驗收測試。例如:
伺服器上已部署 siad,並有 500 SC 的額度(allowance)。
用戶端使用下列指令啟動 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 雜湊值相符
若在懸賞公告中發現含糊之處,應在整個競賽期間持續更新公告,並附上變更日誌說明修改內容。
明確指出懸賞的 issue tracker 是獲獎要求的權威來源。
懸賞參賽者無需滿足出現在官方懸賞追蹤器以外的要求。
懸賞是依概念驗證而非成功整合來支付
Nebulous 是在經 Sia 核心開發者審查後、但在獲得 Minio 維護者核准前就頒發了懸賞。懸賞的真正目標是整合進 Minio 的程式碼庫,否則使用者會不願意部署來自 @dvstate 未再維護的分支(fork)的程式碼。
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 維護者合作完成一系列先前未公布的手動驗證步驟。
建議行動項目:
- 對於未來涉及第三方整合的懸賞,懸賞主辦方應負責驗證解決方案,並與第三方夥伴合作協助他們進行驗證。
- 為懸賞建立客觀的驗收測試。(參見「需求不明確」一節)。
隨機一篇部落格
留言
登入後參與討論