Sia-Minio Integration Postmortem

Michael Lynch

SiaとMinio統合のポストモーテム

原文は Michael Lynch により に公開されました。 このブログを購読する

Googleで働く中で学んだ最も価値あることの一つが、非難なきポストモーテムという慣行です。何か問題が起きたときには、ほとぼりが冷めるのを待ってから、何が起きたのかを分析するレポートを書きます。そのレポートでは問題がどのように発生したかを説明し、将来同様の問題を緩和するためにチームが取れる具体的なステップを定義します。

先週、ポストモーテムを行う絶好の機会がありました。バウンティによって資金提供されたプロジェクトで、MinioへのSiaサポートの統合が正式に完了したのですが、予想よりも数か月長くかかり、その間に大規模な書き直しが何度も行われました。

Siaは分散型クラウドストレージ技術です。私のお気に入りの技術の一つで、以前にも記事を書いていますMinioはオープンソースのS3互換ファイルサーバーです。この2つの統合により、ユーザーはAmazon S3に対応したあらゆるバックアップソフトウェアを使って、データをSiaネットワークにバックアップできるようになりました。

この統合は非常に大きな出来事であり、12月の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 - オペレーション担当VP、Nebulous Labs
  • @harshavardhana - Minioメンテナー

背景:ポストモーテムとは何か

ポストモーテムとは、計画通りに進まなかった直近の経験から学ぶための取り組みです。

ポストモーテムは非難を目的としません。私たちが特定しようとしているのは、悪い結果を招いたプロセスの問題点です。を特定したり非難したりすることが目的ではありません。議論の対象となった出来事に関わったすべての人は、有能で善意を持って行動していたという前提に立ちます。

詳細については、SRE本の“Postmortem Culture: Learning from Failure”をご覧ください。

概要

7月19日、Nebulous Labsは、オープンソースのS3互換ファイルサーバーであるMinioへのSia統合に対して30万SCのバウンティを発表しました。開発者のDavid Gore氏(@dvstate)は5日後に概念実証(PoC)を公開し、その10日足らずで全額の賞金を受け取りました。

しかし、その統合がMinioのリポジトリにマージされるまでには、さらに3か月を要しました。コードをMinioに受け入れてもらうためには全面的な再設計が必要となり、@dvstate氏はバウンティでは正式に補償されない多大な作業をこなすことになりました。

統合自体は機能していますが、完成にあたってはバウンティでは想定されていなかったいくつかの制限を加える必要がありました。

  • ファイル名に使える文字が、Siaが本来許容する範囲よりも厳しい、限定的なホワイトリストに制限されています。
  • マルチパートでのファイル転送に対応していません。
  • 自動テストのカバレッジがあるのは、些末な2つの関数のみです。

影響

一連の出来事がもたらした最も大きな影響は、重要なパートナーとの統合が数か月遅れたことです。SiaがS3互換性を獲得したことは大きなマイルストーンですが、プロセスが長期化したことで、その達成感の勢いが削がれてしまったように感じられます。

このプロセスでのつまずきは、Siaに対して次のような否定的な印象を与えました。

  • Siaとの統合は困難で、Siaのネイティブ言語であるGoでさえ作業の重複を要します。
  • Siaのバウンティを完了するのは、承認基準が不明確なため困難です。

得られた教訓

うまくいったこと

  • SiaがMinioに正常に統合されました。
  • Siaコミュニティのメンバーが、さまざまなS3クライアントを使って異なるシナリオでMinio統合のテストに参加しました。

うまくいかなかったこと

  • 機能や要件に関する認識の齟齬により、統合コードが何度も書き直されることになりました。
  • MinioメンテナーによるレビューとPRの更新の間に長い遅延(場合によっては数週間)がありました。
  • Sia統合のPRが進行中にMinioのコードベースが変更されたため、@dvstate氏はマージコンフリクトの解消に少なからぬ時間を費やさなければなりませんでした。

幸運だった点

  • @dvstate氏が、Nebulousがバウンティを支払った後も数か月にわたり自発的に統合作業を続けてくれました。
  • @dvstate氏が、Minioのテスト用にSiaのテストサーバーを自発的に立ち上げ、設定し、費用も負担してくれました。
  • Minioのメンテナーが時間を惜しまず、同じPRを数か月にわたってレビューし続けてくれました。

