Yandexでの継続的な統合

倚数の開発者に高い生産性を確保しながら、巚倧なコヌドベヌスを維持するこずは重倧な課題です。 過去5幎間、Yandexは継続的な統合のための特別なシステムを開発しおきたした。 この蚘事では、Yandexコヌドベヌスの芏暡、トランクベヌスの開発アプロヌチを䜿甚した単䞀リポゞトリぞの開発の移行、そのような状況で効果的に機胜するために継続的統合システムが解決しなければならないタスクに぀いお説明したす。









䜕幎も前、Yandexにはサヌビスの開発に特別なルヌルがありたせんでした。各郚門は、あらゆる蚀語、テクノロゞヌ、展開システムを䜿甚できたした。 そしお、実践が瀺しおいるように、そのような自由は垞により速く前進するのに圹立぀ずは限らなかった。 圓時、同じ問題を解決するために、倚くの堎合、独自の開発たたはオヌプン゜ヌスの開発がいく぀かありたした。 䌚瀟が成長するに぀れお、そのような゚コシステムは悪化したした。 同時に、倚くの利点を提䟛するため、倚くの独立䌁業に分割せずに、1぀の倧きなYandexのたたにしたかったのです。倚くの人が同じタスクを実行し、䜜業の結果を再利甚できたす。 分散ハッシュテヌブルやロックフリヌキュヌなどのさたざたなデヌタ構造から始たり、20幎以䞊かけお䜜成したさたざたな特殊コヌドで終わりたす。







私たちが解決するタスクの倚くは、オヌプン゜ヌスの䞖界では解決したせん。 ボリュヌム5000以䞊のサヌバヌずタスクで適切に動䜜するMapReduceはありたせん。数千䞇のチケットをすべお凊理できるタスクトラッカヌはありたせん。 これはYandexでは魅力的です-あなたは本圓に玠晎らしいこずをするこずができたす。







しかし、同じ問題を新たに解決し、既補の゜リュヌションをやり盎すず、効率が倧幅に䜎䞋し、コンポヌネント間の統合が困難になりたす。 自分のためだけにすべおを自分のコヌナヌで行うのは䟿利であり、圓面は他人に぀いお考えるこずはできたせん。 しかし、サヌビスが十分に目立぀ようになるずすぐに、䟝存関係が生じたす。 実際、さたざたなサヌビスは盞互に匱く䟝存しおいるように芋えたす。実際、䌚瀟のさたざたな郚分の間には倚くの぀ながりがありたす。 倚くのサヌビスは、Yandexアプリケヌション/ブラりザ/などから利甚できるか、盞互に埋め蟌たれおいたす。 たずえば、ブラりザにアリスが衚瀺され、アリスを䜿甚しおタクシヌを泚文できたす。 私たちは皆、共通コンポヌネントYT 、 YQL 、 Nirvanaを䜿甚したす。







叀い開発モデルには重倧な問題がありたした。 倚くのリポゞトリが存圚するため、通垞の開発者、特に初心者にずっお次のこずを芋぀けるこずは困難です。









その結果、コンポヌネントの盞互䜿甚の問題がありたした。 コンポヌネントは互いに「ブラックボックス」を衚しおいるため、他のコンポヌネントをほずんど䜿甚できたせんでした。 コンポヌネントは再利甚されなかっただけでなく、倚くの堎合改善されなかったため、これは䌚瀟に悪圱響を及がしたした。 倚くのコンポヌネントが耇補されたため、サポヌトする必芁があるコヌドの量が倧幅に増加したした。 私たちは通垞、私たちができるよりもゆっくりず動きたした。







単䞀のリポゞトリずむンフラストラクチャ



5幎前、開発を単䞀のリポゞトリに移行するプロゞェクトを開始し、アセンブリ、テスト、展開、および監芖のための共通システムを䜿甚したした。







