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

Sidekiqで実現する 長時間非同期処理の中断と再開 / Pausing and Resum...

hypermkt
October 25, 2024

Sidekiqで実現する 長時間非同期処理の中断と再開 / Pausing and Resuming Long-Running Asynchronous Jobs with Sidekiq

2024.10.25 Fri Kaigi on Rails 2024@有明セントラルタワーホール & カンファレンス(東京)

hypermkt

October 25, 2024
Tweet

More Decks by hypermkt

Other Decks in Programming

Transcript

  1. 3

  2. 4

  3. Sidekiqとは 10 • Rubyで動作する非同期処理のライブラリ ◦ https://github.com/sidekiq/sidekiq ◦ ジョブ管理のRedisを利用 • 大量データ処理や時間がかかるタスクを非同期で処理

    • 無償版(OSS), 有償版(PRO, ENTERPRISE)があり、プランによって提供される機能に 違いがある ◦ 有償版ではジョブが失われずに再取得できるsuper_fetch機能などがある ◦ SmartHRではENTERPRISE版を利用
  4. 中断・再開処理の全体像 Sidekiq プロセス Redis 1 中断処理 ジョブはSidekiqの処理終了を検知して 任意のタイミングで処理を停止 Sidekiq プロセス

    Redis 2 Sidekiq プロセス Redis ジョブは進捗を保存しながら 処理を進行 3 24 ⚡すべて処理終了!
  5. 中断・再開処理の全体像 Sidekiq プロセス Redis 1 中断処理 ジョブはSidekiqの処理終了を検知して 任意のタイミングで処理を停止 Sidekiq再起動... Redis

    Sidekiq プロセス Redis 2 Sidekiq プロセス Redis ジョブは進捗を保存しながら 処理を進行 3 Sidekiq プロセス 4 25 ⚡すべて処理終了!
  6. 中断・再開処理の全体像 Sidekiq プロセス Redis 1 中断処理 ジョブはSidekiqの処理終了を検知して 任意のタイミングで処理を停止 Sidekiq再起動... Redis

    Redis 再開処理 ジョブは進捗を取得し処理を継続 Sidekiq プロセス Redis 2 Sidekiq プロセス Redis ジョブは進捗を保存しながら 処理を進行 3 Sidekiq プロセス 4 Sidekiq プロセス 5 26 ⚡すべて処理終了!
  7. Sidekiq設定ファイルにイベントハンドリングを設定 config/initializers/sidekiq.rb Sample 29 • Sidekiqの処理終了(quiet)・停止 (stop)を管理する変数を定義、フラグ として利用する • イベントハンドリングを設定し、

    Sidekiqの処理終了と停止を検知 したらフラグをあげる • このフラグで中断を行うかの 判定条件に利用する 参考: https://github.com/sidekiq/sidekiq/wiki/Signals https://github.com/sidekiq/sidekiq/wiki/Deployment
  8. 再開処理の全体像 35 Redis 行番号 1 2 3 4 5 ⚡中断

    • 例) CSVで5件のデータをインポートする 1回目の実行 1行目 終わり! 2行目 終わり! 3行目 終わり! 進捗管理 DB データ登録
  9. 再開処理の全体像 36 Redis 行番号 1 2 3 4 5 ⚡中断

    • 例) CSVで5件のデータをインポートする 1回目の実行 1行目 終わり! 2行目 終わり! 3行目 終わり! 進捗管理 DB データ登録 Redis 行番号 1 2 3 4 5 2回目の実行 1行目 終わり! 2行目 終わり! 3行目 終わり! 4行目 終わり! 5行目 終わり! スキップ 進捗管理 DB データ登録
  10. • 用途 ◦ IDなどテーブルの主キーを用いたデータベースへの一括処 理 ▪ 例) データの一括削除 • ポイント

    ◦ RedisのキーはSidekiqのジョブID + IDの種類名とする ▪ IDの種類名: item_id などデータの種類を示すもの ▪ 1回のジョブで複数データの進捗を管理する 場合もあるため ◦ 処理済みのIDをRedisに追加 ID番号保持方式 38 キー:#{ジョブID}/#{IDの種類名} Redis aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb cccccccc-cccc-cccc-cccc-cccccccccccc …
  11. CSVインポート系の課題: 行ごとに複数個のエラーが発生する可能性がある 46 社員番号 姓 名 部署1 部署 sample-001 須磨

    英知 システム部 2行目:登録済みの社員番号です。 2行目 部署1 部署:存在しない部署名です。
  12. 種類毎にキーを分けて Redisで進捗管理する 47 キー:#{jid} Redis 1行目 2行目 3行目 処理済みの行番号 失敗した行番号

    3行目 … 3行目:登録済みの社員番号です。 3行目:XXXXXは存在しない部署です。 ... 行ごとのエラーメッセージ errors/#{jid} error-logs/#{jid}
  13. • 想定される実行時間 ◦ 数分 • 想定されるファイル容量 ◦ 数MB以下 • 処理内容

    ◦ DBからデータ抽出したものをファイル書き出しするのみ 実行時間が短い & ファイル容量が小さいファイルエクスポート 60
  14. • 想定される実行時間 ◦ 数時間以上 • 想定されるファイルサイズ ◦ 数百MB • 処理内容

    ◦ 従業員の履歴情報のダウンロード 実行時間が長い & ファイル容量が大きいファイルエクスポート 63
  15. ファイルの保存先候補 68 • オブジェクトストレージ (GCS) ◦ 大容量のファイルの保存が可能 ◦ ライブラリを使って簡単にアップロード可能 ◦

    一時ファイルに有効期限を設けて削除することも可能 ◦ セキュリティが強固(暗号化、アクセス制御機能) ◦ GCSへの転送速度も速い 今回の用途としては最適 !!! 😆
  16. Sidekiq Iterationとは • 2024/07/03 Sidekiq v7.3.0で Sidekiq Iterationという新機能が導入 ◦ https://github.com/sidekiq/sidekiq/wiki/Iteration

    ◦ This feature should be considered BETA until the next minor release. • 機能 ◦ 中断時に進行状況(カーソル)を保存し、再開時には保存したポイントから処理を再 開 ◦ on_start, on_resume, on_stop, on_completeなどのコールバック ◦ Active Record, CSV, 配列用にEnumeratorを生成するヘルパーメソッド 82