Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

話の流れ LTで時間切れになったら悲しいので、概要を書いておきます。 DevOps & QAエンジニアLT大会 Vol.1 3 / 19

Slide 7

Slide 7 text

話の流れ LTで時間切れになったら悲しいので、概要を書いておきます。 1. PHPで書いたバッチ処理がすごく遅い DevOps & QAエンジニアLT大会 Vol.1 3 / 19

Slide 8

Slide 8 text

話の流れ LTで時間切れになったら悲しいので、概要を書いておきます。 1. PHPで書いたバッチ処理がすごく遅い 2. PHPで極力頑張る DevOps & QAエンジニアLT大会 Vol.1 3 / 19

Slide 9

Slide 9 text

話の流れ LTで時間切れになったら悲しいので、概要を書いておきます。 1. PHPで書いたバッチ処理がすごく遅い 2. PHPで極力頑張る 3. C++の力をお見せしますよ DevOps & QAエンジニアLT大会 Vol.1 3 / 19

Slide 10

Slide 10 text

話の流れ LTで時間切れになったら悲しいので、概要を書いておきます。 1. PHPで書いたバッチ処理がすごく遅い 2. PHPで極力頑張る 3. C++の力をお見せしますよ 4. C++の底力を絞り出す DevOps & QAエンジニアLT大会 Vol.1 3 / 19

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

PHPのままで性能改善結果 データ初期化 1秒 データ伸長・分析 90秒 データ変換 30秒 トータルで2分程度短縮できました。 25倍の高速化!! 5分のTime Windowに収まるようになって、 高速化、大成功! DevOps & QAエンジニアLT大会 Vol.1 7 / 19

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

[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

Slide 33

Slide 33 text

[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

Slide 34

Slide 34 text

C++への移植チャレンジ 幸いなことに、お客様には以下のような高速化するモチベーションがあることが分かっていました。 1. 少ない遅延で情報を提示したい 2. 余裕があれば配置されるデータに入っている他の情報も有効活用したい DevOps & QAエンジニアLT大会 Vol.1 10 / 19

Slide 35

Slide 35 text

C++への移植チャレンジ 幸いなことに、お客様には以下のような高速化するモチベーションがあることが分かっていました。 1. 少ない遅延で情報を提示したい 2. 余裕があれば配置されるデータに入っている他の情報も有効活用したい お客様からも同意をいただき、 PHPより速いC++での速度向上にチャレンジしてみることに! DevOps & QAエンジニアLT大会 Vol.1 10 / 19

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

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

Slide 39

Slide 39 text

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

Slide 40

Slide 40 text

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

Slide 41

Slide 41 text

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

Slide 42

Slide 42 text

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

Slide 43

Slide 43 text

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

Slide 44

Slide 44 text

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

Slide 45

Slide 45 text

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

Slide 46

Slide 46 text

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

Slide 47

Slide 47 text

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

Slide 48

Slide 48 text

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

Slide 49

Slide 49 text

変更した処理方式でプロトタイピング 「特定の範囲の情報だけを取得する」ロジックを試作して計測。 1回の実行が0.3秒で実行できることを確認できました。 メンテナンスの都合上、本開発ではGo言語を採用することになりましたが、 エラー処理を入れても1秒以下で処理できる方式で運用中。 DevOps & QAエンジニアLT大会 Vol.1 16 / 19

Slide 50

Slide 50 text

変更した処理方式でプロトタイピング 「特定の範囲の情報だけを取得する」ロジックを試作して計測。 1回の実行が0.3秒で実行できることを確認できました。 メンテナンスの都合上、本開発ではGo言語を採用することになりましたが、 エラー処理を入れても1秒以下で処理できる方式で運用中。 高速化によって処理方式に選択肢が生まれ、 運用方式が変化した! と言えるのではないかと思います。 DevOps & QAエンジニアLT大会 Vol.1 16 / 19

Slide 51

Slide 51 text

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

Slide 52

Slide 52 text

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

Slide 53

Slide 53 text

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

Slide 54

Slide 54 text

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

Slide 55

Slide 55 text

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