Pythonバッチの高速化

1.9K Views

March 14, 23

スライド概要

1時間以内に処理が完了しなければならないPythonで書かれたバッチを15〜20分で終わるようチューニングしたときの話です。

コードベースの改善やテストコードの追加などもしました。

profile-image

Webエンジニア Python、Go言語を使用したバックエンド開発の経験が長い​ スクラムを使った開発に通算7年携わり、デイリースクラム、スプリント計画、スプリントレビュー、振り返りなどのファシリテーターも担当していた​ 米国認定アドバンスドスクラムマスター(A-CSM)の資格も取得しており、スクラムやCI/CD、TDD、コードレビュー、ペアプロなどのアジャイル開発技術に詳しい​ AWSをはじめとしたクラウド・コンテナ化のトレンドにも追随しており、6年にわたってAWSを使ったインフラの運用に携わってきた経験あり​ 正確さや丁寧さが求められるデータ移行やシステムリプレイスなどの業務に強みあり

シェア

またはPlayer版

埋め込む »CMSなどでJSが使えない場合

関連スライド

各ページのテキスト
1.

Pythonバッチの高速化 2023年3月14日 石田 武 Copyright © 2023 Takeshi Ishida All Rights Reserved.

2.

とあるPythonバッチの改善

3.

• どんな問題が起きていたか? とあるPython バッチの改善 • 問題解決を妨げる阻害要因 • 解決までの段取り • メモリの改善 • コネクション数の改善

4.

どんな問題が起きていたか? バッチ処理が遅くてデータ更新が滞っていた • • • • 商品マスタのデータ(毎時更新)が時間内に終了しない 未処理のジョブがどんどんメッセージキューに滞留していく やむを得ずメッセージキュー再起動という場当たり対応をしていた 商品マスタの遅延は業務上の支障があり、 改善「待ったなし」の状況だった

5.

• どんな問題が起きていたか? とあるPython バッチの改善 • 問題解決を妨げる阻害要因 • 解決までの段取り • メモリの改善 • コネクション数の改善

6.

問題解決を妨げる阻害要因 1. ドメインロジックのテストコードがない 2. コードベースのレガシー化もかなり進んでいた • データアクセス用オブジェクトを何重にも隠蔽され、見通しが悪かった • 意図が不明なVisitorパターンで実装されていたこともコードの理解を妨げた 3. 当時の担当者は既に退職して質問できない ※コードベースの刷新を前提としつつも慎重な対応が求められる

7.

• どんな問題が起きていたか? とあるPython バッチの改善 • 問題解決を妨げる阻害要因 • 解決までの段取り • メモリの改善 • コネクション数の改善

8.

解決までの段取り コードベースをリプレイスしつつ問題箇所を特定する必要があった 1. まずテストコードを追加する (修正時のエンバグを防ぐため、カバレッジも高く保った) 2. 理解しにくいコードを直し、原因の特定を容易に 3. プロファイルを取って問題箇所を探る 4. Datadogのアラートとプロファイルを参考にコード修正案を立てる 5. 修正後のプロファイルを取り、改善が見られることを確認 6. プログラムをリリースし、アラートの傾向などを経過観察

9.

Datadogのアラートからわかったこと 1. メモリ不足というアラートが多かった (それが更に悪化するとOOMキラーにプロセスを殺されていた) 2. ネットワークのコネクション数の漸増を示すものが次に多かった (Aurora MySQLへの接続数が時間とともに高止まりしていた) ※メモリ不足はバッチ処理の遅さに直結するため、 まずこちらを対策することに

10.

• どんな問題が起きていたか? とあるPython バッチの改善 • 問題解決を妨げる阻害要因 • 解決までの段取り • メモリの改善 • コネクション数の改善

11.

メモリの改善 • データ取得処理を分割 (例えばテーブルAとBのデータを処理するならば、 データの取得・加工・保存処理はAとBで別のルーチンに分ける) • DBから読み出したデータはメモリに格納し、カーソルを早く閉じる (接続は切断しなくてもカーソルは不要になり次第閉じる) メモリに格納したデータは処理を終えたらすぐに解放する (例: dictのpopやdel文) データをあらかじめグループ化し、グループ内の処理を終えた時 点で少しずつメモリを解放する • •

12.

メモリの改善の結果どうなったか? • • 毎時定期実行のジョブ(=60分以内に終了しなければならない) これが15〜20分で終わるようになった 1時間にこのジョブを2回実行しても間に合う時間に短縮されたた め、従来より新しい商品マスタのデータを配信できるようになった Before 毎時実行のジョブが60分以 内に終わらずメッセージ キューに積み上がってしまう After 60分に2回ジョブを実行して も良くなったので、より新し いデータを配信可能に

13.

• どんな問題が起きていたか? とあるPython バッチの改善 • 問題解決を妨げる阻害要因 • 解決までの段取り • メモリの改善 • コネクション数の改善

14.

商品マスタの バッチが改善 したと思った ら… コネクション数のアラートが悪 化してしまった

15.

コネクション数の改善 • • • なぜコネクション数が積み上がったか? 商品マスタのバッチが速く終わって他のバッチが従来より多数動く ようになり、その中に存在したファイルディスクリプタがリークする バグの発生頻度が上がったため ファイルディスクリプタのクローズが漏れていた箇所をすべて修正 これにより、コネクション数のアラートも鳴らなくなった

16.

まとめ

17.

まとめ • • • テストコードのありがたみが分かる事例 プロファイラや監視ツールのアラートメッセージが役に立った ひとつの問題を解決した結果、潜在的な別の問題が浮上すること もある

18.

以上