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

店舗在庫連携のCQRSを支えるメッセージング周りの技術 / Messaging and Pat...

mokamoto12
November 28, 2022
2.1k

店舗在庫連携のCQRSを支えるメッセージング周りの技術 / Messaging and Patterns in DynamoDB for CQRS

mokamoto12

November 28, 2022
Tweet

Transcript

  1. © ZOZO, Inc. 株式会社ZOZO
 ブランドソリューション開発本部 ZOZOMO部
 プロダクト開発ブロック
 岡元 政大
 •

    宮崎生まれ、宮崎育ち
 • 2022年6月に岐阜に移住、生粋の岐阜県民となるべく修 行中
 • ZOZOMOブランド実店舗の在庫確認・在庫取り置きサー ビス(以降、店舗在庫連携)の設計、開発に従事
 2
  2. © ZOZO, Inc. https://zozo.jp/
 3 • ファッションEC
 • 1,500以上のショップ、8,500以上のブランドの取り扱い
 •

    常時90万点以上の商品アイテム数と毎日平均2,600点以上の新着 商 品を掲載(2022年6月末時点)
 • ブランド古着のファッションゾーン「ZOZOUSED」や
 コスメ専門モール「ZOZOCOSME」、靴の専門モール
 「ZOZOSHOES」、ラグジュアリー&デザイナーズゾーン
 「ZOZOVILLA」を展開
 • 即日配送サービス
 • ギフトラッピングサービス
 • ツケ払い など

  3. © ZOZO, Inc. 目次
 • 店舗在庫連携サービスとは
 • 安全にDBとメッセージングシステムに書き込むには?
 ◦ 考えられる2つの方法(二重書き込み、分散トランザクション)と問題点


    ◦ OutboxパターンとCDCの詳細
 • 店舗在庫連携(AWS)では
 ◦ これらを踏まえ店舗在庫連携ではどうしているか
 • まとめ
 • 参考文献
 4
  4. © ZOZO, Inc. Q. 安全にメッセージングシステムに書き込むには?
 • 「安全に」って🤔?
 ◦ DBの状態とメッセージングシステムの状態に不整合が無いこと
 ▪

    (このお話上では)
 8 DB書き込み メッセージングシステム書き 込み 整合性 起こる不都合 ✕ ✕ OK ◯ ✕ NG データは存在するが、通知が飛ばない ✕ ◯ NG 通知は飛ぶが、データが存在しない ◯ ◯ OK
  5. © ZOZO, Inc. Q. 安全にメッセージングシステムに書き込むには?
 • 二重書き込み(Dual Writes)
 ◦ DBへ書き込んでメッセージングシステムに書き込む


    ◦ メリット
 ▪ 不整合が起きて良い状況では、実装が単純
 ◦ デメリット
 ▪ DBへの書き込みは成功するけど、メッセージングシステムへの書き 込みは失敗するということが起きうる
 • 不整合が起きうる
 • ロールバック処理などが必要?
 9 ※ 「Dual Writes - The Unknown Cause of Data Inconsistencies」 https://thorben-janssen.com/dual-writes/ 

  6. © ZOZO, Inc. ロールバック Q. 安全にメッセージングシステムに書き込むには?
 • 二重書き込み(Dual Writes)
 ◦

    ロールバック処理などが必要?
 ▪ ロールバック処理が成功するとは限らない
 • アプリケーションやDBのクラッシュ
 ▪ ロールバックが完了する前に他の処理がロールバック対象の データを読んでしまうかも
 • 実装で気をつける必要がある
 ◦ メッセージングシステムに書き込み、DBに書き込む流れで も問題が起きる
 ▪ メッセージングシステムへ書き込んだデータのロールバック難しい など
 10 ※ 「Dual Writes - The Unknown Cause of Data Inconsistencies」 https://thorben-janssen.com/dual-writes/ 

  7. © ZOZO, Inc. Q. 安全にメッセージングシステムに書き込むには?
 • 二重書き込みを使わず、楽にメッセージングしたい。。
 • 分散トランザクション(グローバルトランザクション)が使え そう?


    ◦ 複数のシステム間でアトミックなコミットを実行し、一貫性を保っ てくれる
 ▪ 2相コミットなど
 ◦ X/Open XA
 ▪ ヘテロジニアスな技術間での2相コミットの標準
 12 ※ 「データ指向アプリケーションデザイン」pp.384-398 

  8. © ZOZO, Inc. Q. 安全にメッセージングシステムに書き込むには?
 • 分散トランザクション
 ◦ X/Open XA


    ▪ パフォーマンスに影響がある※1
 • ディスクへの強制的な書き込み
 ◦ コーディネータのクラッシュ時のリカバリ用
 • ネットワークのラウンドトリップ
 ▪ 最近のDB、メッセージングシステムではサポートされない傾向※2
 • 技術選定の幅を狭める※2、3
 • そこで、、
 ◦ Transactional outboxパターン
 + 変更データキャプチャ(CDC)
 13 ※1 「データ指向アプリケーションデザイン」p.393 
 ※2 「マイクロサービスパターン」pp.124-125 
 ※3 「実践ドメイン駆動設計」 p.291 

  9. © ZOZO, Inc. Q. 安全にメッセージングシステムに書き込むには?
 • Transactional outboxパターン(Outboxパターン)
 ◦ 以下のテーブルにローカルトランザクションを用いて

    書き込みを行う
 ▪ 通常利用するテーブルたち - 集約の状態等を保存する
 ▪ Outboxテーブル - 状態変更時のメッセージ(ドメインイベ ント等)を追記する
 ◦ 分散トランザクションを使用せずローカルトランザク ションのみでメッセージをアトミックに作成できる!
 ▪ メッセージを送出するには?
 14 ※ 「Transactional outbox」 https://microservices.io/patterns/data/transactional-outbox.html 

  10. © ZOZO, Inc. • 変更データキャプチャ(Change Data Capture、CDC)
 ◦ DBに起きた変更を追跡し処理を行うための機能※1
 ▪

    これを使って、DBの変更をメッセージとして扱う
 ◦ CDCには次のような種類がある
 ▪ Query-based CDC(Polling publisherパターン)
 ▪ Log-based CDC(Transaction log tailingパターン)
 • その他Trigger-basedなものや、Diff-basedなものなど※2
 Q. 安全にメッセージングシステムに書き込むには?
 15 ※1 「データ指向アプリケーションデザイン」p.497 
 ※2 「Everything you need to know about Change Data Capture」 https://datacater.io/blog/2020-06-22/everything-you-need-to-know-about-cdc.htm l

  11. © ZOZO, Inc. Q. 安全にメッセージングシステムに書き込むには?
 • Query-based CDC(Polling publisherパターン※1)
 ◦

    定期的にテーブルをポーリングする
 ▪ クエリのイメージ:SELECT * FROM outbox WHERE ts > :previous_ts
 ▪ DBに余計な負荷をかける場合がある
 ▪ 範囲クエリをサポートしないDBで実装が困難(NoSQLなど)
 • Log-based CDC(Transaction log tailingパターン※2)
 ◦ DBのTransaction logを見て変更を追跡する
 ▪ MySQLの場合はbinlog、PostgreSQLの場合はWALなど
 ▪ DB固有のソリューションが必要
 ◦ ポーリング、範囲クエリのサポートが必要ない
 16 ※1 「Polling publisher」 https://microservices.io/patterns/data/polling-publisher.html 
 ※2 「Transaction log tailing」 https://microservices.io/patterns/data/transaction-log-tailing.html 

  12. © ZOZO, Inc. 店舗在庫連携(AWS)では
 17 • Outbox + CDCでメッセージング
 •

    データ永続化周りのポイント
 ◦ DynamoDBのトランザクションを使ったOutboxパ ターンの実現
 ◦ Kinesis Data Streams for DDB(CDC)によるメッ セージング
 ◦ DDBの条件付き書き込みによるロストアップ デートの回避
 ◦ Protobufによるメッセージスキーマ(公表された 言語※1)の定義
 ※ 「DynamoDBによるOutboxパターンとCDCを用いたCQRSアーキテクチャの実装〜ZOZOMOでの取り組み - ZOZO TECH BLOG」 https://techblog.zozo.com/entry/implementation-of-cqrs-using-outbox-and-cdc-with-dynamodb 
 ※1 「実践ドメイン駆動設計」 p.96 

  13. © ZOZO, Inc. 店舗在庫連携では
 • DynamoDBのトランザクション※1を使ったOutboxパターンの実現
 ◦ 以下の2テーブルにトランザクションを使って書き込む
 ▪ 集約テーブル:

    集約の状態を保存する
 • レコードにはバージョンを持たせておき、状態が変わるたびに+1する
 ◦ このレコードのバージョンはロストアップデートの回避に用いる
 ▪ イベントテーブル: 集約の状態が変わる際に発生したイベントを追記する
 • イベントにも集約が持っているバージョンを持たせておき、重複除去に利用する
 • Kinesis Data Streams for DDB(CDC)によるメッセージング
 ◦ イベントテーブルに追記されたレコードをKDSに流す
 ◦ コンシューマ側のスループットの関係でDDB StreamsではなくKDS for DDBを使ってる※2
 18 ※1 「DynamoDB トランザクションで複雑なワークフローを管理する - Amazon DynamoDB」 https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/transactions.html 
 ※2 「Amazon DynamoDB の変更データキャプチャ - Amazon DynamoDB」 https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/streamsmain.html 

  14. © ZOZO, Inc. 店舗在庫連携では
 • DDBの条件付き書き込みによるロストアップデートの回避※1
 ◦ 書き込みの際、他処理から更新されていないか確認する: 楽観的ロック
 ▪

    条件のイメージ: version_on_ddb = :previous_version
 • version_on_ddb: DDB上のレコードのバージョン
 • :previous_version: 書き込もうとしている集約の更新前のバージョン
 ▪ 他の処理で更新がかかっている場合、
 • version_on_ddbが大きい値になり、上の条件が成り立たず書き込みが失敗する
 • Protocol Buffersによるメッセージスキーマの定義
 ◦ 言語に対して中立的、生成されるコードがいい感じ(Java、所感)
 ◦ 将来的に、取置きのイベントに関心のある機能もそれぞれ独自にコンシューマを開発したり
 ▪ 「“取り置き受付”が起きたら“アプリから通知送る”」とか
 ◦ DDDの用語でいうと「公表された言語」
 19 ※1 「バージョン番号を使用した楽観的ロック - Amazon DynamoDB」 https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/DynamoDBMapper.OptimisticLocking.html 

  15. © ZOZO, Inc. まとめ
 • 二重書き込みは不整合を起こしうる
 ◦ “Dual writes are

    often underestimated, and a lot of developers aren’t even aware of the potential data inconsistencies.”※1
 ▪ 「二重書き込みはしばしば過小評価されており、多くの開発者は潜在的なデータの不整合にさえ気づいていま せん。」(Google翻訳)
 • Outbox + CDCでメッセージングを安全に
 ◦ DynamoDBなどCDCを第一級のインターフェースとしてサポートするDBも※2
 ▪ TiDBやCloud Spannerなどもサポートしてるらしい※3、4(知らんけど)
 ◦ CQRSやイベント駆動、Saga※5も全ては安全なメッセージングから
 20 ※1 「Dual Writes - The Unknown Cause of Data Inconsistencies」 https://thorben-janssen.com/dual-writes/ 
 ※2 「データ指向アプリケーションデザイン」 p.500、※3 「TiCDC Overview | PingCAP Docs」 https://docs.pingcap.com/tidb/dev/ticdc-overview 
 ※4 「Cloud Spanner の変更ストリームでトランザクション データをさらに活用 | Google Cloud 公式ブログ」 https://cloud.google.com/blog/ja/products/databases/track-and-integrate-change-data-with-spanner-change-streams 
 ※5 「Outboxパターンを使用したマイクロサービスのSagaオーケストレーション」 https://www.infoq.com/jp/articles/saga-orchestration-outbox/ 

  16. © ZOZO, Inc. 参考文献(1/2)
 • “Dual Writes - The Unknown

    Cause of Data Inconsistencies” https://thorben-janssen.com/dual-writes/
 • Martin Kleppmann、斉藤太郎(監訳)、玉川竜司(訳): データ指向アプリケーションデザイン. オライリー・ジャパン, 2019
 • Chris Richardson、長尾高弘(訳)、樽澤広亨(監修): マイクロサービスパターン. インプレス, 2020
 • Vaughn Vernon、高木正弘(翻訳): 実践ドメイン駆動設計. 翔泳社, 2015
 • “Transactional outbox” https://microservices.io/patterns/data/transactional-outbox.html
 • “Everything you need to know about Change Data Capture” https://datacater.io/blog/2020-06-22/everything-you-need-to-know-about-cdc.html
 • “Polling publisher” https://microservices.io/patterns/data/polling-publisher.html
 • “Transaction log tailing” https://microservices.io/patterns/data/transaction-log-tailing.html
 • “DynamoDBによるOutboxパターンとCDCを用いたCQRSアーキテクチャの実装〜ZOZOMOでの取り組み - ZOZO TECH BLOG” https://techblog.zozo.com/entry/implementation-of-cqrs-using-outbox-and-cdc-with-dynamodb
 21
  17. © ZOZO, Inc. 参考文献(2/2)
 
 • “DynamoDB トランザクションで複雑なワークフローを管理する - Amazon

    DynamoDB” https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/transactions.html
 • “Amazon DynamoDB の変更データキャプチャ - Amazon DynamoDB” https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/streamsmain.html
 • “バージョン番号を使用した楽観的ロック - Amazon DynamoDB” https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/DynamoDBMapper.OptimisticLocking.h tml
 • “TiCDC Overview | PingCAP Docs” https://docs.pingcap.com/tidb/dev/ticdc-overview
 • “Cloud Spanner の変更ストリームでトランザクション データをさらに活用 | Google Cloud 公式ブログ” https://cloud.google.com/blog/ja/products/databases/track-and-integrate-change-data-with-spanner-change-str eams
 • “Outboxパターンを使用したマイクロサービスのSagaオーケストレーション” https://www.infoq.com/jp/articles/saga-orchestration-outbox/
 22
  18. © ZOZO, Inc. We’re Hiring
 • エンジニア募集 ◦ https://hrmos.co/pages/zozotech/jobs/0000066
 23

    • カジュアル面談 ◦ https://zozotech-inc.connpass.com/event/26557 7/