Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
バッチ処理と冪等性 / 20191218_merpay_techtalk
Search
kaznishi
December 18, 2019
Technology
2
5.3k
バッチ処理と冪等性 / 20191218_merpay_techtalk
kaznishi
December 18, 2019
Tweet
Share
More Decks by kaznishi
See All by kaznishi
Finally_I_can_kichijojipm32
kaznishi
0
610
Bounds Check Eliminationについて調べてみた / 1218-lt
kaznishi
0
510
Hello, Prometheus!! Goで作るexporter自作入門 / 180727 LT
kaznishi
6
3.7k
Goのスライス容量拡張量がどのように決まるのか追った / 180713 LT
kaznishi
3
3.7k
スライス容量拡張量がどのように決まるのか追った / 180709 LT
kaznishi
0
160
Other Decks in Technology
See All in Technology
2025/10/27 JJUGナイトセミナー WildFlyとQuarkusの 始め方
megascus
0
110
最近読んで良かった本 / Yokohama North Meetup #10
mktakuya
0
400
進化する大規模言語モデル評価: Swallowプロジェクトにおける実践と知見
chokkan
PRO
3
450
AIエージェントを導入する [ 社内ナレッジ活用編 ] / Implement AI agents
glidenote
1
150
어떤 개발자가 되고 싶은가?
arawn
1
420
AWS re:Invent 2025事前勉強会資料 / AWS re:Invent 2025 pre study meetup
kinunori
0
1.1k
仕様駆動開発を実現する上流工程におけるAIエージェント活用
sergicalsix
10
5.4k
kotlin-lsp の開発開始に触発されて、Emacs で Kotlin 開発に挑戦した記録 / kotlin‑lsp as a Catalyst: My Journey to Kotlin Development in Emacs
nabeo
2
300
サブドメインテイクオーバー事例紹介と対策について
mikit
14
6.5k
書籍『実践 Apache Iceberg』の歩き方
ishikawa_satoru
0
450
Boxを“使われる場”にする統制と自動化の仕組み
demaecan
0
180
短期間でRAGシステムを実現 お客様と歩んだ生成AI内製化への道のり
taka0709
1
170
Featured
See All Featured
Understanding Cognitive Biases in Performance Measurement
bluesmoon
31
2.7k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
231
22k
What’s in a name? Adding method to the madness
productmarketing
PRO
24
3.7k
Scaling GitHub
holman
463
140k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
234
17k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
52
5.7k
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
4 Signs Your Business is Dying
shpigford
186
22k
Code Reviewing Like a Champion
maltzj
526
40k
For a Future-Friendly Web
brad_frost
180
10k
StorybookのUI Testing Handbookを読んだ
zakiyama
31
6.3k
GitHub's CSS Performance
jonrohan
1032
470k
Transcript
2019.12.18 Wed. 1 Tech Talk vol.2 Backend Engineer ~マイクロサービスの冪等性 ~
バッチ処理と冪等性 kaznishi
自己紹介 • kaznishi • Twitter: @kaznishi1246 • Backend Engineer •
Code Payment Team • 2018年11月入社 15% 35% 50% 2
自己紹介 • 担当しているマイクロサービス ◦ 加盟店精算 ◦ 補助金接続 ◦ 加盟店レポート •
いずれもバッチ処理がメイン! 15% 35% 50% 3
バッチ処理の紹介 4
加盟店精算の様々なバッチ処理 5 会計 精算 決済 銀行 残高 会計データ取り込み処理 (毎日) ※会計サービスにリクエストを送って取得するのではなく、
会計サービスがストレージ(GCS)にファイルとして 吐き出したものを取り込み
加盟店精算の様々なバッチ処理 6 会計 精算 決済 銀行 残高 会計データ中間集計処理 (毎日)
加盟店精算の様々なバッチ処理 7 会計 精算 決済 銀行 残高 精算金額集計(締め)処理(月2回)
加盟店精算の様々なバッチ処理 8 会計 精算 決済 銀行 残高 入金指示処理(月2回)
バッチ処理と冪等性 今回のテーマ 9
冪等性 • ある操作を1回実行しても、複数回実行しても、同じ結果になる • 冪等性がある処理の例 ◦ 「ある変数の値を x に更新する」 ◦
何回実行しようが結果は x 10 process x x x
冪等性 • ある操作を1回実行しても、複数回実行しても、同じ結果になる • 冪等性がない処理の例 ◦ 「ある変数の値を 現在値 + x
に更新する」 ◦ 実行のたびに違う値に更新される 11 process 初期値 + x 初期値 + 2x 初期値 + 3x
バッチ処理を冪等に作るモチベーション • バッチ処理設計の重要な考慮事項の一つが「回復可能か」 ◦ 「バッチ処理の採用と設計を考えてみよう」 (https://tech.mercari.com/entry/2019/02/27/112650) より • バッチ処理は様々な理由によって失敗する •
失敗したときのリカバリー容易性は非常に大事 • 冪等に作ることで、原因除去後に単純なリトライで回復可能に 12 recovery
何回実行されても大丈夫な バッチ処理を作る 13
方針は大きく2種類 • 処理済み含めてやり直すパターン • 一度処理したものをスキップするパターン 14
処理済み含めてやり直すパターン • バッチ処理が実行されるたびに全部の処理をやり直す • バッチ処理の個々のステップが冪等である前提が必要 • 他マイクロサービス(or外部サービス)にもリクエストを送る処理の場合は リクエスト先にも冪等性が必要 • 条件分岐を細かく考える必要がない
• 再実行には時間がかかる 15
一度処理したものをスキップするパターン • ステータス等で条件分岐し、処理済みのものをスキップする • 未処理のものだけを対象とするため、所要時間が短くて済む ◦ (未処理かどうかを判別するステップは必要だが) • 実装は条件分岐で複雑になりがち 16
どちらで実装している? • どちらのパターンも存在している • 要件によって選択 • ステート管理が必要なものについては自ずと「一度処理したものをス キップするパターン」になるのではないかと • 中間集計など単純にレコードを生成するような処理かつ、全部やり直し
ても大丈夫なぐらい時間的制約が緩いものは「処理済み含めてやり直 すパターン」により実装している ◦ もちろんレコードが重複して生成されないように適切なユニークキーを定義しておく前提 17
一度処理したものをスキップするパターンでの実装 • バッチが失敗したときに中途半端状態が生じないように実装を気をつけ る • 処理の再開地点以外の状態で落ちていることがないように。DBのトラン ザクション機能などを使って防ぎましょう 18 トランザクションの単位
再開地点
一度処理したものをスキップするパターンでの実装 • ステップの中に他サービスへのリクエスト処理が含まれている場合はど うすればいいか? ◦ 他サービスにリクエストを送ったあとにリクエスト済みステータスに DB更新するようなケースを想定 ◦ DB更新でエラーが発生したら? ◦
他サービスにキャンセルリクエストを送る? ◦ 他サービスが冪等に作られているならば、もう一度同じリクエストを 送るのは問題ないと考え、キャンセルせずにそのままリトライして解 消する 19
その他の取り組み 20
1. バッチを回す前の確認 • バッチ処理が処理する材料データは揃っているか? • 前段バッチが異常なく終了していることを確認しよう • バッチ履歴管理テーブルを作り、正常に終了したことを記録 • 後段のバッチ起動時に前段が終わっているかの確認を行っている
21
1. バッチを回す前の確認 • 前段の処理が別のマイクロサービスの場合は難しい • チーム間でどうやって前段の処理を知らせるか調整が必要 • 加盟店精算の会計データ取り込み処理の場合 ◦ 前段は会計システムのGCSへのデータエクスポート処理
◦ エクスポート処理終了時に指定名(export.done)の空ファイルを設 置してもらっている ◦ データ取り込み処理開始時にexport.doneが存在していない場合 はまだ前段が終わっていないとみなす 22
2. バッチが複数回処理された想定のテストを書く • 作ったバッチ処理、冪等になっていますか? • 下記のようなテストコードを書いて保証 ◦ 正常にバッチが回った状態に再度バッチ処理を実行する ◦ 途中でバッチがコケた状態に再度バッチ処理を実行する
23
まとめ 24
まとめ • 回復可能性を高めるためにバッチ処理を冪等に作ろう • 何回バッチを実行しても結果が変わらないように処理を作る • 処理済み含めてやり直す or 処理済みのものをスキップするように作る •
中途半端状態を作らないように設計しよう • 前段のバッチ処理が成功しているかを確認しよう • テストコードで冪等になっていることを保証しよう 25