【レポート】アーキテクチャ道場!(AWS-51) #AWSSummit
こんにちは!AWS事業本部コンサルティング部のたかくに(@takakuni_)です。
今回は、2022年5月25 - 26日の2日間で開催されているAWS Summit Online 2022のセッションレポートをしていきます。セッションのサマリーを理解し、興味があるセッションをチェックすることに、ご活用ください。また、セッションのアーカイブも公開されますので、詳細はそちらをチェックしてください。
本記事は、「アーキテクチャ道場!(AWS-51)」のレポート記事となります。
今回はセッションの中でも「特に私が勉強になった部分」をピックアップしてご紹介します。
※詳細はアーカイブセッションをご覧いただけますと幸いです。
セッション概要
概要
優れたアーキテクチャを設計するためのプラクティスを AWS のソリューションアーキテクトと一緒に学びましょう。 このセッションでは、 お題として提示されたシステム要件や技術的な課題に対して AWS のソリューションアーキテクトが実際に設計したアーキテクチャ例を題材に、 アーキテクチャを設計する際の着眼点、良いアーキテクチャが備えている性質、モデリングの手法やデザインパターンなどを議論・解説します。
スピーカー
AWS 技術統括本部 チーフテクノロジスト 内海 英一郎 氏
AWS 技術統括本部 インターネットメディアソリューション本部 ソリューションアーキテクト 奥野 友哉 氏
AWS 技術統括本部 インターネットメディアソリューション本部 部長 シニアソリューションアーキテクト 山﨑 翔太 氏
セッションレベル
Level 400: 上級者向け
セッションリンク(AWS Summit Online 2022 への登録が必要です)
※閲覧には、AWS Summit Online 2022の無料登録が必要です。
レポート
オンラインセール案件
- 数量限定のスニーカーを出品するオンラインサイト
- 販売開始にスパイクアクセスが発生する
- サービスのスケーラビリティが課題
- 専用システムを構築して対象アクセスを捌けるには?
- マイクロサービスアーキテクチャ
- BFFがあり以下のサービスと連携する
- 通常の商品在庫管理サービス
- 数量限定のスニーカーの在庫管理サービス
- 商品カートのサービス
- 抽選販売NG
- 在庫数を超えて商品の確保はNG
- 商品がカートに入った段階でトランザクションは完了とみなす
- チェックアウトやタイムアウトで商品がカートから削除などは考慮不要
DynamoDBのスケーリングについて
商品の在庫管理DBにDynamoDBを使用する場合、特定のItemにRead/Updateが集中するためPartitionあたりのRCU/WCUの制限に引っかかる可能性がある。
- 書き込みスケーリング
- シャーディングで課題解決
- Partitionが増加してしまう課題
- Partitionが増加してしまう課題解決
- Partition IDのリスト(在庫状態テーブル)を別途用意する
- リストに対して読み込みが集中してしまう
- リストに対して読み込みが集中してしまう課題解決
- Write-through cacheとしてDAXを使用する
- 元テーブルとの同期を取るためTTLを設定
在庫がなくなった場合
在庫状態テーブルと、在庫テーブルの同期をどうするか。
- 在庫テーブルを操作するマネージャーで在庫状態テーブルをアップデートする
- 在庫状態のアップデートに失敗した場合、不整合が発生する
- マネージャーが操作を担っているためスループットや実装が煩雑になる
- DynamoDB Streamsで変更履歴からLambdaで在庫状態をアップデートする
- Updateに失敗した場合でもDLQに残せる
- Lambda障害時もイベント履歴が残る
- 最終的に整合性の確保ができる
Q&A
- BFFが在庫確保に失敗した場合
- ジッター付きのエクスポネンシャルバックオフのリトライを行う
- アクセスの平準化
- 既存カートサービスが動かない時
- 在庫管理とカートの整合性
- まずはリトライ処理の実装
- リトライ処理もうまくいかない時
- DynamoDB StreamsとLambdaで在庫数を回復し整合性を確保
- 一連の流れには共通IDを使用してのデータ連携を行う
まとめ
- 書き込みを「シャーディング」でスケールする
- 1つのItemで在庫管理しない複数のItemで管理する
- 読み込みは「複製」でスケールする
- 在庫状態の複製をDAXで読み込みリクエストをスケール
- DBのUpdateをアトミックに行う
- DB更新後のDynamoDB StreamsとLambdaで整合性管理
SaaSメータリング案件
- 課金システムの開発
- テナント別の集計結果をダッシュボードに表示
- ダッシュボードはできるだけリアルタイムに反映
- 前提
- SaaSアプリケーション→課金システム→ダッシュボード
- 機能ごとにSaaSアプリケーションは料金プランが変わる
- 機能A:トランザクション実行数で課金
- 機能B:利用時間に応じて課金
- 課金額はダッシュボードに表示時点の単価(ダッシュボードは毎日更新)
システムの責任範囲
- SaaSアプリケーション
- 使用したデータ量を課金システムに送信する
- SaaSはサービス提供の維持を優先(データ遅延は次点以降の優先度)
- データを一意に送信
- 課金システム
- 受信してダッシュボードへ表示
- 遅延したデータもダッシュボードへ表示
- データの重複を防止して表示
設計
- 機能A:トランザクション毎に同期で送信
- 機能B:利用終了時に同期で送信
- 課金システムは1つのデータベースに全てのデータを格納
データベースへの書き込み不可
- 機能Aはトランザクションの数に比例して書き込みが増加する
- 機能Bではデータベース内部で、ダッシュボードのAPIリクエストに複雑なクエリを要する
- 解決策
- 機能Aは1分前に事前集計して書き込みリクエストを減らす
- 機能Bも1分前に同期処理する
可用性
- SaaSアプリケーションや、課金システムの障害時に同期で送っているためメータリングができない
- 事前集計のタイミングで遅延したデータの処理を上手く実装する必要がある
- 解決策
- データ送信を非同期に送る
- データの処理時間を利用することで遅延処理に対応
二重計上
- トランザクションデータの重複排除
- データベースの重複排除
- 解決策
- トランザクションIDの搭載
- 集計単位でタイムスタンプを作成してレコードを作成
AWSを使用した実装
- SaaSからのデータ収集:Kinesis Data Streams
- トランザクションIDをパーティションキーにして送信
- 重複排除:AWS Lambda、DynamoDBテーブル
- トランザクションIDの有無を確認して書き込む
- Lambdaからデータ受け取り:Kinesis Data Streams
- データ分析:Kinesis Data Analytics
- データベースへの書き込み:Lambda、RDS proxy
- データベース接続数を減らしながら書き込み
- データベース:RDS
- 使用量を収集、送信:ECSからALBへ送信
Q&A
- 重複排除で発生したトランザクションイベントの保持期間ウィンドウの実装方法
- DynamoDBのTTLで保持期間ウィンドウの実装
- 保持期間を過ぎて再試行されたデータの扱い
- ドロップまたは流す
- 流すのがポリシーにあっている(遅れたデータも担保するため)
- 重複排除でウィンドウの管理も必要になる
まとめ
- 分散ストリーム処理はトレードオフがある
- 完全性、コスト、レイテンシー
- 各機能の重複排除の種類や手法をまとめるとシンプルになるかも
- AuroraとKinesis Analyticsでテナントを収容するのは将来的に大変
- セルアーキテクチャを用いて将来的な規模の拡張を解決
- 課金システムを1つのセルとみなす
- セル毎にテナントを制限する
- セルの複製を作ってテナントの増加を管理
- セルとテナントのマッピングをDynamoDBで管理
- 読取はDAXでカバーも可能
- SaaSと課金システム間でテナントをルーティング
おわりに
本セッションではAWSのSAさんの設計思想がうかがえるとても良いセッションだったと思います。特にDynamoDBの活用方法が参考になりました。
私自身も、設計を考える上で大変参考になるポイントが多々ありソリューションアーキテクトとして活動されている方にはぜひ1度ご覧いただきたいセッションでした。
なお、本セッションはオンデマンドで2022年6月30日(木)まで配信中です。
見逃した方は、ぜひ登録してご覧いただければと思います。
以上、AWS事業本部コンサルティング部のたかくに(@takakuni_)でした!