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
5k
バッチ処理と冪等性 / 20191218_merpay_techtalk
kaznishi
December 18, 2019
Tweet
Share
More Decks by kaznishi
See All by kaznishi
Finally_I_can_kichijojipm32
kaznishi
0
560
Bounds Check Eliminationについて調べてみた / 1218-lt
kaznishi
0
460
Hello, Prometheus!! Goで作るexporter自作入門 / 180727 LT
kaznishi
6
3.6k
Goのスライス容量拡張量がどのように決まるのか追った / 180713 LT
kaznishi
3
3.6k
スライス容量拡張量がどのように決まるのか追った / 180709 LT
kaznishi
0
150
Other Decks in Technology
See All in Technology
システムとの会話から生まれる先手のDevOps
kakehashi
PRO
0
280
4/16/25 - SFJug - Java meets AI: Build LLM-Powered Apps with LangChain4j
edeandrea
PRO
1
100
SREからゼロイチプロダクト開発へ ー越境する打席の立ち方と期待への応え方ー / Product Engineering Night #8
itkq
2
670
品質文化を支える小さいクロスファンクショナルなチーム / Cross-functional teams fostering quality culture
toma_sm
0
100
SmartHR プロダクトエンジニア求人ガイド_2025 / PdE job guide 2025
smarthr
0
110
日経電子版 for Android の技術的課題と取り組み(令和最新版)/android-20250423
nikkei_engineer_recruiting
0
250
生成AIによるCloud Native基盤構築の可能性と実践的ガードレールの敷設について
nwiizo
6
590
Porting PicoRuby to Another Microcontroller: ESP32
yuuu
4
410
はじめてのSDET / My first challenge as a SDET
bun913
1
250
OpenSearchでレガシーな検索処理の大幅改善をやってやろう
dznbk
2
170
食べログが挑む!飲食店ネット予約システムで自動テスト無双して手動テストゼロを実現する戦略
hagevvashi
3
420
IVRyにおけるNLP活用と NLP2025の関連論文紹介
keisukeosone
0
200
Featured
See All Featured
Bash Introduction
62gerente
611
210k
BBQ
matthewcrist
88
9.6k
What's in a price? How to price your products and services
michaelherold
245
12k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
41
2.2k
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
280
13k
YesSQL, Process and Tooling at Scale
rocio
172
14k
Product Roadmaps are Hard
iamctodd
PRO
52
11k
Large-scale JavaScript Application Architecture
addyosmani
512
110k
Side Projects
sachag
452
42k
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
32
5.4k
Unsuck your backbone
ammeep
670
57k
Building Applications with DynamoDB
mza
94
6.3k
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