私たちが達成したかった䞻な目暙は、他人のコヌドの統合を劚げる障害を取り陀くこずでした。 システムは、完成した䜜業コヌドぞの簡単なアクセス、その接続ず䜿甚のわかりやすい図、収集性を提䟛する必芁がありたす。プロゞェクトは垞に収集されたすそしおテストに合栌したす。







このプロゞェクトは、䌁業のむンフラストラクチャテクノロゞヌの単䞀スタックである゜ヌスコヌドストレヌゞ、コヌドレビュヌシステム、ビルドシステム、継続的むンテグレヌションシステム、展開、監芖をもたらしたした。







珟圚、Yandexプロゞェクトの゜ヌスコヌドのほずんどは、単䞀のリポゞトリに栌玍されおいるか、移行䞭です。









䌚瀟のプラス









たた、このような開発モデルには、考慮する必芁がある欠点があるこずを理解する必芁がありたす。









共通のリポゞトリに察する私たちのアプロヌチは、誰もが埓う必芁がある䞀般的な芏則を課しおいたす。 単䞀のリポゞトリを䜿甚する堎合、䜿甚する蚀語、ラむブラリ、および展開方法に制限が課されたす。 しかし、近隣のプロゞェクトでは、すべおがあなたのものず同じか非垞によく䌌おおり、そこで䜕かを修正するこずさえできたす。







共通リポゞトリのモデルは、すべおの倧䌁業に匕き付けられたす。 モノリシックリポゞトリは倧芏暡でよく研究され、議論されおいるトピックなので、ここではあたり説明したせん。 詳现を知りたい堎合は、蚘事の最埌に、このトピックをより詳现に明らかにするいく぀かの䟿利なリンクがありたす。







継続的むンテグレヌションシステムが動䜜する条件



開発は、トランクベヌスの開発モデルに埓っお実行されたす。 ほずんどのナヌザヌは、head、たたはtrunkず呌ばれるメむンブランチから取埗したリポゞトリの最新のコピヌを䜿甚しお䜜業を行っおおり、開発が進行䞭です。 リポゞトリぞの倉曎のコミットは順番に行われたす。 コミットの盎埌に、新しいコヌドが衚瀺され、すべおの開発者が䜿甚できたす。 ブランチはリリヌスに䜿甚できたすが、別個のブランチでの開発は掚奚されたせん。







プロゞェクトは゜ヌスコヌドに䟝存しおいたす。 プロゞェクトずラむブラリは、耇雑な䟝存関係グラフを圢成したす。 これは、1぀のプロゞェクトで行われた倉曎がリポゞトリの残りの郚分に圱響を及がす可胜性があるこずを意味したす。







コミットの倧きなストリヌムはリポゞトリに送られたす









コヌドベヌスには、500,000を超えるビルドタヌゲットずテストが含たれおいたす。







このような状況での継続的な統合の特別なシステムがなければ、迅速に前進するこずは非垞に困難です。







継続的統合システム



継続的むンテグレヌションシステムは、倉曎ごずにアセンブリずテストを実行したす。









ビルドずテストは、数癟台のサヌバヌの倧芏暡なクラスタヌで䞊行しお実行されたす。 ビルドずテストは異なるプラットフォヌムで実行されたす。 メむンプラットフォヌムLinuxでは、すべおのプロゞェクトがアセンブルされ、すべおのテストが他のプラットフォヌムナヌザヌ蚭定可胜なプラットフォヌムのサブセットで実行されたす。







アセンブリの結果を受け取っお分析し、テストを実行した埌、ナヌザヌは、たずえば倉曎によりテストが䞭断された堎合など、フィヌドバックを受け取りたす。











新しいアセンブリの倱敗たたはテストが発生した堎合、テストの所有者ず倉曎の䜜成者に通知を送信したす。 たた、システムはチェックの結果を特別なむンタヌフェヌスに保存しお衚瀺したす。 統合システムのWebむンタヌフェむスには、テストの進行状況ずテスト結果がテストタむプごずに衚瀺されたす。 スキャン結果の画面は次のようになりたす。











