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

運用に困っていた重いバッチを高速化したらそもそもの運用が変わった話

 運用に困っていた重いバッチを高速化したらそもそもの運用が変わった話

SHIFT_EVOLVE

June 27, 2021
Tweet

More Decks by SHIFT_EVOLVE

Other Decks in Business

Transcript

  1. 運用に困っていた重いバッチ
    を高速化したらそもそもの運
    用が変わった話
    Airitech株式会社 橋本拓也
    DevOps & QAエンジニアLT大会 Vol.1 1 / 19

    View full-size slide

  2. 発表する人
    Airitech株式会社 橋本拓也
    DevOps & QAエンジニアLT大会 Vol.1 2 / 19

    View full-size slide

  3. 発表する人
    Airitech株式会社 橋本拓也
    仕事内容
    トラブルシューティングや性能試験設計・実施をメインの仕事にしています。
    ぱっと見解決できない障害とか見るとアドレナリン上がるタイプです。
    DevOps & QAエンジニアLT大会 Vol.1 2 / 19

    View full-size slide

  4. 発表する人
    Airitech株式会社 橋本拓也
    仕事内容
    トラブルシューティングや性能試験設計・実施をメインの仕事にしています。
    ぱっと見解決できない障害とか見るとアドレナリン上がるタイプです。
    好きなプログラミング言語
    C++/Lua/AWK
    DevOps & QAエンジニアLT大会 Vol.1 2 / 19

    View full-size slide

  5. 発表する人
    Airitech株式会社 橋本拓也
    仕事内容
    トラブルシューティングや性能試験設計・実施をメインの仕事にしています。
    ぱっと見解決できない障害とか見るとアドレナリン上がるタイプです。
    好きなプログラミング言語
    C++/Lua/AWK
    趣味
    GithubのTrending見て、面白そうなリポジトリを触ってみる。
    paiza スキルチェックのレーティングを上げる。
    DevOps & QAエンジニアLT大会 Vol.1 2 / 19

    View full-size slide

  6. 話の流れ
    LTで時間切れになったら悲しいので、概要を書いておきます。

    DevOps & QAエンジニアLT大会 Vol.1 3 / 19

    View full-size slide

  7. 話の流れ
    LTで時間切れになったら悲しいので、概要を書いておきます。

    1. PHPで書いたバッチ処理がすごく遅い
    DevOps & QAエンジニアLT大会 Vol.1 3 / 19

    View full-size slide

  8. 話の流れ
    LTで時間切れになったら悲しいので、概要を書いておきます。

    1. PHPで書いたバッチ処理がすごく遅い
    2. PHPで極力頑張る
    DevOps & QAエンジニアLT大会 Vol.1 3 / 19

    View full-size slide

  9. 話の流れ
    LTで時間切れになったら悲しいので、概要を書いておきます。

    1. PHPで書いたバッチ処理がすごく遅い
    2. PHPで極力頑張る
    3. C++の力をお見せしますよ
    DevOps & QAエンジニアLT大会 Vol.1 3 / 19

    View full-size slide

  10. 話の流れ
    LTで時間切れになったら悲しいので、概要を書いておきます。

    1. PHPで書いたバッチ処理がすごく遅い
    2. PHPで極力頑張る
    3. C++の力をお見せしますよ
    4. C++の底力を絞り出す
    DevOps & QAエンジニアLT大会 Vol.1 3 / 19

    View full-size slide

  11. 話の流れ
    LTで時間切れになったら悲しいので、概要を書いておきます。

    1. PHPで書いたバッチ処理がすごく遅い
    2. PHPで極力頑張る
    3. C++の力をお見せしますよ
    4. C++の底力を絞り出す
    5. あれ?バッチ処理いらないのでは?
    DevOps & QAエンジニアLT大会 Vol.1 3 / 19

    View full-size slide

  12. 話の流れ
    LTで時間切れになったら悲しいので、概要を書いておきます。

    1. PHPで書いたバッチ処理がすごく遅い
    2. PHPで極力頑張る
    3. C++の力をお見せしますよ
    4. C++の底力を絞り出す
    5. あれ?バッチ処理いらないのでは?
    6. そして運用が変わった
    DevOps & QAエンジニアLT大会 Vol.1 3 / 19

    View full-size slide

  13. 事の発端
    コンサルティング契約中のお客様がデータ処理のバッチ作ろうとしていました。
    PHPでバックエンドを書くのが得意なお客様なので、バッチもPHPで書いていました。

    今までは処理も単純で、データ量も少なく、これでうまくいっていたのです。
    ところが今回の処理では以下のようなそこそこ厳しい制約が存在して、バッチ処理の速度が大きな問題
    になってしまいました。
    1. 5分毎に外部から配置されるデータを加工して参照しやすいデータに変更しないといけない
    2. 当然5分以内に全ての処理を終わらせないといけない
    3. インスタンスが外部からのファイルサーバーとしても利用されていて、高負荷をかけられない
    DevOps & QAエンジニアLT大会 Vol.1 4 / 19

    View full-size slide

  14. 事の発端
    コンサルティング契約中のお客様がデータ処理のバッチ作ろうとしていました。
    PHPでバックエンドを書くのが得意なお客様なので、バッチもPHPで書いていました。

    今までは処理も単純で、データ量も少なく、これでうまくいっていたのです。
    ところが今回の処理では以下のようなそこそこ厳しい制約が存在して、バッチ処理の速度が大きな問題
    になってしまいました。
    1. 5分毎に外部から配置されるデータを加工して参照しやすいデータに変更しないといけない
    2. 当然5分以内に全ての処理を終わらせないといけない
    3. インスタンスが外部からのファイルサーバーとしても利用されていて、高負荷をかけられない
    そんな中,お客様より
    Airitechさん性能改善もしてたよね。なんとかできますか
    ね?
    とエンジニアのプライドをくすぐる発言をいただきました。
    コレハガンバラナイト…。
    DevOps & QAエンジニアLT大会 Vol.1 4 / 19

    View full-size slide

  15. 改善前の処理
    改善前のコードは既存のPHP5のコードを元に作成されていて、非常に効率が悪いものでした。
    5分間のデータ(1.5Mbyte)の処理に50分以上かかっていることが分かります。
    データ初期化 17分
    データ伸長・分析 16分
    データ変換 20分
    DevOps & QAエンジニアLT大会 Vol.1 5 / 19

    View full-size slide

  16. 改善前の処理
    改善前のコードは既存のPHP5のコードを元に作成されていて、非常に効率が悪いものでした。
    5分間のデータ(1.5Mbyte)の処理に50分以上かかっていることが分かります。
    データ初期化 17分
    データ伸長・分析 16分
    データ変換 20分
    …とても、遅いですね。
    DevOps & QAエンジニアLT大会 Vol.1 5 / 19

    View full-size slide

  17. PHPのままで性能改善
    PHPのプロファイラで遅い処理を特定しつつ、以下のような改善をしました。
    DevOps & QAエンジニアLT大会 Vol.1 6 / 19

    View full-size slide

  18. PHPのままで性能改善
    PHPのプロファイラで遅い処理を特定しつつ、以下のような改善をしました。
    データ初期化でファイルへの書き込み回数を減らす
    DevOps & QAエンジニアLT大会 Vol.1 6 / 19

    View full-size slide

  19. PHPのままで性能改善
    PHPのプロファイラで遅い処理を特定しつつ、以下のような改善をしました。
    データ初期化でファイルへの書き込み回数を減らす
    伸長処理の一部を事前計算して高速化してみる
    DevOps & QAエンジニアLT大会 Vol.1 6 / 19

    View full-size slide

  20. PHPのままで性能改善
    PHPのプロファイラで遅い処理を特定しつつ、以下のような改善をしました。
    データ初期化でファイルへの書き込み回数を減らす
    伸長処理の一部を事前計算して高速化してみる
    一時ファイルの出力先をtmpfsに移動する
    DevOps & QAエンジニアLT大会 Vol.1 6 / 19

    View full-size slide

  21. PHPのままで性能改善
    PHPのプロファイラで遅い処理を特定しつつ、以下のような改善をしました。
    データ初期化でファイルへの書き込み回数を減らす
    伸長処理の一部を事前計算して高速化してみる
    一時ファイルの出力先をtmpfsに移動する
    arrayへの検索回数を極力減らす
    DevOps & QAエンジニアLT大会 Vol.1 6 / 19

    View full-size slide

  22. PHPのままで性能改善
    PHPのプロファイラで遅い処理を特定しつつ、以下のような改善をしました。
    データ初期化でファイルへの書き込み回数を減らす
    伸長処理の一部を事前計算して高速化してみる
    一時ファイルの出力先をtmpfsに移動する
    arrayへの検索回数を極力減らす
    PHP8を使ってみる
    リリースしたてで触ってみたかった…
    DevOps & QAエンジニアLT大会 Vol.1 6 / 19

    View full-size slide

  23. PHPのままで性能改善結果
    データ初期化 1秒
    データ伸長・分析 90秒
    データ変換 30秒
    トータルで2分程度短縮できました。
    DevOps & QAエンジニアLT大会 Vol.1 7 / 19

    View full-size slide

  24. PHPのままで性能改善結果
    データ初期化 1秒
    データ伸長・分析 90秒
    データ変換 30秒
    トータルで2分程度短縮できました。
    25倍の高速化!!
    DevOps & QAエンジニアLT大会 Vol.1 7 / 19

    View full-size slide

  25. PHPのままで性能改善結果
    データ初期化 1秒
    データ伸長・分析 90秒
    データ変換 30秒
    トータルで2分程度短縮できました。
    25倍の高速化!!
    5分のTime Windowに収まるようになって、

    高速化、大成功!
    DevOps & QAエンジニアLT大会 Vol.1 7 / 19

    View full-size slide

  26. でも、まだ遅くない?
    DevOps & QAエンジニアLT大会 Vol.1 8 / 19

    View full-size slide

  27. でも、まだ遅くない?
    感覚的に 1.5MByte のファイルの処理に2分かかるのはかなり遅いのでは?
    DevOps & QAエンジニアLT大会 Vol.1 8 / 19

    View full-size slide

  28. でも、まだ遅くない?
    感覚的に 1.5MByte のファイルの処理に2分かかるのはかなり遅いのでは?
    PHPがボトルネックになっているかもしれない。
    DevOps & QAエンジニアLT大会 Vol.1 8 / 19

    View full-size slide

  29. でも、まだ遅くない?
    感覚的に 1.5MByte のファイルの処理に2分かかるのはかなり遅いのでは?
    PHPがボトルネックになっているかもしれない。
    もしや…
    DevOps & QAエンジニアLT大会 Vol.1 8 / 19

    View full-size slide

  30. でも、まだ遅くない?
    感覚的に 1.5MByte のファイルの処理に2分かかるのはかなり遅いのでは?
    PHPがボトルネックになっているかもしれない。
    もしや…
    これは……
    DevOps & QAエンジニアLT大会 Vol.1 8 / 19

    View full-size slide

  31. でも、まだ遅くない?
    感覚的に 1.5MByte のファイルの処理に2分かかるのはかなり遅いのでは?
    PHPがボトルネックになっているかもしれない。
    もしや…
    これは……
    C++を業務で使うチャンスでは?
    DevOps & QAエンジニアLT大会 Vol.1 8 / 19

    View full-size slide

  32. [FYI] PHPとC++の速度比較
    プログラミング言語の速度には色々な比較の方法があり、完璧で正確な比較の方法は存在しません。
    色々なbenchmarkを様々なエンジニアが実装している以下のリポジトリでJSONのパース処理を見ると、
    C++はPHPの10倍の処理速度を叩き出していることが分かります。
    https://github.com/kostya/benchmarks#json
    Language Time, s
    C++/g++(DAW JSON Link) 0.130
    PHP 1.345
    DevOps & QAエンジニアLT大会 Vol.1 9 / 19

    View full-size slide

  33. [FYI] PHPとC++の速度比較
    プログラミング言語の速度には色々な比較の方法があり、完璧で正確な比較の方法は存在しません。
    色々なbenchmarkを様々なエンジニアが実装している以下のリポジトリでJSONのパース処理を見ると、
    C++はPHPの10倍の処理速度を叩き出していることが分かります。
    https://github.com/kostya/benchmarks#json
    Language Time, s
    C++/g++(DAW JSON Link) 0.130
    PHP 1.345
    今回の処理も更に10倍程度の高速化を目指せるはず!
    DevOps & QAエンジニアLT大会 Vol.1 9 / 19

    View full-size slide

  34. C++への移植チャレンジ
    幸いなことに、お客様には以下のような高速化するモチベーションがあることが分かっていました。

    1. 少ない遅延で情報を提示したい
    2. 余裕があれば配置されるデータに入っている他の情報も有効活用したい
    DevOps & QAエンジニアLT大会 Vol.1 10 / 19

    View full-size slide

  35. C++への移植チャレンジ
    幸いなことに、お客様には以下のような高速化するモチベーションがあることが分かっていました。

    1. 少ない遅延で情報を提示したい
    2. 余裕があれば配置されるデータに入っている他の情報も有効活用したい
    お客様からも同意をいただき、

    PHPより速いC++での速度向上にチャレンジしてみることに!
    DevOps & QAエンジニアLT大会 Vol.1 10 / 19

    View full-size slide

  36. C++に単純移植
    PHPのコードをほぼそのままC++に移植してみました。
    データ初期化 1秒
    データ伸長・分析 12秒
    データ変換 4秒
    DevOps & QAエンジニアLT大会 Vol.1 11 / 19

    View full-size slide

  37. C++に単純移植
    PHPのコードをほぼそのままC++に移植してみました。
    データ初期化 1秒
    データ伸長・分析 12秒
    データ変換 4秒
    17秒と2分から約7倍の高速化を達成!
    DevOps & QAエンジニアLT大会 Vol.1 11 / 19

    View full-size slide

  38. C++に単純移植
    PHPのコードをほぼそのままC++に移植してみました。
    データ初期化 1秒
    データ伸長・分析 12秒
    データ変換 4秒
    17秒と2分から約7倍の高速化を達成!
    …でもまだ遅く感じる。
    DevOps & QAエンジニアLT大会 Vol.1 11 / 19

    View full-size slide

  39. C++に単純移植
    PHPのコードをほぼそのままC++に移植してみました。
    データ初期化 1秒
    データ伸長・分析 12秒
    データ変換 4秒
    17秒と2分から約7倍の高速化を達成!
    …でもまだ遅く感じる。
    C++はもっと「できる子」だって示したい!
    DevOps & QAエンジニアLT大会 Vol.1 11 / 19

    View full-size slide

  40. C++の底力を絞り出す!
    unordered_mapの変わりにmartinus/robin-hood-hashingを使う 17秒 → 15秒
    fmtlib/fmtの引数をFMT_COMPILEに変更する 15秒 → 13秒
    doubleの文字列化処理を整数に変換してから実施 13秒 → 11秒
    dbubleの文字列化処理をキャッシュして保持 11秒 → 10秒
    martinus/robin-hood-hashingの一部をTessil/robin-mapに変更 10秒 → 9秒
    CSV parserの利用をやめて最適化したロジックへ 9秒 → 8秒
    標準allocatorの代わりにmicrosoft/mimallocを使う 8秒 → 7秒
    条件分岐をループの外に移動 7秒 → 6秒
    さらに3倍弱の高速化!
    DevOps & QAエンジニアLT大会 Vol.1 12 / 19

    View full-size slide

  41. 同僚からはちょっと呆れられました。
    DevOps & QAエンジニアLT大会 Vol.1 13 / 19

    View full-size slide

  42. そして、ふと気がつく
    DevOps & QAエンジニアLT大会 Vol.1 14 / 19

    View full-size slide

  43. そして、ふと気がつく
    これだけ速くでいるならば、処理方式を変更できるのでは?
    DevOps & QAエンジニアLT大会 Vol.1 14 / 19

    View full-size slide

  44. そして、ふと気がつく
    これだけ速くでいるならば、処理方式を変更できるのでは?
    契約先が
    ファイルを
    配置
    オリジナル
    データを
    保存
    参照しやすいデータを
    ⽣成して、保存
    (
    重い処理)
    最新データを⼀部を取得 業務に応じて⾮定期で
    最新状態を閲覧
    DevOps & QAエンジニアLT大会 Vol.1 14 / 19

    View full-size slide

  45. そして、ふと気がつく
    これだけ速くでいるならば、処理方式を変更できるのでは?
    契約先が
    ファイルを
    配置
    オリジナル
    データを
    保存
    ⽣データから
    必要な部分だけ抽出
    業務に応じて⾮定期で
    最新状態を閲覧
    DevOps & QAエンジニアLT大会 Vol.1 15 / 19

    View full-size slide

  46. そして、ふと気がつく
    これだけ速くでいるならば、処理方式を変更できるのでは?
    契約先が
    ファイルを
    配置
    オリジナル
    データを
    保存
    ⽣データから
    必要な部分だけ抽出
    業務に応じて⾮定期で
    最新状態を閲覧
    お客様に提案したところ、プロトタイピングすることに!
    DevOps & QAエンジニアLT大会 Vol.1 15 / 19

    View full-size slide

  47. 変更した処理方式でプロトタイピング
    「特定の範囲の情報だけを取得する」ロジックを試作して計測。
    DevOps & QAエンジニアLT大会 Vol.1 16 / 19

    View full-size slide

  48. 変更した処理方式でプロトタイピング
    「特定の範囲の情報だけを取得する」ロジックを試作して計測。
    1回の実行が0.3秒で実行できることを確認できました。
    DevOps & QAエンジニアLT大会 Vol.1 16 / 19

    View full-size slide

  49. 変更した処理方式でプロトタイピング
    「特定の範囲の情報だけを取得する」ロジックを試作して計測。
    1回の実行が0.3秒で実行できることを確認できました。
    メンテナンスの都合上、本開発ではGo言語を採用することになりましたが、

    エラー処理を入れても1秒以下で処理できる方式で運用中。
    DevOps & QAエンジニアLT大会 Vol.1 16 / 19

    View full-size slide

  50. 変更した処理方式でプロトタイピング
    「特定の範囲の情報だけを取得する」ロジックを試作して計測。
    1回の実行が0.3秒で実行できることを確認できました。
    メンテナンスの都合上、本開発ではGo言語を採用することになりましたが、

    エラー処理を入れても1秒以下で処理できる方式で運用中。
    高速化によって処理方式に選択肢が生まれ、

    運用方式が変化した!
    と言えるのではないかと思います。
    DevOps & QAエンジニアLT大会 Vol.1 16 / 19

    View full-size slide

  51. 環境的な後押しも大きな要因
    こんなにうまくいったのは、環境に寄るところも大きかったと思います。
    1. 運用と開発の両方に関わっているお客様だったため、両方の課題を把握されていた
    2. ソフトウェアの規模が数千行程度で、細かいチャレンジがしやすかった
    3. 私たちも、運用・開発と垣根を作らず、提案ができる体制で臨めた
    DevOps & QAエンジニアLT大会 Vol.1 17 / 19

    View full-size slide

  52. 環境的な後押しも大きな要因
    こんなにうまくいったのは、環境に寄るところも大きかったと思います。
    1. 運用と開発の両方に関わっているお客様だったため、両方の課題を把握されていた
    2. ソフトウェアの規模が数千行程度で、細かいチャレンジがしやすかった
    3. 私たちも、運用・開発と垣根を作らず、提案ができる体制で臨めた
    運用と開発を一緒に話せる環境って大事と実感しました。
    DevOps & QAエンジニアLT大会 Vol.1 17 / 19

    View full-size slide

  53. まとめ
    1. PHPで書かれたバッチ処理を25倍高速化しました
    2. さらにC++での移植して7倍高速化しました
    3. C++で最適化をくりかえし更に3倍弱高速化しました
    4. 500倍以上の高速化によって処理内容への違う考え方が生まれ、運用の仕方も変えられました。
    DevOps & QAエンジニアLT大会 Vol.1 18 / 19

    View full-size slide

  54. まとめ
    1. PHPで書かれたバッチ処理を25倍高速化しました
    2. さらにC++での移植して7倍高速化しました
    3. C++で最適化をくりかえし更に3倍弱高速化しました
    4. 500倍以上の高速化によって処理内容への違う考え方が生まれ、運用の仕方も変えられました。
    性能改善で運用にも貢献できるかもしれない!
    DevOps & QAエンジニアLT大会 Vol.1 18 / 19

    View full-size slide

  55. 最後までご覽いただき、ありがとうございました。
    このスライドは で作成しました。
    DevOps & QAエンジニアLT大会 Vol.1 19 / 19

    View full-size slide