Upgrade to PRO for Only $50/Year—Limited-Time Offer! 🔥
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
630
Bounds Check Eliminationについて調べてみた / 1218-lt
kaznishi
0
530
Hello, Prometheus!! Goで作るexporter自作入門 / 180727 LT
kaznishi
6
3.8k
Goのスライス容量拡張量がどのように決まるのか追った / 180713 LT
kaznishi
3
3.7k
スライス容量拡張量がどのように決まるのか追った / 180709 LT
kaznishi
0
170
Other Decks in Technology
See All in Technology
Microsoft Agent 365 についてゆっくりじっくり理解する!
skmkzyk
0
370
GitHub Copilotを使いこなす 実例に学ぶAIコーディング活用術
74th
3
3.4k
Python 3.14 Overview
lycorptech_jp
PRO
1
120
AIエージェント開発と活用を加速するワークフロー自動生成への挑戦
shibuiwilliam
2
100
AI駆動開発における設計思想 認知負荷を下げるフロントエンドアーキテクチャ/ 20251211 Teppei Hanai
shift_evolve
PRO
2
420
AWS Security Agentの紹介/introducing-aws-security-agent
tomoki10
0
300
re:Invent 2025 ~何をする者であり、どこへいくのか~
tetutetu214
0
220
モダンデータスタック (MDS) の話とデータ分析が起こすビジネス変革
sutotakeshi
0
510
Lookerで実現するセキュアな外部データ提供
zozotech
PRO
0
150
CARTAのAI CoE が挑む「事業を進化させる AI エンジニアリング」 / carta ai coe evolution business ai engineering
carta_engineering
0
1.9k
AIプラットフォームにおけるMLflowの利用について
lycorptech_jp
PRO
1
170
.NET 10の概要
tomokusaba
0
110
Featured
See All Featured
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
659
61k
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
Agile that works and the tools we love
rasmusluckow
331
21k
Leading Effective Engineering Teams in the AI Era
addyosmani
8
1.3k
Music & Morning Musume
bryan
46
7k
Principles of Awesome APIs and How to Build Them.
keavy
127
17k
RailsConf 2023
tenderlove
30
1.3k
Embracing the Ebb and Flow
colly
88
4.9k
Measuring & Analyzing Core Web Vitals
bluesmoon
9
710
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
234
17k
Stop Working from a Prison Cell
hatefulcrawdad
273
21k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
359
30k
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