
2026/11/07 4:24
GitHub の新しい Git ストレージアーキテクチャ
RSS: https://news.ycombinator.com/rss
要約▶
Japanese Translation:
GitHub は GitHub Universe で発表された「Project Rubicon」という新しい Git ストアージアーキテクチャを公式に発表しました。このシステムは、1 秒あたりの数천回の書き込みとスケーラブルな読み取りトラフィックに対応することを目的としており、2026 年 5 月に導入されました。その基盤となるのは 2 つの原則です:協調性を最小限に抑え、ストレージとコンピューティングを分離することです。Git の不変性(オブジェクトは内容で名前付けされる)を活用することで、参照のみが合意が必要となり、遅延を大幅に削減しています。
テストでは、単一のリポジトリに対して 5,000 の同時エージェントから 7,200 回のプッシュ/秒を送信する能力が確認されました。これは、現在最も繁忙なリポジトリの性能を少なくとも 2 つの桁(100 倍)以上で縦方向にスケーリングしたものです。アーキテクチャでは、永続的な Git オブジェクト(パックとマニフェスト)は Azure Blob Storage に分離管理され、参照は専用システム「Ref-CAS」を通じて管理されます。トラフィックは Spokes を介して仮想レプリカにルーティングされ、ローカルディスクをリビルド可能なキャッシュとして使用します。背景では別の専用ハードウェア上でコンパクト化が実行されており、この分離によりコンパクト化の水平スケーリングが可能となり、ユーザーレイテンシに影響を与えることなく実現できます。現在、Azure をバックボーンとするこのアーキテクチャへの移行完了率は 99.99999% に達しており、大規模な同時ワークロードに対して高い故障耐性と安定した稼働時間を提供しています。
本文
Git ストレージアーキテクチャの新構築:エージェント・スケールへの対応
GitHub ユニバーズにて、毎秒数千回の書き込みを処理し、読み込みはオンデマンドで拡張可能な新しい Git ストレージアーキテクチャを発表しました。
実証結果と概要
内部テストでは以下の能力を実証済みです。
- 同時接続サポート: リポジトリ上で 5,000 のエージェント を同時に接続可能。
- 書き込み性能: 1 リポジトリあたり、毎秒 7,200 回のプッシュ 送信が可能。
- 読み込み性能: 常に低いレイテンシで読み込みトラフィックを処理できることを確認。
このアーキテクチャは、何億人もの開発者に対する「エージェント型開発」のサポートを実現するための土台となっており、GitHub の停止リスクなく下層部分を構築しています。
過去 1 年間の歩みと設計原則
エージェントによる開発により、GitHub 上の忙しいリポジトリの姿が変化しました。次世代アーキテクチャを支える 2 つの基本原則は以下の通りです。
- 調整を最小化: 合意形成コストを抑える。
- ストレージとコンピュートの非同期化: 処理を分離する。
移行と知見
前回の投稿では、Azure への移行(99.99999% のリポジトリ取り込み)、書き込みクォーラム範囲の個別参照化、および Azure Blob Storage をバックエンドとしたバーチャルレプリカの導入について説明しました。
主な知見として以下の点があります。
- Git オブジェクトの不変性: コンテンツで名前が付けられるため、2 つの書き手が同時並行でデータを格納する際の合意は不要です。
- 合意が必要なのは参照のみ: 更新が必要な「参照」は非常に小さな領域であり、ここに合意形成を限定すればよいことが判明しました。
バーチャルレプリカはこの知見を取り入れた最初のステップとして機能し、残りのアーキテクチャも同様の観点を基に構築されています。これにより、かつて密に結合していたデータ保存、リクエスト処理、リポジトリ維持の各要素が 独立して拡張可能 になりました。
開発者体験(プッシュ、フェッチ、ブランチ操作など)や必要な保護機能は従来の通り維持されます。
エージェント・スケールに対応した構築
GitHub プラットフォームの拡張性を以下の 2 つの軸で捉えています。
- 水平スケーリング: 多くのリポジトリをまたいで働く開発者およびエージェントの数(既存のアプローチを引き継ぎ、テナントパーティショニングや負荷分散を適用)。
- 垂直スケーリング: 1 つのリポジトリ上で働く数(エージェントによる書き込み増加により要件が導かれ、今回のアーキテクチャの主要な動機)。
なぜ垂直スケーリングが必要なのか?
現在、忙しいリポジトリは 1 秒あたり数十回の書き込み(短時間スパイク)でしたが、24 時間稼働するエージェントへシフトすると、これは持続的な高レートへと変化します。また、各プッシュに伴う読み込み(CI 実行、デプロイ引き寄せなど)が増大し、書き込み量に比例してトラフィックが拡大しています。
既に指数関数的な成長が見られます。未来には少なくとも 2 オーダー規模の拡張を見込む必要があります。これに対応するため、単一リポジトリに対し以下が必要です。
- 毎秒数千回の書き込み受け入れ: ハンドリング能力の向上。
- 複数のライターノードサポート:
- インデックス作成やオブジェクト接続性のチェックは CPU コストが高く、単一ノードではすぐに飽和するため。
- 障害時の耐性向上および復旧時間短縮のため。
- コミットレイテンシの最小化: エージェントが完了を待って次のステップへ進むため。
- 素早い直線化(Linearization)能力: 追いつけなくなった場合でも、必要なデータのみダウンロードして追いつけるように参照を更新記録する。
- 読み込みコスト削減: 変化がない際のコストを抑える(読み込み/書き込み比率を考慮)。
- コンポーネントの独立スケーリング: 各部を個別に拡張可能にする。
「Project Rubicon」のご紹介
2026 年 5 月、最初の Azure 移行後に設計が進められました。整合性、耐久性、可用性、レイテンシ保証を維持しつつ、スループットを最大化する設計として、「Rubicon」と命名しました(取り返しの利かない境界=ローマ神話のルビコ川へのオマージュ)。
アーキテクチャ概要
従来の要素(Git クライアント、API、Web UI)は変更せず、リクエストは Spokes に集まり、ルーティングと負荷分散を処理します。変化が生じたのは Spokes の下の データ平面 です。
スピーチ(Spokes)の役割
- リクエストを各リポジトリに割り当てられた少量の バーチャルレプリカグループ へルーティングします。
- バーチャルレピカは読み込み・書き込み用の使い捨て可能な単一機動隊で、ローカルディスクはキャッシュとして機能し(いつでも再構築可能)、停止しても他が役割を引き継ぎます。
- 永続データ: バックグラウンドで動作するコンパクションノードが Blob Storage と Ref-CAS にアクセスし、パックをマージおよび不要なオブジェクトを削除します。これにより、バーチャルレピカの CPU メモリは完全なリクエスト処理に充てられます。
永続的な状態データ(2 か所)
- Git オブジェクト: パック、インデックス、読み込み加速器、コンパクション記録、キャッシュ応答などは Azure Blob Storage に格納。
- 参照(References)およびパックマニフェスト: 「Ref-CAS(Reference Compare-and-Swap)」という別のレプリケートされたログサービスに格納。
データフロー
- 書き込み: バーチャルレピカがインデックス化&Blob Storage にアップロード → Ref-CAS でトランザクションコミット → 背景でコンパクションノードがマージ。
- 読み込み: バーチャルレピカが Ref-CAS でバージョン確認 → Blob Storage から必要なパックをキャッシュへ引き寄せ → 処理完了。
原則 1:協調を最小化(高スループットでの参照状態の変更)
Azure Blob Storage は大量データの格納には適していますが、参照の頻繁な競合更新には不向きでした。過去のアプローチでは以下の課題がありました。
- アプローチ 1(単一 Blobs):整合性は保つが、条件付き書き込みが 1 つだけのため、スループットが毎秒数百回程度に制限。
- アプローチ 2(複数セグメント):スループットは上がるが、読み込みで全セグメントチェックが必要となり、最悪の遅延が発生。
解決策として、参照専用のレプリケートされたログサービス Ref-CAS を採用しました。
Ref-CAS の仕組み
- クォーラムベース: 参照更新はクォーラムによりコミットされる compare-and-swap です。ロック範囲を最小限に抑え、並列実行可能。
- バージョン管理: 各コミットにはログシーケンス番号(LSN)が付き、リポジトリの最新バージョンを示します。
- 追いついている場合: 単なる比較のみで済みます。
- 追いついていない場合: パックデータへのポインタや最終ガベージコレクションサイクル情報を受け取って追従します。
- データ分離: Ref-CAS はデータ自体を保持せず、オブジェクトへのポインタのみを格納します(バーチャルレピカがパックをアップロード後、参照はその永続化されたオブジェクトにだけ指す)。
これにより、数万回の操作をトランザクトでき、読み込み側は必要なデータを判断できるようになりました。
原則 2:ストレージとコンピュートの非同期化(毎秒数千回書き込み時のコンパクション)
各プッシュで Blob Storage に追加されるパック数は増えるため、ルックアップコストが増大します。これに対処するため、コンパクションとガベージコレクションの処理を バックグラウンド・専用ノード で行います。
コンパクションノードのフロー
- リース取得: Blob Storage 内のシャードへのリースを取得(一度に 1 つのみ)。
- パック収集: バーチャルレピカがアップロードしたパックをマニフェストから読み取り、オープンセグメントへ集める。
- 封鎖(Seal)と結合: セグメント定義(パックス数、サイズなど)に達すると封鎖し、複数のパックを少ない大きなパックへ結合。
- 重複チェック: 公開前に新規パックに入力と同じオブジェクトが含まれていないか確認。
- アップロード・マニフェスト更新: 新しいパックをアップロードし、マニフェストに追加。
- 不要データ削除: 入力データをマニフェストから削除。
効果とスケールアウト
- 独立実行: プロセスが多数のシャードに対して同時並行で行われるため、スループットが増加。
- 実質的なパック数平坦化: コンパクションによりパック数は増えすぎず、プッシュ増加に伴うレイテンシ曲線を平坦に保つことができます。
- ガベージコレクション: 専用ワーカーで処理し、参照されていないオブジェクトを安全に削除。
これらの最適化により、書き込み増加にも関わらず一貫したレイテンシを保ちつつ、パフォーマンスを維持しています。
次に何が起こるのか
2 つの原則により、アーキテクチャの各部分は独立して拡張可能です。目標は「サイドプロジェクトから大規模モノレポまで」全てのリポジトリが同じアーキテクチャで動作することです。移行や特別扱いなしにスケーリングし、一人の開発者からエージェント機動隊への変化を即座に対応します。
アーキテクチャの改善(予定)
- 必要なもののみを読み込む: オブジェクト全体ではなく、単一のオブジェクトのみフェッチ。
- パックのタイプ別整理: コミット・ツリー・ブロブを個別にグループ化し、データ接触を削減。
- 部分的なレプリカ: ローカルディスク上の全パックなしでリクエストに対応。
- マテリアライズされたビュー: アーカイブやデフォルトブランチの浅いコピーを維持。
- グローバルレプリカ: リプレピアをリージョンに配置し、古さ(staleness)を保ったまま最新データを提供。
- ゼロへのスケーリング: 機動隊規模を実際の負荷に合わせて縮小可能。
GitHub 上での効率的なエージェント操作
- クローンなしでの作業: 完全なワーキングツリー不要。必要な文脈のみサーバーから直接読み込み。
- 原子コミット API: マルチファイル変更を一回の操作で適用(衝突時は cleanly 拒否)。
- イベントストリーム: リアルタイム情報購読により、変更発生直後の反応を実現。
エージェント向けの Git 改善
GitHub は Git プロジェクトへのコントリビューターとしても進化し続けています。
- 軽量クローンの最適化: Partial Clone, Shallow Clone, Sparse Checkout の互換性向上。
- 隠れたスケーリングコストの削除: リポジトリ成長に伴う遅延要因の継続的な見つけ出しと修正。
- 高速な履歴トラバーサル: メタデータを活用し、マージベースや到達可能性質問を高速化。
- 一般的な落とし穴の回避: エージェントが犯しやすい Git 過ちに対する事前警告機能の実装。
エージェントはソフトウェア構築方法を根本から変えました。この新たなアーキテクチャをスタートラインに送り出しています。現在では限られたプライベートプレビューとして利用可能で、年内の早い段階でのより広範な展開が予定されています。リポジトリ上で作業するエージェントの数がアイデアによってのみ制限される未来に期待しています。