タイムライン

  • 2017-07-19: Nebulous Labsが一連のSiaバウンティを発表しました。第一弾はSiaとMinioの統合に対するバウンティでした。
  • 2017-07-24: @dvstate氏が概念実証版の統合を公開しました。
  • 2017-08-03: Nebulous Labsが@dvstate氏にバウンティの全額を授与しました。
  • 2017-08-09: @dvstate氏がMinioのソースコードに対してSia統合の最初のPRを作成しました。
  • 2017-08-09: @harshavardhana氏が、SQLiteの代わりにBoltDBを使うようPRの書き直しを要請しました。
  • 2017-08-13: @harshavardhana氏がSia-Minio統合の受け入れに合意しました。
  • 2017-08-16: @dvstate氏がBoltDBへの書き換えを完了しました。
  • 2017-08-28: コードレビューの中で、@harshavardhana氏がデータベース自体を削除し、キャッシュ層なしでPRを書き直すよう要請しました。
  • 2017-09-26: PRが数週間動きがなかったため、@zherbert氏@mtlynch氏が進捗の更新を依頼しました。
  • 2017-10-19: @dvstate氏がキャッシュ層を削除したPRの書き直しを完了しました。
  • 2017-10-24: @harshavardhana氏が@dvstate氏にパッチを送付しました。
  • 2017-10-25: @dvstate氏が元のPRをクローズし、Minio側の要望と@harshavardhana氏のパッチを反映した新しいPRを開始しました。
  • 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メンテナーからの要件に対応するため、統合コードを大きく異なる3つのバージョンで書き上げることになりました(1回目2回目3回目)。

推奨されるアクションアイテム:

  • 今後のSiaバウンティでは、事前にサードパーティのメンテナーと協力して要件を確定し、それをバウンティの受賞基準に含めてください。

  • バウンティのための客観的な受け入れテストを定めてください。例:

    1. 500 SCのallowanceでsiadが動作するサーバーを用意します。

    2. クライアントが次のコマンドでminioを起動します。

      export MINIO_ACCESS_KEY=minioaccesskey
      export MINIO_SECRET_KEY=miniosecretkey
      ./minio gateway sia
      
    3. クライアントマシン上のフォルダ ~/test-data に、1KBから10GBまでのサイズの異なる100個のファイルを用意し、合計は4TBを超えないものとします。ファイルには深さが最大3のネストされたフォルダが含まれます。

    4. クライアントマシンで次のコマンドが正常に実行されます。

      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/
      
    5. ダウンロードしたファイルのSHA-1ハッシュが、元のファイルのSHA-1ハッシュと一致します。

  • バウンティ告知に曖昧な点が見つかった場合は、コンテスト期間中も変更履歴(changelog)を示しながら継続的に更新してください。

  • バウンティの受賞要件に関する正式な情報源はバウンティの課題トラッカー(issue tracker)であることを明確にしてください。

  • バウンティ参加者は、公式のバウンティトラッカー以外で寄せられた要望に応える必要はありません。

成功した統合ではなく概念実証に基づいて支払われたバウンティ

NebulousはSiaコア開発者によるレビューの後にバウンティを授与しましたが、それはMinioメンテナーからの承認を得る前のことでした。バウンティの真の目的はMinioのリポジトリへの統合であり、そうでなければユーザーは@dvstate氏のメンテナンスされていないフォークからコードを導入することを躊躇するでしょう。

Siaは、@dvstate氏が自身の責務が終わった後も長くPRの作業を続けてくれたことに恵まれましたが、バウンティ本来の目的の達成を、受賞者の善意に依存すべきではありません。

バウンティが授与される前は、賞を勝ち取るための切迫感があり、要求された変更は数時間から数日で実装されていました。授与後は、遅延が数週間にまで延びました。

これは、@dvstate氏がボランティアのベストエフォートで作業していたことを考えれば、当然かつ合理的です。Siaにとって、遅延が無限大にならなかっただけでも幸運でした。

