CTC 教育サービス
[IT研修]注目キーワード Python UiPath(RPA) 最新技術動向 Microsoft Azure Docker Kubernetes
今回から2回に渡り、2016年に公開された学術記事「Why Google Stores Billions of Lines of Code in a Single Repository」をもとにして、Google社内で利用されているソースコード管理システムのPiperとCitCを紹介します。この記事では、Googleにおけるソースコード管理の仕組みやPiper/CitCの機能に加えて、そのメリット/デメリットが議論されています。
今回は、まずは、Googleにおけるソースコード管理の仕組みと、その考え方を紹介していきます。
Googleのソースコード管理では、Piperと呼ばれるシステムにより、すべてのソフトウェアのソースコードが単一のリポジトリで管理されているという、大きな特徴があります。GitHubのように、ソフトウェアごとにリポジトリを分けるのでなく、1つの巨大なリポジトリ内に、ディレクトリーを分けるかたちで、すべてのソフトウェアのソースコードが保存されています。図1は、2015年1月時点でのリポジトリの利用状況を示すデータですが、ソースコードが約900万ファイルで、1日あたり4万個のコミット(ファイルの変更)があります。
図1 ソースコードリポジトリの利用状況(記事より抜粋)
このリポジトリ内のソースコードは、約25,000人のソフトウェア開発者が利用しており、1日の4万個のコミットの内、開発者が手動でコミットするものは約1万6千個で、残りは、自動化システムによるものです。これらのソースコードは、独自の分散ビルドシステムからもアクセスされており、1日平均で秒間約50万アクセス、ピーク時には、秒間約80万アクセスがあるそうです。
図2は、1週間あたりのコミット数の変化を示したグラフですが、2012年にソースコード管理の自動化を導入しており、それ以降、自動化システムによるコミット数が大きく増加していることがわかります。ちなみに、年に数回、コミット数が大きく減少しているのは、クリスマスなどの主要な休暇によるものだそうです。
図2 1週間あたりのコミット数の変化(記事より抜粋)
ソフトウェア開発者がソースコードの修正を行う際は、図1に示したリポジトリ上の「10億個のすべてのファイル」を作業用ワークステーションにコピーした後に、このローカルコピーに修正を加えます。―― と言っても、本当に物理的なコピーを行うわけではありません。CitC(Clients in the Cloud)と呼ばれるシステムを使って、リポジトリのスナップショットコピーを作成した後、それをネットワーク経由でLinuxワークステーションのディレクトリー上にマウントします。これにより、ソフトウェア開発者は、あたかもローカルにすべてのソースコードファイルがあるかのように、ファイルの検索、閲覧、修正ができるようになります。このスナップショットは、いわゆる「CoW(Copy on Write)方式」のもので、実際に修正したファイルの差分のみがクラウド上のストレージ領域に保存されます。
また、同一のスナップショットを複数の開発者のワークステーションに同時にマウントすることもできます。この機能を利用して、開発中のコードを相互に確認するなどが可能になります。スナップショットコピーそのものはクラウド環境上にあるため、1人の開発者が、複数の場所にあるワークステーションから、同一のスナップショットを用いて開発作業を進めることも簡単にできます。
修正したソースコードをリポジトリにコミットする際は、必ず、コードレビューシステムによるレビュープロセスが入ります。スナップショットコピー上に存在するレビュー中のコードは、レビューシステムからもアクセスできるようになっており、簡単な修正については、レビューシステムから直接に行うことも可能です。レビューが完了すると修正がコミットされるわけですが、この処理は、レビューの完了と同時に自動で行うように設定することもできます。これら全体の流れは、図3のようにまとめられます。
図3 Piperによるコード開発の流れ(記事より抜粋)
また、ソースコードのコミットに伴うテスト処理も自動化されています。まず、ソースコードがコミットされる前に、コードの自動分析処理が走ります。ここでは、すべてのコードに共通の分析処理が用意されており、さらに、コードのオーナーが独自の分析/テストを追加することもできます。そして、ソースコードの修正がコミットされると、その変更に影響を受けるすべてのバイナリファイルについて、再ビルドと再テストの処理が自動で行われます。ここで大きな問題が発見された場合は、コミットの取り消しが行われます。
Googleのソフトウェア開発では、単一のリポジトリを使用することに加えて、トランクベースの開発を行うという特徴があります。ここでいうトランクは、Gitにおけるマスターブランチに相当するものです。一般に、Gitを使った開発では、機能ごとに開発用のブランチを作成して、開発ブランチ上で複数のコミットを行った後、最後に、開発ブランチの内容をマスターブランチにまとめて反映します。一方、Googleでは、そのような事は行いません。基本的にすべての修正は、トランク(マスターブランチ)に直接に反映されます。
特に、新機能を追加する際は、機能追加前と追加後の両方のコードをソースコード内に残しておき、設定ファイルのフラグによって、新機能の有効化/無効化を指定できるようにしておきます。これには、新機能に問題が発見されて、一時的に以前の状態に戻したいという際に、古いソースコードから再ビルドするのではなく、設定ファイルの変更だけで機能を無効化できるというメリットがあります。この手法は、一部のユーザーのみに機能を有効化して行う、A/Bテストなどにも利用されています。
それでは、このようなトランクベースの開発を行うのは、どのような理由によるものなのでしょうか? これには、すべてのソフトウェアについて、すべての開発者が必ず同じ状態を見ることができるというメリットがあります。Googleのソフトウェア開発者は、自分が担当するソフトウェアに限らず、あらゆるソフトウェアのソースコードを見て、問題や改善点を発見した場合は、修正を提案することができます。Piperが管理するソフトウェアリポジトリ上では、ビジネスの根幹に関わるアルゴリズムを含むものなど、ごく一部のソースコードを除き、ほとんどすべてのソースコードは、すべての開発者から閲覧可能になっているのです。このような、開発チームをまたいだ協力を効率的に進める上で、全員が同一のトランクに対して修正を加えていくというモデルが役立つというわけです。また、同一のソースコードに対して、開発中のブランチが複数あると、複数のブランチをマージする際に不整合が発生することがあります。このような、ブランチマージの問題を回避できるというメリットもあります。
なお、新機能の開発はトランク上で行われますが、本番環境にリリースするコードについては、リリース用のブランチが別れています。トランク上でコードの変更が行われた後に、それが、リリースブランチに対しても反映される形になります。図4のように、必要な変更を選択して適用する、チェリーピックの作業が行われます。
図4 リリース用ブランチの管理モデル(記事より抜粋)
今回は、Piper/CitCを用いたGoogleのソースコード管理の仕組み、特に、その大きな特徴として、単一のリポジトリを用いたトランクベースの開発を紹介しました。図1にあるように、設定ファイルなどを含めて、10億ものファイルを単一のリポジトリで管理するというのはなかなか思いつかない発想かも知れません。Piper/CitCと言った独自の管理システムがなければ、実現できるものではないでしょう。
次回は、このような仕組みのメリット/デメリットについて解説を進めたいと思います。
Disclaimer:この記事は個人的なものです。ここで述べられていることは私の個人的な意見に基づくものであり、私の雇用者には関係はありません。
[IT研修]注目キーワード Python UiPath(RPA) 最新技術動向 Microsoft Azure Docker Kubernetes