「1つのバスケット」:コードの保存について少し

効果的なデータストレージは、何らかの形でITに接続しているすべての人の関心を引きます。 1cloud IaaSプロバイダーでは 、同僚の経験常に分析しています。最近、大企業がどのようにデータを保存するかを議論しました。



今日はこのトピックを続け、1つのリポジトリまたは複数のリポジトリにコードを保存する最善の方法について説明します。 また、両方のアプローチの特徴を示す2つの例を見てみましょう。







/写真デニス・スクレイ CC



ソースを単一のモノリシックリポジトリに保存する必要がありますか、それともコードをブロックに分割して複数の異なるリポジトリに書き込む必要がありますか? 原則として、それはチームとそれが動作しているプロジェクトに依存します。 まず、両方のタイプのストレージの長所と短所を考慮してください。



モノリシックリポジトリ



通常、最初に頭に浮かぶのは、少なくとも最初の段階で、すべてのコードを1つのリポジトリに書き込むことです。ほとんどのプロジェクトはそこから始まります。 リポジトリは、2つ以上の別個のプロジェクトを格納する場合、モノリシックと呼ばれます。 これらのプロジェクトは弱くまたは完全に接続されておらず、リポジトリ自体に含まれるファイル、コミット、その他のオブジェクトが多すぎます。



コードを単一のリポジトリに格納する主な利点は、コードとのコラボレーションを整理することがはるかに簡単になることです。 複数のサブプロジェクトで構成される1つの共通プロジェクトを作成してから、これらのサブプロジェクトをリンクすると便利です。



開発者がコードまたはプロジェクトの部分間の通信の原則を変更する必要がある場合、プロジェクト全体のコードにアクセスできる場合、これを行うのが簡単です。 マイクロサービスアーキテクチャ上に構築されたオンライントレーディングシステムを作成しているとします。 バスケットサービス用のコードを作成し、共有ライブラリを表示または変更する必要がある場合は、すぐにアクセスできます。別のプロジェクトやリポジトリを開く必要はありません。 依存関係を編集できるため、バージョン管理を気にせずにグローバルな変更をより迅速に行うことができます。



すべてのコードが1か所に保存されたら、プロセスを開始し、たとえば、共有ライブラリの変更がバスケットの作業にどのように影響するかを監視するだけです。 オブジェクトはいつでもどこからでも利用でき、変更は迅速かつ簡単です。 しかし、すべてがそれほどスムーズではありません。



多くの場合、マネージャーは単一のリポジトリーを選択するのは、それを使用する方が簡単だからです。 そのような決定のため、開発者が触れてはならないコードの部分に変更を加える場合がより頻繁にあります。 また、コード全体にアクセスでき、プロジェクトに明確に定義された境界がない場合、これは簡単です。



展開とスケーリングには多くの問題が発生します。 したがって、システムの整合性が失われます。 リポジトリが大きいほど、チェックが遅くなります。 コードが複数のリポジトリに保存されている場合、プロセスを並列化でき、プロジェクトの一部で発生したエラーがすべてのサービスの作業を台無しにすることはありません。



結論:小規模なチームがある場合、または拡張しない場合は、すべてのコードを1か所に保存する方が論理的です。 マイクロサービスを使用していないが、モノリシックアプリケーションを開発している場合にも、単一のリポジトリを使用すると便利です。



Gitのモノリシックリポジトリ(大きなファイルサイズ、コミットとポインターの数)Habrユーザーの欠点を軽減するためのヒントを以下に示します。



コードを複数のリポジトリに保存する



単一のリポジトリーがある場合に発生する問題の一部は、いくつかのリポジトリーの導入によって解決されます。 マイクロサービスについて話す場合、理想的には、各サービスに独自のリポジトリが必要です。 このアプローチにより、バージョン管理プロセスが容易になります。ライブラリに変更を加え、バージョンを更新し、サービスコードを微調整し、バージョンを更新しました。



いくつかのリポジトリが存在するため、サードパーティの開発者がコードを表示するかのようにコードを書く必要があります(ちなみに、これは可能性が高いです)。 開発者は、コードの変更をプログラム全体の大規模な変更と考える代わりに、システム全体の動作に影響を与えずに1つのモジュールを変更する方法について考え始めます。 その結果、モジュール間の接続が弱まります。



これにより、相互に独立して展開できます。 チェックアウトサービスが両方のバージョンのプロトコルで動作する場合、バスケットコードが修正される前に展開できます。 このアプローチには、高度な規律が必要です。



結論:チームが定期的なバージョンの更新をサポートし、マイクロサービスを使用するのに十分な経験がある場合、または小さなグループに編成されている人が多い場合は、コードを複数のリポジトリに保存することをお勧めします。 このアプローチは、バージョンを更新し、サービス間の境界を維持するためのルールに従えば、規律が厳しくなる新入社員のトレーニングにも役立ちます。



GoogleおよびKilnコードの保存方法



