ぼくとJenkinsおじさんの360日戦争

12,067 views

Published on

ぼくとJenkinsおじさんの360日戦争

  1. 1. 僕とJenkinsおじさんの360日戦争株式会社ミクシィMasaaki Goshima(@goccy54)
  2. 2. 自己紹介• 2012年度新卒としてミクシィに入社• 趣味でPerlの処理系を作っている• 技術部たんぽぽGに所属– たんぽぽGって何? : 開発者のための開発を行う– 具体的にどんなことしてるの?:• 技術的負債を効率的に返済するためのツール作成• mixi.jpのJenkinsの保守・運用
  3. 3. Jenkinsとの出会い• たんぽぽG配属後の6月某日、Jenkins運用の命を受け、おじさんとの戦いの火蓋が切って落とされた…
  4. 4. アジェンダ• おじさんをどうにかするための準備– mixiのテスト環境と課題の把握• おじさんとの闘い、そして…– テスト実行フローと課題解決• おまけ– mixiとおじさんのアブノーマルな関係• mixiの変わったJenkinsの使い方の紹介
  5. 5. mixiのテスト環境と課題
  6. 6. mixiのリリースフローJenkins本番サーバdeploy時間mixi.gitrepositoryの変化開発者コミットリリース時間Full test
  7. 7. Full testの中身と実行環境• 言語 : Perl• テストファイル数 : 18000以上• テスト項目数 : 25万以上• 実行環境(Jenkins Slaveのスペック)• CPU : 24 core (Xeon 2.67GHz)• Memory : 64GB
  8. 8. テスト所要時間min
  9. 9. おじさんから与えられた課題は強大だった…• Full testにかかる時間が長いとその分リリースするまでに時間がかかる…さて、どうしますか?
  10. 10. 何らかの方法でテスト実行を高速化する必要がある課題を解決するためには…
  11. 11. テスト実行フローと課題解決
  12. 12. テスト実行の仕組みを詳細に理解する• 高速化のアプローチを考えるため、テスト実行の仕組みをもっと掘り下げる1. Jenkins X Perl- テスト実行フローの理解2. 並列実行の問題とFixture- テスト実行方法の理解
  13. 13. 1. Jenkins X Perl
  14. 14. Jenkins X PerlPerlのテストファイル(18000)JenkinsProveテスト実行1..1ok 1TAP形式の出力収集123JUnit形式のXMLファイルを生成4 5結果を読み取って表示
  15. 15. Jenkins X PerlPerlのテストファイル(18000)JenkinsProveテスト実行1..1ok 1TAP形式の出力収集123JUnit形式のXMLファイルを生成4 5結果を読み取って表示この2つについてもう少し詳しく解説
  16. 16. ProveとTAP• Prove– テストの並列実行・再帰的実行をサポート– 失敗したテストだけ実行するなど多機能– テスト側がTAP形式で出力することをサポートしていれば、他言語でも利用可能ex) prove --ext=.js --exec node• TAP(Test Anything Protocol)– 成功なら「ok」、失敗なら「not ok」– とにかくシンプル!# test : xxxok 1 – pattern1ok 2 – pattern2
  17. 17. 2. 並列実行の問題とFixture
  18. 18. 並列実行の問題• mixiでは大量のテストを捌くために、proveのオプションで並列にテストを処理している• 並列実行は高速実行するためにかかせないが、深刻な問題がある
  19. 19. 共通DB参照によるデータ不整合問題DB(MySQL)Prove並列実行テストA テストBInsertselectdeleteselectinsertselect期待した結果とは異なる結果が返ってきて、テストがFAILする
  20. 20. Fixture• テスト毎に同一データから別DBを作成して、それを参照するDB(MySQL)Prove並列実行テストA テストBInsertselectdeleteselectinsertselectDB(MySQL)テストA用のDB テストB用のDBcreate create
  21. 21. ボトルネックの把握• 大量のテストを処理する上では、次の処理が無視できないオーバーヘッドになる–Fixtureによるテスト毎のDB生成・破棄–テスト毎のモジュール読み込み• 巨大なモジュール/依存の多いモジュール
  22. 22. 課題解決のために~ テスト高速化手法 ~
  23. 23. 高速化アプローチ• モジュール読み込み時間を削る–forkprove : proveで並列実行する際、forkして子プロセスで行う• 親プロセスでモジュールをロードすることで、子プロセスでのモジュール読み込みが発生しない• Fixtureで生成したDBをキャッシュする– 一度DBを作成したら、Write処理(Insert, Update, Delete)が発生するまでDBを使い回す• DB生成コストを削減
  24. 24. しかしそう簡単にはいかない• よくも悪くもモジュールを先読みすると不整合を生じるケースがある– モジュールの読み込み順が大事な場合など• 生成したDBをCacheする機構は実装が難しく、実装コストと効果が釣り合うか分からない– ReadOnlyなテストがどれだけあるのか、調査が必要
  25. 25. しかしそう簡単にはいかない• よくも悪くもテスト側でモジュール読み込みを行わないと、不整合を生じるケースがある– モジュール読み込み時をhookして何かやる場合など• 生成したDBをCacheする機構は実装が難しく、実装コストと効果が釣り合うか分からない– ReadOnlyなテストがどれだけあるのか、調査が必要どうしたものかと悩みに悩む…もはや高速化することはできないのか
  26. 26. そこに、48人の女神が現れた!※正確には、AKBの名を冠した48のノードをJenkinsスレーブとして使えるようになった!JKS48
  27. 27. テスト実行を複数ノードで!Jenkinsテスト実行要求MasterノードSlaveノードSlaveノードSlaveノード18000600060006000(Rino)(Mariko)(Mayu)(Yuko)
  28. 28. min
  29. 29. 圧倒的勝利• リソースって大事ですねひとまず、おじさんとの闘いはここで幕を閉じるJKS48
  30. 30. mixiの変わったJenkinsの使い方
  31. 31. remotetest• 負荷のかかるテストはJenkinsを介して行う開発者個人開発環境サーバログインJenkinsJenkins Slaveサーバgit://git.mixi.jp/repo.git –b branch開発中のブランチをJenkinsに投げてしまう空いているslaveでテストを実行低スペック高スペック
  32. 32. 問題点1• Jenkinsの仕様上、前のテスト結果を知る必要があるため、後に実行したテストが待たされるテスト実行キューの順番前後30分50分後に実行されたテストの方が先に終わっても、前のテスト結果が出るまで待たされる
  33. 33. 問題点2• テスト実行キューを同じタイミングで大量に投げられると、テスト終了時にJenkinsマスターノードが高負荷になるテスト実行キューの順番1分おきMasterテスト結果を表示するための計算やレンダリング処理ほぼ同タイミング
  34. 34. おわりに• remote testにも適した軽量CIツールの導入が期待される• 構想はあるので、試しに作ってみます

×