エージェントスケールのGitインフラストラクチャへの架け橋
The bridge to agent-scale Git infrastructure (github.blog)
要約
GitHubは、指数関数的に増加するGitトラフィックに対応するため、リポジトリの大部分をデータセンターとAzureの両方に配置するアーキテクチャを採用しました。この移行の課題は、特に遅いレプリカによる25msのラウンドトリップ遅延が、書き込みスループットのボトルネックとなっていたことです。この問題を解決するため、GitHubはクォーラムの範囲をリポジトリ全体から個々の参照に変更し、書き込みの並列処理を大幅に改善しました。
全文翻訳
エージェントスケールのGitインフラストラクチャへの架け橋
過去1年間、Gitトラフィックが指数関数的に増加する中、GitHub上のGitリポジトリの99.99999%は、私たちのデータセンターとAzureの2か所に同時に存在していました。残りはプラットフォーム上で最もビジーなリポジトリの一部であり、それらを妨げているのはただ1つのこと、それは25msのラウンドトリップです。
以前のブログ記事で、私たちは次世代ストレージアーキテクチャの2つの原則を説明しました。
- コーディネーションを最小限に抑える
- ストレージとコンピューティングを分離する
この記事では、古い設計と新しい設計の間の直接的な架け橋に焦点を当てます。クォーラムが書き込みをシリアライズする方法の変更が、最もビジーなリポジトリをAzureにどのように取り込み、その同じステップが、独自の永続状態を保持しないレプリカへの道を開くかについて説明します。
ここに至るまで
移行のタイミングと形状は、エージェントシフトによって推進されました。トラフィックの急速な増加、データセンターと周辺地域の電力容量のハードリミット、そして物理的なサプライチェーンの制約です。移行開始時、可能な限りの拡張を含めた残りの容量は、安全に移行するのに十分な時間を提供しましたが、ゆっくりと移行するには十分ではありませんでした。
クラウドインフラストラクチャ上でGitをスケーリングするための新しいアーキテクチャアプローチをプロトタイプ化していましたが、その成長下でストレージアーキテクチャとホスティングプラットフォームを同時に変更することは、リスクが高すぎました。私たちの規模とサービスがコミュニティにとってどれほど重要であるかを考えると、作業を慎重にシーケンスする必要がありました。まずデータを移動し、それが到着してからアーキテクチャを進化させるという順序です。
Git操作はTier 0サービスです。GitHubのコア機能であり、GitHubのほぼすべてのものがリポジトリデータに依存しています。これは、データ、サービス、そしてすべての依存関係が最初に移動する必要があることを意味しました。リポジトリの最初のコピーは2025年8月にAzureのセントラルUSリージョンに配置されました。現在、ほとんどのリポジトリは5つのレプリカのうち2つをAzureに持ち、AzureはGitトラフィックの約半分を処理しています。この期間のほとんどの間、Azureは私たちの成長を吸収し、私たちのデータセンターは安定していました。
移行中、トラフィックはデータを追跡します。ほとんどのリポジトリは、耐久性、可用性、およびスケーリングのバランスを取るために5つのレプリカを持っています。読み取りレイテンシを最小限に抑えるために、Spokesは優先ルーティングを使用して、要求と同じリージョンとアベイラビリティゾーンにあるレプリカにトラフィックを向けます。レプリカがAzureに移動するにつれて、Azureから提供できるトラフィックのシェアは、最後のレプリカが到着して古いリージョンがリクエストの受信を完全に停止するまで、それぞれが増加します。すべてのリポジトリはこのプロセスを経ます。
[動画: リポジトリのレプリカがAzureに移動し、トラフィックがそれに続く様子を示すアニメーション]
置き去りにされたリポジトリはない
では、残りの0.00001%のリポジトリはどうでしょうか?
現在のアーキテクチャでは、複数のリージョンにホストされているリポジトリは、書き込みスループットの上限が低くなります。Spokesのクォーラムは書き込みをコミットするために過半数を必要とするだけですが、タイムアウトまでの間、すべての正常なレプリカが応答するのを待ってから先に進むため、遅いレプリカはすべての書き込みを遅延させ、遅れをとることはありません。実際には、最も遅い正常なレプリカがすべての書き込みのレイテンシを設定し、各書き込みはコミットされるまでリポジトリ全体のロックを保持するため、スループットの上限も設定します。レプリカがターゲットのAzureリージョンに配置されると、私たちのデータセンターから約1,000マイル離れているため、各ネットワークラウンドトリップは約25msになり、書き込みには複数のラウンドトリップが必要です。すでにスループット上限に近いリポジトリは、各シリアライズされた書き込みでその遅延を吸収できません。各プッシュでさらに遅れをとることになります。
ここで、私たちの最初の原則である「コーディネーションの最小化」が役立ちます。特にこのケースでは、「必要のないものをシリアライズしない」ということです。Gitの一貫性要件は、各参照に個別に適用されます。サーバーが参照の更新を受け入れたら、クライアントはいかなる場合も古い値を見るべきではなく、その値またはそれ以降の値のみを見るべきです。これは、更新がファストフォワード、フォースプッシュ、または削除であっても同様です。しかし、ほとんどの場合、異なる参照への更新は互いに依存せず、独立して適用できます。
そのため、クォーラムのスコープをリポジトリ全体から個々の参照に変更しています。
書き込み全体を、参照の更新全体(ラウンドトリップを含む)に対してロックすることで、クォーラムは単一の順序付けされていないリクエストキューになり、一度に1つの書き込みしかインフライトになりません。そのキュー内の各書き込みは、最も遅い正常なレプリカと同じ時間がかかります。
参照ごとのシリアライズにより、共有参照で競合する書き込みのみが互いに待機する必要があります。実際には、リポジトリへのほとんどの書き込みは異なる参照に触れます(例:エージェントと開発者がそれぞれのブランチにプッシュする)。そのため、それらは互いに待機しなくなります。各書き込みは依然としてクロスリージョンレイテンシを経験しますが、異なる参照への書き込みは同時にインフライトで実行できます。これにより、リポジトリに対する単一のボトルネックが解消されます。同様の負荷下で2つのアプローチを並べて比較することで、キューイングとタイムアウトがどのように蓄積するかを視覚化できます。
[動画: リポジトリ全体ロックと参照ごとのロックの比較]
これらの変更により、書き込み対象の参照数にほぼ比例してリポジトリの書き込みスループット上限が向上し、残りのリポジトリがAzureに取り込まれます。現実的なトラフィックを使用した内部テストでは、異なる参照への書き込みは、一貫して3〜4倍高いスループットと低いレイテンシを示しました。
読み取りのスケーリングを独立して行う
ほとんどのリポジトリは読み取りが非常に多く、書き込み1回あたり100〜1,000回の読み取りがあります。現在、読み取りと書き込みは同じレプリカにアクセスするため、同じリソースを競合し、独立してスケーリングできません。
ストレージとコンピューティングの分離はそれを変えます。リポジトリデータがAzure Blob Storageに耐久性をもって保存され、各受信書き込みで更新されると、読み取りトラフィックを書き込みクォーラムから分離し、それぞれに必要なコンピューティングを独立してスケーリングできるようになります。例えば、読み取りは現在提供しているものよりもはるかに多くのインメモリキャッシュから恩恵を受けることができますが、そのメモリはコンパクションにも必要です。分離されると、それぞれが独自の構成を持つようになります。
最初のステップは、オブジェクトストレージをクォーラムのメンバーにすることですが、これは「仮想レプリカ」と呼ぶ特別なメンバーです。それを表すコンピューティングは、私たちの最初の完全にエフェメラルなノードです。これはオブジェクトストレージへの架け橋として機能し、受信書き込みをストリーミングし、読み取りを提供しません。クォーラムのメンバーであるため、書き込みはオブジェクトストレージに耐久性があるまで確認されません。
これにより各書き込みのレイテンシがわずかに増加しますが、クロスリージョンラウンドトリップと同様に、参照ごとのシリアライズによりスループットのボトルネックになるのを防ぎます。仮想書き込みレプリカは、個別の参照のトランザクションをオブジェクトストレージへのネットワークI/Oの単一セットに統合するため、ビジーなリポジトリは書き込みごとのラウンドトリップではなく、多数の同時書き込みに対する1回のラウンドトリップで済みます。現時点では、仮想書き込みレプリカはコンパクションも処理し、読み取りレプリカはコンパクションされた状態を継承します。
仮想書き込みレプリカを配置することで、リポジトリが必要とする数の仮想読み取りレプリカをオンデマンドでスケールアウトできます。各読み取りレプリカはAzure Blob Storageからキャッシュをウォームアップし、クォーラムに参加せずに読み取りトラフィックの受信を開始します。オブジェクトストレージを真実の情報源として使用し、バックグラウンドでローカルの状態と同期します。
このステップは、読み取りスケーリングを大幅に向上させます。内部テストでは、分散ロードテストハーネスは現在のアーキテクチャで定期的に上限に達しました。仮想読み取りレプリカに対しては、ハーネス自体が最初に限界に達しました。また、後続のステップで解決されるいくつかの課題も伴います。
- 仮想読み取りレプリカはバックグラウンドでオブジェクトストレージと同期を開始するため、一部の読み取りワークロードには適していますが、すべてではありません。あらゆる種類の読み取りを提供するには、その同期をインラインに移動し、レプリカが最後に同期してから変更された参照状態とデータのみを取得する必要があります。
- 参照ごとのモデルへの移行により書き込みスループットは徐々に増加しましたが、クォーラムはさらなる増加の制約要因のままです。
書き込みスループットをさらに向上させるにはどうすればよいでしょうか?
次に来るもの
今日のGitHubはSpokesクォーラムの上に構築されており、長年にわたりSpokesは単なるクォーラムコーディネーター以上のものになりました。それはまた、インテリジェントなルーティングおよびロードバランシングレイヤー、内部クライアントが1日あたり1,000億以上の操作でリポジトリデータにアクセスおよびトランザクションするために使用する統一API、そしてリポジトリの配置、修復、ストレージノード間の再バランシングを処理する「スイーパー」と呼ばれるバックグラウンドシステムのコレクションでもあります。
Spokesサービスアンブレラの下にあるものの大部分は、既存のアーキテクチャと同様に新しいアーキテクチャにも適用されます。しかし、GitHubを10億リポジトリまで導いたコミットプロトコルが、次の10億リポジトリ以降には通用しないことも認識しています。
私たちはまだ終えていません。これらのステップを配置することで、次の限界は書き込みスループットです。すべての書き込みは、それぞれリポジトリの完全なコピーを保持するレプリカをまだ待っていますが、書き込みの実際にはほとんど順序付けられる必要はありません。Gitオブジェクトは不変であり、その内容によって名前が付けられているため、誰もそれらに同意することなく保存できます。残りは小さく、難しい部分はそれを可能な限り速く順序付けることです。ただし、ボトルネックを別の場所に移動しないようにする必要があります。ホワイトボードでそれを設計することは1つのことです。開発者やエージェントが24時間体制で書き込んでいる10億リポジトリの下でそれを実行することは別のことです。そこに至るために、耐久性のある参照状態がどこにあり、コンパクションとガベージコレクションがどのようにスケーリングするかといった、二次的な影響についても再考する必要がありました。
エージェントトラフィックは減速しておらず、これらの各ステップは、最終状態を待つことなく、リポジトリにヘッドルームを増やします。
来週公開: GitHub Universeとこのシリーズの最終記事で、その最終状態、書き込みスループットに何をもたらすか、そこに到達するために解決する必要があった二次的な問題、そしてなぜスタックのどこかに(小さな)コンセンサスグループがまだ存在するのかについて解説します。
この記事への貢献にBrian Celenza氏に感謝します。
執筆者
[画像: Eleanor White]
シニアソフトウェアエンジニア
[画像: Victoria Dye]
スタッフソフトウェアエンジニア
GitHubからさらに探る
[画像: Docs]
Docs
GitHubをマスターするために必要なすべてが1か所に。
ドキュメントへ移動
[画像: GitHub]
GitHub
GitHubで次を構築しましょう。どこからでも誰でも、あらゆるものを構築できる場所です。
構築を開始
[画像: Customer stories]
カスタマー事例
GitHubで構築する企業やエンジニアリングチームを紹介します。
詳細はこちら
[画像: GitHub Universe 2026]
GitHub Universe 2026
10月28〜29日にサンフランシスコまたはオンラインで開催されるGitHub Universeに参加しましょう。開発者、エージェント、そして世界のコードを結びつけるフラッグシップ開発者イベントです。
今すぐ登録