🔧

データ連携ジョブ開発の心得 - 最小実装から並列処理への道のり

2024/12/05に公開

はじめに

弊社では企業様からデータを連携いただき、弊サービスで掲載することができます。
そのため、APIでデータを受け取り、DBへ保存するジョブを作成するのですが、
データ取得→整形・保存するだけと簡単そうにみえて、仕様が複雑で悩むポイントが多くありました。
本稿では、そんな私の経験から「どのように実装を進めるべきだったか」をお伝えできればと思います。

とりあえず何を目指すべきか?

まずは最小限の実装で動くものを作り、全体の流れを理解することを目指します。
「詳細な仕様が決まっていない」や「ドメイン知識が不足して業務の理解が難しい」ということがあるため、ざっくりとやりたいことを書き出して、可能な限り少ないコードで実装することを目標にします。

まずは直列処理で実装

この時点では並列化やパフォーマンスの心配をしないでよいかと思います。
とにかく動くものを作ることで、自分の心を落ち着かせることができます。(大切)
直列処理は、処理の流れが理解しやすいため、デバッグが容易でGoodです。

仕様に沿って肉付けする

この時点では、1レコード分を保存できることを目指すのがよいと思います。
特異なケースは一旦忘れて、楽しさを優先します。
その後は「1レコード < 特定のグループ < ... < 全体」のように徐々に複雑なケースに対応していきます。

パフォーマンス計測

ある程度しっかり形になったらパフォーマンス計測を行います。
ここで潰しておきたいことは、N+1問題やボトルネックの特定です。
「動くものを作る」を優先したため、設計が甘かったり、パフォーマンスが悪かったりします。

特に気にする点として

  • 無駄にクエリを発行していないか
  • 非効率なループ処理を行なっていないか
  • インデックスやテーブル設計が適切か

などが挙げられます。

並列処理への移行

パフォーマンス計測を行った後は、並列処理への移行を行います。
弊社ではkuroko2を利用しているため、リソースが許す限り並列化を行い、高速化を目指します。
できるだけ逐次部分を減らし、並列化できる箇所を見極めます。

タスク分解

処理を複数に分解する際に、依存関係を見極める必要があります。

マスタ取得と情報A取得は依存関係が合っても情報A取得と情報B取得は依存関係がないため並列化できます。

データ分解

データ分解を行うことで、並列化できる箇所もあります。

効果検証

最後に、処理時間の比較やメモリ使用量の確認、エラーハンドリングの検証を行います。

完走した感想

実際には、「動くものを作ったけど、すごく遅い」という問題に直面してからパフォーマンス改善を検討しました。
その際になっとく!並行処理プログラミングを参考にして、理解を深めていきました。
まだまだ理解が浅いため、もっと深く理解していこうと思います。

LCL Engineers

Discussion