なされた結論から判断すると、ほとんどの企業、特に大企業は、いくつかのリポジトリで作業することを好むでしょう。 それでも、この規則には少なくとも1つの大きな例外があります。 奇妙なことに、今日、数万人のGoogle開発者が、約20億行のコードを格納するモノリシックリポジトリを使用しています。 この規模を維持するために、GoogleはPiperとして知られるバージョン管理システムを開発する必要がありました。



Piperへのアクセスは、クラウドストレージとLinux用のFUSEファイルシステムで構成されるクラウド内クライアント(CitC)システムを使用して構成されます。 各開発者には、自分が変更したファイルを保存する作業環境があります。 記録されたすべてのファイルはスナップショットとしてCitCに保存されます。これにより、必要に応じて数ステップ前の作業を「ロールバック」できます。



CitCに組み込まれているCodeSearchコード検索ツールを使用すると、コードを少し修正するだけでなく、自動コミットの可能性がある検証用に変更されたコードを送信できます。検証に合格すると、テストが実行され、その後システム自体がコミットします。



モノリシックリポジトリモデルの基礎は、トランクベースの開発(「トランク開発」)と呼ばれるアプローチです。 メイン(トランク)行コードの最新バージョンであり、変更は1回限りで順番に行われます。 コミットの直後に、すべてのPiperユーザーが新しいバージョンのコードを利用できます。つまり、実際には、開発者は常に新しいバージョンのコードを目の前に持っています。



機能の追加に関しては、古いコードと新しいコードの両方が互いに並行して存在し、それらの使用は構成フラグを使用して制御されます。 このアプローチは、変更のマージから生じる問題を回避します。



Stack Overflowユーザーは、コードを複数のリポジトリに分割できる場合でも、単一のリポジトリにコードを保存することをお勧めします。 これには、Gitのサブモジュール、Subversionの外部オブジェクト、Mercurialのサブリポジトリなどのツールがあります。



それらはすべて、大規模プロジェクトの内部階層を構築するように設計されており、個々のモジュールを分離するために使用できます。各プロジェクトを個別のリポジトリに配置し、サブモジュールを使用して階層の特定のレベルに必要なプロジェクトを含めます。



さらに、Gitには独立したブランチを作成する機能があり、これはオーファン(オーファン)と呼ばれます。 彼らは互いに関係がなく、排他的に彼らの歴史を保ちます。 これにより、新しい孤立ブランチが作成されます。



git checkout --orphan BRANCHNAME
      
      





個々のプロジェクトは、個別の孤立ブランチとして表すことができます。 何らかの理由で、Gitでは、このブランチを作成した後にこのクリーンアップを行う必要があります。



 rm .git/index rm -r *
      
      





クリーニングする前に、適切なコミットが設定されていることを確認してください。 その後、ブランチを安全に使用できます。

別のオプションは、いくつかのリポジトリを作成し、これらのブランチをそれぞれにドロップすることです(リポジトリの名前は一致しないはずです):



 # repo 1 git push origin master:master-1 # repo 2 git push origin master:master-2
      
      





かつてモノリシックSubversionリポジトリからMercurialマルチリポジトリに切り替えたKiln開発者は、コードストレージについて異なる意見を持っています。 プロジェクトは、exeクライアント、クライアントインタラクション用サーバー(Reflector)、Webサイト、課金システム、およびAadvarkライブラリの5つの部分に分かれています。



各パーツについて、develとstableの2つのリポジトリを作成しました。 最初の機能には新しい機能が含まれており、しばらくしてから2番目の機能に移り、逆に修正されたバグは最初に安定版に置かれ、次に新しい機能としてdevelに返されます。 タグは同期に使用されます。 Mercurialでは、これらはリポジトリメタデータです。



たとえば、サイトの新しいバージョンを展開するには、リポジトリwebsite-stableおよびaadvark-stableが使用されます。 各タグは、たとえばWebsite-000123に添付されます。 次に、ビルドプロセスが開始され、サーバーからビルドディレクトリに両方のリポジトリが複製され、hg up –C Website-000123コマンドが実行されて、ローカルコピーが目的のタグに切り替えられます。 ビルドを収集した後、展開が実行されます。



おわりに



コードを保存する場所と方法の選択には意味のあるアプローチが必要であり、これには多少の努力が必要です。 これは、あるアプローチが別のアプローチより明らかに優れていると言うことではありません。 チームの構成、経験、目標を考慮し、これに基づいて決定を下す必要があります。 さらに、必要に応じて、1つのリポジトリから複数のリポジトリに、またはその逆にいつでも切り替えることができます。



いずれにしても、理解には経験が必要です。 後で何を恐れるか、どの方法がおそらく機能するかを知るために、コーンを埋めることが役立つ場合があります。 したがって、あなたのチームにより適しているものを本当に理解するために、製品の開発に最大限の貢献をする時間とすべての人の欲求が役立ちます。



PS IaaSプロバイダー1cloudの開発に関する資料:





PPSクラウド神話神話の新しいシリーズ:






All Articles