Slide 1

Slide 1 text

店舗在庫連携のCQRSを支えるメッ セージング周りの技術
 株式会社ZOZO
 ブランドソリューション開発本部 ZOZOMO部プロダクト開発ブロック
 岡元 政大 Copyright © ZOZO, Inc. 1

Slide 2

Slide 2 text

© ZOZO, Inc. 株式会社ZOZO
 ブランドソリューション開発本部 ZOZOMO部
 プロダクト開発ブロック
 岡元 政大
 ● 宮崎生まれ、宮崎育ち
 ● 2022年6月に岐阜に移住、生粋の岐阜県民となるべく修 行中
 ● ZOZOMOブランド実店舗の在庫確認・在庫取り置きサー ビス(以降、店舗在庫連携)の設計、開発に従事
 2

Slide 3

Slide 3 text

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


Slide 4

Slide 4 text

© ZOZO, Inc. 目次
 ● 店舗在庫連携サービスとは
 ● 安全にDBとメッセージングシステムに書き込むには?
 ○ 考えられる2つの方法(二重書き込み、分散トランザクション)と問題点
 ○ OutboxパターンとCDCの詳細
 ● 店舗在庫連携(AWS)では
 ○ これらを踏まえ店舗在庫連携ではどうしているか
 ● まとめ
 ● 参考文献
 4

Slide 5

Slide 5 text

© ZOZO, Inc. 5 店舗在庫連携とは
 ● ZOZOTOWN上で店舗の商品を取り置きできるサービス


Slide 6

Slide 6 text

© ZOZO, Inc. ● ZOZOTOWN上で店舗の商品を取り置きできるサービス
 ● 取り置き受付時の例
 店舗在庫連携とは
 6 バリデーション ・会員のステータス ・在庫確保

Slide 7

Slide 7 text

© ZOZO, Inc. ● ZOZOTOWN上で店舗の商品を取り置きできるサービス
 ● 取り置き受付時の例
 店舗在庫連携とは
 7 バリデーション ・会員のステータス ・在庫確保

Slide 8

Slide 8 text

© ZOZO, Inc. Q. 安全にメッセージングシステムに書き込むには?
 ● 「安全に」って🤔?
 ○ DBの状態とメッセージングシステムの状態に不整合が無いこと
 ■ (このお話上では)
 8 DB書き込み メッセージングシステム書き 込み 整合性 起こる不都合 ✕ ✕ OK ◯ ✕ NG データは存在するが、通知が飛ばない ✕ ◯ NG 通知は飛ぶが、データが存在しない ◯ ◯ OK

Slide 9

Slide 9 text

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


Slide 10

Slide 10 text

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


Slide 11

Slide 11 text

© ZOZO, Inc. Q. 安全にメッセージングシステムに書き込むには?
 ● 二重書き込みを使わず、楽にメッセージングしたい。。
 11

Slide 12

Slide 12 text

© ZOZO, Inc. Q. 安全にメッセージングシステムに書き込むには?
 ● 二重書き込みを使わず、楽にメッセージングしたい。。
 ● 分散トランザクション(グローバルトランザクション)が使え そう?
 ○ 複数のシステム間でアトミックなコミットを実行し、一貫性を保っ てくれる
 ■ 2相コミットなど
 ○ X/Open XA
 ■ ヘテロジニアスな技術間での2相コミットの標準
 12 ※ 「データ指向アプリケーションデザイン」pp.384-398 


Slide 13

Slide 13 text

© 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 


Slide 14

Slide 14 text

© ZOZO, Inc. Q. 安全にメッセージングシステムに書き込むには?
 ● Transactional outboxパターン(Outboxパターン)
 ○ 以下のテーブルにローカルトランザクションを用いて 書き込みを行う
 ■ 通常利用するテーブルたち - 集約の状態等を保存する
 ■ Outboxテーブル - 状態変更時のメッセージ(ドメインイベ ント等)を追記する
 ○ 分散トランザクションを使用せずローカルトランザク ションのみでメッセージをアトミックに作成できる!
 ■ メッセージを送出するには?
 14 ※ 「Transactional outbox」 https://microservices.io/patterns/data/transactional-outbox.html 


Slide 15

Slide 15 text

© 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


Slide 16

Slide 16 text

© 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 


Slide 17

Slide 17 text

© 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 


Slide 18

Slide 18 text

© 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 


Slide 19

Slide 19 text

© 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 


Slide 20

Slide 20 text

© 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/ 


Slide 21

Slide 21 text

© 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

Slide 22

Slide 22 text

© 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

Slide 23

Slide 23 text

© ZOZO, Inc. We’re Hiring
 ● エンジニア募集 ○ https://hrmos.co/pages/zozotech/jobs/0000066
 23 ● カジュアル面談 ○ https://zozotech-inc.connpass.com/event/26557 7/


Slide 24

Slide 24 text

No content