推奨されるアクションアイテム:

  • バウンティの支払いは概念実証ではなく、統合の成功に基づいて行ってください。
  • 対象リポジトリへの正常なマージを、今後のバウンティの明確な要件としてください。

Minio統合がsiacコマンドラインクライアントのロジックを重複している

Minio統合コードの30〜40%は、単にSia APIを実装するためのロジックです。これはSiaコアリポジトリにすでに存在するコードの重複であり、siacコマンドラインクライアントが同一の機能を実装しています。

Siaのネイティブ言語であるGoを含め、どの言語にも公式のSia APIバインディングが存在しません。

推奨されるアクションアイテム:

  • Sia API用の公式Goクライアントライブラリを作成してください。siacをこのライブラリのリファレンスクライアントとし、Minio統合をこのライブラリを使うようにリファクタリングしてください。
  • Go以外のコードを必要とする今後のバウンティでは、必要なSia API機能を実装するライブラリを作成することを提出要件としてください。このライブラリはアプリケーション固有のコードから独立したものとすべきです。

Minio統合のテストカバレッジが極めて低い

些末な2つの関数にしかテストカバレッジがなく、Sia Minioコードへの変更がMinioの機能を破壊したかどうかを検出することが困難です。

推奨されるアクションアイテム:

  • 自動テストを今後のSiaバウンティの要件としてください。

レビュー中の情報のサイロ化

PRに必要な変更に関する重要な議論が非公開で行われました。@dvstate氏と@harshavardhana氏以外は誰も進捗を追跡したり、PRを前進させる手助けをしたりできませんでした。

推奨されるアクションアイテム:

  • バウンティの支払いは概念実証ではなく統合の成功に基づいて行ってください。
  • 議論は一元的な場所(例:バウンティ用のGitHub issue)で行うことを義務付け、すべてのバウンティ応募者が同じ情報にアクセスできるようにしてください。

「最初に完了した者が勝つ」形式のバウンティがもたらす歪んだインセンティブ

バウンティプログラムのルールには次のように記載されています。

バウンティは1つの提出に対して1回のみ支払われ、別途指定がない限り、バウンティに設定されたすべての基準を最初に満たした個人またはチームに支払われます。

これは、バウンティ応募者が実装コストを最小化するようにソリューションを最適化することを促し、結果として可読性、保守性、あるいは明確なドキュメントに時間を費やす動機を削いでしまいます。

Minio統合のケースでは、コード自体は徹底的にドキュメント化されていますが、テストが不足し、SiaのロジックとMinioのロジックが混在しているため、将来の保守性に課題を生む可能性があります。

この制度は、コラボレーションや改善も阻害します。ある開発者がソリューションを公開すると、バウンティが最初の提出者に渡る可能性が高いため、他の開発者が別のソリューションに挑戦するインセンティブがなくなります。ルールがそのようなシナリオを想定していないため、他の応募者の提出物を改善する道筋も存在しません。

推奨されるアクションアイテム:

  • 無差別な「提出期間(submission window)」を設けてください。
  • 提出の速さが問われない期間を定めてください(例:バウンティコンテストの最初の2週間以内に受け取ったすべての提出物は同等に扱われます)。
  • 応募者は早期に提出できますが、他者がその成果をフォークして改善すること(単なるシンボルのリネームではなく、実質的な改善である必要があります)を許可してください。この場合、バウンティはNebulousの裁量により貢献した開発者間で分割されます。
  • 最初の提出期間が終了した後は、有効な最初の提出物に賞が与えられます。

サードパーティによる検証の困難さ

MinioチームはそれまでSiaの経験がありませんでした。MinioがPRをマージできるようになるまでに、@dvstate氏は自費でテストサーバーを用意し、事前に告知されていなかった一連の手動検証ステップについてMinioメンテナーと協力しなければなりませんでした。

推奨されるアクションアイテム:

  • サードパーティ統合に関する今後のバウンティでは、バウンティ主催者がソリューションの検証と、検証を支援するためのサードパーティパートナーとの連携に責任を持ってください。
  • バウンティのための客観的な受け入れテストを定めてください(「要件の不明確さ」を参照)。

この記事は「muse-spark-1.2-contributor」を使用して翻訳されました。

コメント