Artifact Registry ADR 011: データ調整機能のタイミング
コンテキスト
コンテンツアドレッサブルストレージ(ADR-008)は、2 つの真実の情報源を持つシステムを生み出します。データベースメタデータ(参照、アップロードセッション)とオブジェクトストレージ(blob、アップロード)です。これは CAS の本質的な帰結です(ADR-008 の「ネガティブな帰結 #6」)。これら 2 つの情報源を不一致にするいくつかの操作カテゴリがあります。
- ストレージ書き込みと DB コミット間のクラッシュ: blob はオブジェクトストレージに存在しますが、データベースレコードがありません。これは孤立したストレージオブジェクトを生成します。
- 移動中の copy 後 delete の失敗: アップロードが最終 blob パスへのコピーを完了しますが、一時アップロードオブジェクトの削除に失敗します。これは孤立したアップロードオブジェクトを生成します。
- 外部からのストレージ変更: オペレーターまたは外部プロセスが、レジストリ API を経由せずにストレージのオブジェクトを変更または削除します。これはコンテンツの不一致または欠落オブジェクトを生成します。
- 参照追跡のバグ: 参照解除ロジックのバグは、古い参照(リークしたストレージ、決して GC されない)を残すか、参照を早期に削除する(次の GC サイクルでデータロス)ことがあります。
Virtual レジストリのキャッシュも同じ不一致パターンに従います。データベースのキャッシュメタデータが、ストレージのキャッシュされた blob と不一致になる可能性があります。CAS はオリジンに関係なくすべての blob を均一に保存するため、同じ調整機能(GC、アップロードパージング、データ検証)が virtual キャッシュの不一致に対処します。
ADR-010 とのスコープ境界
ADR-010(データ保持)は GC が 何をする かを定義します: 孤立した blob の削除、ソフト削除されたアーティファクトのハード削除。本 ADR は、各調整機能が いつ出荷されるか と、データベーススキーマ(ADR-007)とストレージレイアウト(ADR-008)に どのようなアーキテクチャ的制約を課すか を決定します。ソフト削除の期限切れは保持メカニズム(ADR-010 のスコープ)であり、両方の情報源がデータの状態に同意しているため、調整メカニズムではありません。ポリシーのみが削除すべきと言っているのです。
調整機能
3 つの調整機能が DB/ストレージの不一致に対処します。
| 機能 | 目的 | タイミング |
|---|---|---|
| ガベージコレクション | ゼロ参照の blob をストレージから削除 | 初回リリース |
| アップロードパージング | 放棄されたアップロードセッションをクリーンアップ(ストレージ + DB) | 延期 |
| データ検証 | DB/ストレージの不一致を検出して報告 | 延期 |
決定
ガベージコレクションを初回リリースで出荷します。アップロードパージングとデータ検証は延期しますが、スキーマやストレージレイアウトの後退を防ぐため、それらの要件は今のうちに把握します。
GC: 初回リリースの要件
なぜ GC を延期しないのか
Container Registry の教訓。 Container Registry は数年の運用後にオンライン GC を後付けしました。何十億もの既存オブジェクト、確立されたアクセスパターン、事前の追跡インフラの不在を持つシステムに GC を追加する複雑さが、主要なエンジニアリング課題でした。新しいサービスに GC を組み込むことで、これを完全に回避できます。
ゼロからのスケールの利点。 新しいサービスはゼロデータでスタートします。低データ量では、GC のバグはより少ないオブジェクトに影響します。早期削除のリスクのあるデータが少なく、API トラフィックと競合する GC によるストレージ I/O とデータベース接続の圧力が低く、診断中に手動で検査できる小さなデータセットです。並行性の問題(GC と API の競合状態)はどの規模でも存在しますが、間違いの代償はサービスが新しいときに最も低いです。これは一回限りのウィンドウです。
ストレージコスト。 GC がなければ、孤立した blob は無制限に蓄積します。Container Registry は GitLab.com で何十億ものオブジェクトと数十ペタバイトに成長しました(ADR-003、ADR-002)。Artifact Registry の孤児蓄積率はまだありません。自己修正メカニズムがなければ、孤立したストレージは単調に増加します。
参照追跡の正確性。 GC は参照追跡ライフサイクル全体(参照を作成、参照解除、ゼロ参照を検証、削除)を行使する唯一のコンシューマーです。GC を早期に出荷することで、データ量がバグを高価にする前に、参照追跡スキーマ(ADR-007)が正しいことを検証します。
なぜ初日からデータベース追跡なのか
GC 候補は、ストレージのオブジェクト列挙ではなく、データベースクエリから来る必要があります。Container Registry はストレージ列挙によるメモリスケーリング問題(issue #216)と、インスタンスごとの実行による冗長スイープ問題(issue #217)に遭遇し、オンラインガベージコレクションをサポートするためにデータベーススキーマを一から再構築しました(オンライン GC 仕様)。ADR-007 は初期設計から GC を考慮する必要があります。参照追跡と候補選択はスキーマにネイティブであるべきで、後付けされるべきではありません。GC はネームスペース単位(ADR-022)で動作します。これはすべてのデータ操作の分離とパーティショニングの境界です。
ADR-008 (CAS) への遡及影響
ADR-008 への変更は不要です。
アップロードパージング: 延期
なぜ延期可能か
アップロードパスは一時的(数分から数時間)であり、uploads/{upload_id} 配下に分離されています。読み込みパスや blob 完全性に影響しません。ADR-008 はすでにベストエフォートのインラインクリーンアップを指定しています。アップロードハンドラーは、移動成功後に一時オブジェクトを削除し、再開不可能なアップロードは失敗時に削除します。これは一般的なケースを処理します。パージャーは残り(クラッシュしたプロセス、放棄された再開可能アップロード)を捕捉します。
パージャーがなければ、放棄されたアップロードはオブジェクトストレージに蓄積します。期限切れのセッションレコードもデータベースに蓄積します。これはストレージとデータベースの衛生問題であり、正確性の問題ではありません。孤立したアップロードからデータロスや破壊された pull は発生しません。極端な規模では、無制限のセッションレコードがアクティブなアップロードのクエリパフォーマンスに影響する可能性があります。ローンチ規模では、ストレージコストとセッションレコード量はどちらも境界づけられて管理可能です。
パージャーが出荷されるとき、既存のデータから完全なクリーンアップ状態を再構成できます。データベースの期限切れアップロードセッションレコードが、どのアップロードが放棄されたかを識別します。オブジェクトストレージの uploads/{upload_id} パス構造により、孤立したアップロードはプレフィックスで列挙可能です。ADR-007 と ADR-008 がすでに提供している以上の追加追跡インフラは不要です。
今のうちに把握する要件
アップロードセッション追跡は、初期スキーマ設計(ADR-007)から有効期限ベースのクリーンアップをサポートする必要があります。パージャーは、ストレージのオブジェクトをリストする方法ではなく、データベースレコードから候補を識別する必要があります(GC と同じ原則)。ADR-008 の可逆的なパス構造はすでにこれをサポートしています。
データ検証サービス: 延期
なぜ延期可能か
検証サービスは、すでに発生した不一致を検出します。不一致を防ぐわけではありません。GC とアップロードパージングが既知の不一致原因(孤立した blob、孤立したアップロード)を処理します。検証サービスはそれ以外のすべて(ストレージの破損、外部変更、GC やパージングのバグ)を捕捉します。
Container Registry の提案(#690)は、最初のイテレーションで自動修復ではなく可視性(ロギング、メトリクス、Sentry)に焦点を当てました。Artifact Registry も同じ段階的アプローチに従えます。検証サービスの構築には、本番で「正しい」とは何かを成熟して理解することが必要です。GC を最初に実行することで、そのベースラインが提供されます。
検証サービスが出荷されるとき、既存のデータベースとストレージレイアウトから正しい状態を導出できます。ADR-008 の可逆的なパス構造により、検証器は別個のマッピングなしに、ストレージオブジェクトとデータベースレコードを双方向にマッピングできます。延期期間中に蓄積した不一致は、これら 2 つの情報源から検出可能で復元可能です。
今のうちに把握する要件
検証サービスは、データベースレコードとストレージオブジェクトを比較して不一致を見つけます。現在の設計の 2 つの特性により、オプションを排除せずに延期できます:
- ADR-008 の可逆的なパス構造により、検証器は別個のマッピングを維持することなく、ストレージパスから期待されるデータベースレコードを導出できます(およびその逆)。SHA256 コンテンツアドレッシングにより、検証器は二次チェックサムを保存することなく、再ハッシュによって完全性を検証できます。
- ADR-007 は、効率的なネームスペースごとの blob クエリをサポートする必要があります。GC はすでにネームスペーススコープの候補選択を必要とするため、この制約は検証サービスに固有ではありません。
どちらの特性も、後で検証をサポートするために設計変更を必要としません。どちらかの特性が欠けていれば、検証サービスは独自の追跡インフラを必要とし、より早く出荷する必要がありました。
検討した代替案
3 つの機能すべてを初回リリースで出荷する
GC、アップロードパージング、検証サービスを初回リリースにバンドルすると、延期機能のギャップ(孤立アップロードの蓄積、未検出の不一致)を排除できます。しかし、アップロードパージングと検証は GC と同じ延期リスクを持ちません。GC には一回限りのゼロからのスケールウィンドウがあり、参照追跡スキーマを検証します。アップロードパージングは境界づけられた衛生問題に対処します。検証サービスには、GC のみが提供できる本番ベースラインが必要です。3 つすべてを出荷することは、リスク低減に比例しない初回リリースのスコープを増やします。
3 つの機能すべてを延期する
GC を延期することは、一回限りの利点(ゼロデータの新サービスに GC を組み込む)と恒久的な後付けコストとを交換します。Container Registry は、何十億ものオブジェクトと事前の追跡インフラの不在を持つシステムにオンライン GC を後付けするのに数年を費やしました。初日から GC がなければ、データベーススキーマ(ADR-007)は実トラフィック下で参照追跡が機能することの検証なしに出荷され、孤立した blob は自己修正メカニズムなしに蓄積します。
帰結
ポジティブ
- GC は、データ量が増える前に実トラフィック下で参照追跡の正確性を検証します。
- 低データ量の新しいサービスに GC を出荷することで、並行性バグを発見して修正するコストが削減されます。
- 延期された機能は、スキーマやストレージレイアウトの後退を防ぐ把握済みの要件を持っています。
- アップロードパージングと検証は、GC と同じ設計基盤(データベース駆動の候補選択、ネームスペーススコープの実行)の上に構築されます。
ネガティブ
- 初回リリースのスコープが増加: GC にはデータベーススキーマサポートとバックグラウンドワーカーが必要です。
- アップロードパージングが出荷されるまで、放棄されたアップロードはオブジェクトストレージに蓄積します(境界づけられたコスト、正確性への影響なし)。
- 検証サービスが出荷されるまで、孤立した blob/アップロード以外の原因による DB/ストレージの不一致は検出されません。
- 検証サービスが出荷されるまで、参照された blob を早期に削除する GC のバグは、クライアントが影響を受けるアーティファクトを要求するまで検出されません。ゼロからのスケールウィンドウは影響を受けるアーティファクトの数を境界づけますが、検出レイテンシは境界づけません。
参考文献
- ADR-008: コンテンツアドレッサブルストレージ: ストレージレイアウトと blob ライフサイクル
- ADR-022: ネームスペースデカップリング: GC 境界としてのネームスペース
- ADR-010: データ保持: GC トリガーに供給される保持ポリシー
- Container Registry オンライン GC 仕様: プロダクション実証済みの GC アーキテクチャ
- Container Registry アップロードパージングメモリ (#216): なぜファイルシステムウォークではなく、データベース追跡パージングなのか
- Container Registry アップロードパージングスケーリング (#217): なぜインスタンスごとのスイープではなく、コーディネートされた実行なのか
- Container Registry データ検証サービス (#690): 不一致検出への可視性ファーストアプローチ
c955a93f)