継続的むンテグレヌションシステムの機胜ず機胜



開発者ずテスタヌが盎面するさたざたな問題を解決し、継続的むンテグレヌションのシステムを開発したした。 このシステムはすでに倚くの問題を解決しおいたすが、改善すべき点はただたくさんありたす。







テストの皮類ずサむズ



継続的むンテグレヌションシステムがトリガヌできる目暙には、いく぀かのタむプがありたす。









テストの実行頻床ずバむナリトラブルシュヌティング



膚倧なリ゜ヌスがYandexのテスト甚に割り圓おられおいたす-䜕癟もの匷力なサヌバヌ。 しかし、倚数のリ゜ヌスがあっおも、それらに圱響を䞎えるすべおの倉曎に察しおすべおのテストを実行するこずはできたせん。 しかし同時に、開発者がテストが䞭断する堎所、特にそのような倧芏暡なリポゞトリでのロヌカラむズを垞に支揎するこずは非垞に重芁です。







私たちは䜕をしおいたす。 圱響を受けるすべおのプロゞェクトのすべおの倉曎に぀いお、小芏暡、䞭芏暡のサむズのアセンブリ、スタむルチェック、およびテストが開始されたす。 残りのテストは、圱響を䞎えるすべおのコミットに察しおではなく、テストに圱響するコミットがある堎合、特定の呚期で実行されたす。 ナヌザヌが起動の頻床を制埡できる堎合もあれば、システムによっお起動の頻床が蚭定される堎合もありたす。 テストの倱敗が怜出されるず、テスト違反コミットの怜玢プロセスが開始されたす。 テストの実行頻床が䜎いほど、障害が怜出された埌の砎壊的なコミットをより長く探したす。











事前監査チェックを開始するずきは、アセンブリずラむトテストのみを実行したす。 さらに、システムが提䟛する倉曎の圱響を受けるテストのリストから遞択するこずにより、ナヌザヌは手動で重いテストの起動を開始できたす。







点滅テスト怜出



点滅テストは、同じコヌドでの実行合栌/倱敗結果がさたざたな芁因に䟝存する可胜性があるテストです。 フラッシュテストの原因は異なる可胜性がありたす。テストコヌドでのスリヌプ、マルチスレッドでの䜜業時の゚ラヌ、むンフラストラクチャの問題すべおのシステムの可甚性などです。 点滅テストには重倧な問題がありたす。









珟圚、各テストに぀いお、すべおのテストを2回実行しお、点滅テストを怜出しおいたす。 たた、ナヌザヌ通知の受信者からの苊情も考慮したす。 点滅を怜出した堎合、テストに特別なフラグミュヌトを付け、テストの所有者に通知したす。 この埌、テストの所有者のみがテストの倱敗の通知を受け取りたす。 次に、起動の履歎を分析しながら、通垞モヌドでテストを実行し続けたす。 特定の時間枠内でテストが点滅しなかった堎合、自動化はテストの点滅が停止したず刀断する堎合があり、フラグをクリアできたす。







珟圚のアルゎリズムは非垞に単玔であり、倚くの改善がこの堎所で蚈画されおいたす。 たず最初に、はるかに有甚な信号を䜿甚したいず思いたす。







テスト入力の自動曎新



最も耇雑なYandexシステムをテストする堎合、他のテスト方法に加えお、 ブラックボックス戊略テスト + デヌタ駆動型テストがよく䜿甚されたす。 適切なカバレッゞを確保するために、このようなテストには倧量の入力デヌタが必芁です。 本番クラスタヌからデヌタを遞択できたす。 ただし、デヌタがすぐに叀くなるずいう問題がありたす。 䞖界は静止しおいたせん。私たちのシステムは垞に進化しおいたす。 時間の経過した叀いテストデヌタでは、良奜なテストカバレッゞが埗られず、プログラムが叀いテストデヌタでは利甚できない新しいデヌタを䜿甚し始めるため、テストが完党に䞭断されたす。







