バッチをGoにリプレイスして高速化した話 / GoGoGolangEdition!
by
yuma iwasaki
Link
Embed
Share
Beginning
This slide
Copy link URL
Copy link URL
Copy iframe embed code
Copy iframe embed code
Copy javascript embed code
Copy javascript embed code
Share
Tweet
Share
Tweet
Slide 1
Slide 1 text
バッチをGo にリプレイスして 高速化した話 株式会社Speee エンジニア 岩崎 裕馬 (@suthio_) バッチをGo にリプレイスして高速化した話
Slide 2
Slide 2 text
自己紹介 岩崎裕馬(@suthio_) 趣味はおいしいお店探し 株式会社Speee でネイティブ広告の配信システムを開発 2
Slide 3
Slide 3 text
アジェンダ Go の良いところを紹介 移行の背景 パフォー マンスチュー ニング おまけ まとめ 3
Slide 4
Slide 4 text
Go の良いところを少しだけ紹介 4
Slide 5
Slide 5 text
5
Slide 6
Slide 6 text
実行 ワンバイナリで実行可能 scp で送るだけでどこでも実行可能 - ライブラリの依存などを考える必要がない 高速な実行速度 6
Slide 7
Slide 7 text
開発 言語仕様がシンプル 型安全性 コンパイルが早い 並列/ 並行処理が行いやすい 7
Slide 8
Slide 8 text
移行した話 8
Slide 9
Slide 9 text
結果から先に共有 9
Slide 10
Slide 10 text
移行前 10
Slide 11
Slide 11 text
移行後 11
Slide 12
Slide 12 text
移行前 12
Slide 13
Slide 13 text
移行後 13
Slide 14
Slide 14 text
移行前のバッチについて Amazon EMR(Spark) を使用 Spark(Scala) を実行 14
Slide 15
Slide 15 text
移行後のバッチについて EC2 Container Service(ECS) を使用 Go のバッチアプリケー ションを実行 15
Slide 16
Slide 16 text
移行前のバッチが抱えていた課題 遅い 10 時間ぐらいかかる 高い r4.2xlarge インスタンスを12 台(6 台 × 2 クラスタ) で運用 0.64 * 720 * 12 = 5529.6 ドル ロー カルで実行しずらい よく失敗している 原因不明のものが多数 修正しずらい雰囲気 16
Slide 17
Slide 17 text
移行する際に求めたこと 高速 安価 ロー カルで実行可能 失敗時の原因究明が容易 17
Slide 18
Slide 18 text
パフォー マンスが良くて、 ロー カルでも実行が簡単で エラー が起こった際も復旧しやすい バッチが求められた 18
Slide 19
Slide 19 text
パフォー マンスチュー ニング 並列化 アルゴリズム最適化 デー タ量の削減 19
Slide 20
Slide 20 text
パフォー マンスチュー ニングを 行う際に大切な考え方 コンピュー ティングリソー スを使えきれているかどうか CPU リソー スを使い切れるようにする ディスクIO、 ネットワー クIO で詰まらせない 計算量は必要最小限となっているかどうか 適切なアルゴリズムを使って計算量を減らす 不必要なオブジェクト生成や計算は極力減らす 20
Slide 21
Slide 21 text
並列化 実行単位が細かく分けられることがわかったため、 実行単位ごとに並列で処理を行うようにした 通信処理の並列化 21
Slide 22
Slide 22 text
アルゴリズム最適化 アプリケー ション内でデー タのJoin が多く発生していたので そういった処理をO(1) でできるように 多くのデー タをMap で保持して使用できる形に修正 事前に使用するメモリサイズを予測し、 メモリを確保 ルー プ処理を削減( 関数っぽく書かない) 22
Slide 23
Slide 23 text
デー タ量削減 Input のデー タサイズ削減 不要なデー タが含まれていたので削除 Output デー タサイズの削減 圧縮してSQS に送信(DynamoDB にも圧縮して保持) 使う際に解凍するようにした 23
Slide 24
Slide 24 text
圧縮について 圧縮にはSnappy を使用 http://s-yata.jp/docs/snappy/ 今回のデー タを圧縮した結果、 圧縮率は0.783 だったので、 35KB が7.6KB のデー タになった デー タ自体を圧縮したことにより、 結果的にDynamoDB のRead、Write のCapacity がより少ない状態で も動作するようになり、 コスト削減に繋がった 24
Slide 25
Slide 25 text
移行する際に求めたこと 早い 安い ロー カルで実行可能 失敗時の原因究明が容易 25
Slide 26
Slide 26 text
結果 早い: 実行時間は1/10 安い: サー バー 台数は1/6(5529.6 ドルから921.6 ドルに削減) ロー カルで実行可能: 簡単にできるようになった 失敗時の原因究明が容易: 今のところ困ったことはない 26
Slide 27
Slide 27 text
おまけ 27
Slide 28
Slide 28 text
28
Slide 29
Slide 29 text
Lambda のバッチについて SQS のデー タを定期的にDynamoDB にPut するだけのバッチ Python で実装 29
Slide 30
Slide 30 text
起こった問題 Lambda を使って、DynamoDB へのPut 処理を行っていたが IO で詰まり、DynamoDB のWriteCapacity を余らせてしまっている 状態となっていた 今回のバッチを高速化したために、 次のボトルネックとなった 30
Slide 31
Slide 31 text
Lambda のバッチもGo 化しよう!!! 31
Slide 32
Slide 32 text
Lambda のバッチをGo 化 Lambda 上でGo を実行 Go はワンバイナリなので、NodeJS から 実行ファイルをキックするだけで実行可能 IO でネックが発生していたので、 並列処理が得意なGo を使うことにより、 解決 ロー カルでテストしやすい 32
Slide 33
Slide 33 text
まとめ 処理時間が長くなりがちなバッチは特にパフォー マンスを意識 コンピュー ティングリソー スを使えきれているかどうか 計算量は必要最小限となっているかどうか 今回のようなバッチではパフォー マンスチュー ニングがしやすく、 並列処理が得意なGo を使うのは良い選択だった 33