Upgrade to Pro — share decks privately, control downloads, hide ads and more …

CircleCIの実行時間を大幅に短縮した話

izumiiii
December 04, 2023
34

 CircleCIの実行時間を大幅に短縮した話

izumiiii

December 04, 2023
Tweet

Transcript

  1. Koizumi Fumiya 株式会社pring システム部 エンジニア 18年4月~ 国際学部(アラビア語専攻)卒 SES系企業にてRails案件常駐 20年11月~ 現職

    pringではAPI開発(Ruby on Rails)、フロントエンド開発 (React.js)等 OSS Contributors: Svelte.js, MDsveX, svelte-json-tree Svelte Advent Calendar 2020
  2. Copyright © pring Inc. All Rights Reserved Outline 4 1.

    はじめに 2. 開発環境 3. 改善のアプローチ手法 4. 改善結果① 5. CircleCIの最適化 6. 改善結果②
  3. Copyright © pring Inc. All Rights Reserved 6 はじめに pringのAPIプロジェクトで度々CircleCIの実行時間が長いと問題が上がっていた。

    CircleCIの実行履歴を見る限り、CIの実行順番待ちが1h~2hかかったりと開発効 率が低い状態にありました。 こういった背景もあり、CircleCIの改善対応をすることになった。
  4. Copyright © pring Inc. All Rights Reserved 9 開発規模 エンドポイント数

    - 229 テスト項目数 - 2886 CI実行時間 - 20~40分 コミッター数(直近の1ヶ月): - 10名
  5. Copyright © pring Inc. All Rights Reserved 12 改善のアプローチ手法 前職でもCI改善を行ってる作業に立ち会ったことがある関係で、ある程度の目星を

    付けていたのですが、、 何より改善のためには現在のCIの徹底的に解析する。これに尽きると思い、今回は ある程度時間かかってでも解析調査を優先した。 その後、問題のある箇所に対して修正を行うというアプローチで進めた。
  6. Copyright © pring Inc. All Rights Reserved 14 test-prof test-profはテストプロファイリングとテスト最適化のツールが揃っているGemです。

    ※遅いテストスイートを解析したり、rubocopと組み合わせてRSpecのコードを改善すること ができる。
  7. Copyright © pring Inc. All Rights Reserved 16 Factory Doctor

    テストを遅くする一般的なパターンの1つとして不要なデータベースクエリを発行してる ことが挙げられます。 Factory Doctorはその不要なクエリを実行するテストを特定するツールになります。 FDOC=1 rspec ….で実行することができます。
  8. Copyright © pring Inc. All Rights Reserved 17 before_all RSpecのbefore(:all)の場合、一括で前準備をしてくれるが作成したデータの破棄

    まで行ってくれない。。。 test-profのbefore_allを使えばデータ破棄までやってくれる。
  9. Copyright © pring Inc. All Rights Reserved 18 let_it_be 繰り返しデータ作成するのを防ぐためにbefore_allが既にあるが、こちらだと既存のlet

    で書かれているものをインスタンス変数に変えたりといろいろめんどくさくなってしまい ます。 そのめんどくさいリファクタリングを最小限に抑えることができるのが、let_it_beです。
  10. Copyright © pring Inc. All Rights Reserved 19 Rubocop cops

    test_prof/rubocopを使用して障害の集約を行う。 使用する際には、bundle exec rubocop -r ‘test_prof/rubocop’’ --only RSpec/AggregateExamples
  11. Copyright © pring Inc. All Rights Reserved 21 create系での改善結果 test-profによるcreate系のみの対応だけ全体で約5分の改善を行うことができた。

    Concepts admin - -3分5秒 auth - -15秒 bank - -21秒 external: - -35秒 payment - -10秒 talk - -26秒 user - -10秒
  12. Copyright © pring Inc. All Rights Reserved 23 CircleCI側での対応検討 test-profを使ってcreate系によるパフォーマンス問題は全体的に潰したが、、それでもまだ

    12〜13分かかってしまった。 これではだめだと思い、CircleCI側でもパフォーマンスをよくできないかと考えた。 下記リストは今回改善で行った対応内容になります。 1. テスト並列実行化 (CircleCI parallelism) 1. ビルドイメージの最適化(Pre built CircleCI images) 1. parallelismの最適化
  13. Copyright © pring Inc. All Rights Reserved 24 使用しなかったもの 1.

    Docker Layer Caching(DLC) - 1job実行で200クレジット消費してしまい最悪CI破産起きかねない。 - そこまで効果がなかった。 1. parallel_tests - CI側で並列ので十分だったので特に必要性を感じなかった。 ※ マルチコアCPUで並列実行テストを行えるGem
  14. Copyright © pring Inc. All Rights Reserved 25 Docker Layer

    Caching(DLC) CircleCIのジョブ中にビルドされたDockerイメージの個々のイメージレイヤーを保 存して、次回以降リビルドを行うのではなく未変更のイメージレイヤーを利用する 仕組みです。
  15. Copyright © pring Inc. All Rights Reserved 26 テスト実行並列化(CircleCI parallelism)

    CircleCI parallelismは.circleci/config.ymlにparallelismを指定することで簡単に テストを並行に実行することができ、実行時間を減らすことが出来ます。 言語にも依存していないため、どの言語であっても実行することができます。
  16. Copyright © pring Inc. All Rights Reserved 27 ビルドイメージ最適化(Pre built

    CircelCI images) テスト用にチューニングしたイメージがCircleCI側で提供されており、ベストプラクティス としても紹介されています。使用するのは簡単で対象のDocker Imageにcircleciと追記 するだけです。
  17. Copyright © pring Inc. All Rights Reserved 28 parallelismの最適化① 並列テストで最適化をするための最良の方法にタイミングデータを使用してテストを分

    割することがあります。 これにより、並列実行してるジョブに均等にテストを振り分けて実行することができま す。 タイミングデータを使用するには各テストランナーでメタデータを用意する必要がありま す。 ※タイミングデータ:各テストが完了するのにかかった時間が記録されているもの。
  18. Copyright © pring Inc. All Rights Reserved 30 parallelismの最適化③ RSpecでテストメタデータコレクションを使用するにはrspec_junit_formatter

    が必要です。 RSpec実行時にoptionを指定して書き出しを行い、store_test_resultsステップでメ タデータコレクションの保存を行います。
  19. Copyright © pring Inc. All Rights Reserved 32 ガイドライン化と開発メンバーへ共有 晴れてCircleCIの改善ができたので、RSpecの書き方についてのガイドライン化を

    作成し、開発メンバーに周知してCIの維持に努めました。 実際の流れとしてはGitHub Wikiに記載→定例時にWikiを見ながら解説という流 れです。
  20. Copyright © pring Inc. All Rights Reserved 34 CI分離&新プランの契約 3/26にCircleCIのOrganizationsをmetapsからpring-incに移行しました。

    それに伴いCircleCIのプランをパフォーマンスプランに変更 変更内容 並列実行数 - 4 → 20 同時実行者数 - 1 → 4 実行時間差分 - 24分13秒
  21. Copyright © pring Inc. All Rights Reserved 36 まとめ 1.

    RSpec側でパフォーマンスを悪くしてるのは特にINSERT系のものが多く気をつけ なければいけない。 1. ある程度RSpec側での改善に成功したら、CircleCI側の並列化を検討した方がい いかも。 1. RSpecの書き方について怪しい物があったりするので、開発メンバーで再度ドキュ メントを確認する必要がある。 2. テストパフォーマンス解析ツールはプロジェクト初期段階から導入を検討すべきで あり、後になるほどパーフォーマンス修正に無駄な工数が発生してしまう。 (CircleCIの並列化までは必要ないですが)
  22. Copyright © pring Inc. All Rights Reserved 38 やりたいこと 1.

    CircleCI Insightsを導入してクレジット、使用量、成功率、パイプラインの実 行時間、関連情報に関する時系列データの概要を表示して継続的な監視体 制をできるようにする。 1. RSpec profileを設定して実行時間を可視化する。