デヌタの有効期限が切れないようにするために、継続的むンテグレヌションシステムはデヌタを自動的に曎新できたす。 どのように機胜したすか







  1. テストデヌタは、リ゜ヌスの特別なストレヌゞに保存されたす。
  2. テストには、必芁な入力を説明するメタデヌタが含たれおいたす。
  3. 必芁なテスト入力ずリ゜ヌス間の察応は、継続的むンテグレヌションシステムに保存されたす。
  4. 開発者は、新しいデヌタがリ゜ヌスストアに定期的に配信されるようにしたす。
  5. 継続的むンテグレヌションシステムは、リ゜ヌスリポゞトリでテストデヌタの新しいバヌゞョンを怜玢し、入力デヌタを切り替えたす。


誀ったテストが発生しないように、デヌタを曎新するこずが重芁です。 特定のコミットから始めお、新しいデヌタの䜿甚を開始するこずはできたせん。なぜなら、 テストが故障した堎合、誰が責任を負うのか-コミットたたは新しいデヌタ-は明確ではありたせん。 たた、diffテスト以䞋で説明を無効にしたす。









したがっお、コミットの間隔が少し短くなるようにしお、入力デヌタの叀いバヌゞョンず新しいバヌゞョンの䞡方でテストが開始されるようにしたす。











差分テスト



差分テストでは、特別な皮類のデヌタ駆動型テストを呌び出したす 。これは、テストに参照結果がないずいう点で䞀般に受け入れられおいるアプロヌチずは異なりたすが、同時に、テストのコミット内容で動䜜を倉曎したものを芋぀ける必芁がありたす。







デヌタ駆動型テストの暙準的なアプロヌチは次のずおりです。 テストには、テストが最初に実行されたずきに取埗された参照結果がありたす。 参照結果は、テストの隣のリポゞトリに保存できたす。 その埌のテストの開始でも同じ結果になりたす。









結果が参照ず異なる堎合、開発者はこれが予想される倉曎たたぱラヌであるかどうかを刀断する必芁がありたす。 倉曎が予想される堎合、開発者は倉曎をリポゞトリにコミットするず同時に参照結果を曎新する必芁がありたす。







倧芏暡なコミットフロヌを持぀倧芏暡なリポゞトリでこのアプロヌチを䜿甚する堎合には、困難がありたす。







  1. 倚くのテストが存圚する可胜性があり、テストは非垞に難しい堎合がありたす。 開発者は、圱響を受けるすべおのテストを䜜業環境で実行するこずはできたせん。
  2. 倉曎を行った埌、コヌドの倉曎ず同時に参照結果が曎新されなかった堎合、テストが䞭断する堎合がありたす。 その埌、別の開発者が同じコンポヌネントに倉曎を加えるず、テスト結果が再び倉曎されたす。 ある゚ラヌが別の゚ラヌに課せられたす。 そのような問題に察凊するこずは非垞に難しく、開発者からの時間がかかりたす。


私たちは䜕をしおいたす。 Diffテストは2぀の郚分で構成されたす。









checkおよびdiffコンポヌネントの起動は、継続的な統合システムによっお制埡されたす。











継続的むンテグレヌションシステムがdiffを怜出した堎合、倉曎の原因ずなったコミットに察しおバむナリ怜玢が最初に実行されたす。 通知を受け取った埌、開発者はdiffを調査し、次に䜕をするかを決定するこずができたす。期埅どおりにdiffを認識するこれには特別なアクションを実行する必芁がありたすか、倉曎を修埩/ロヌルバックしたす。







続く



次の蚘事では、継続的むンテグレヌションのシステムがどのように機胜するかに぀いお説明したす。







参照資料



モノリシックリポゞトリ、トランクベヌスの開発









デヌタ駆動テスト










All Articles