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

あれは良かった、あれは苦労したB2B2C型SaaSの新規開発におけるCloud Spanner

あれは良かった、あれは苦労したB2B2C型SaaSの新規開発におけるCloud Spanner

Nagatomo Hirohito

February 18, 2025
Tweet

Other Decks in Technology

Transcript

  1. © ASOVIEW Inc. 2 自己紹介
 長友 宏仁 アソビュー株式会社/エンターテインメント PF開発部/エンジニア 2019年~

    SES 大規模旅行予約サイトのtoB・toC向けの機能開発や大規模システムの刷新プロ ジェクトを経験。 2022年~ アソビュー株式会社 座席指定チケット販売を主力とした B2B2C型SaaSの新規開発の立ち上げに参加。 複数のコア機能・データベースの設計・実装を担当。
  2. © ASOVIEW Inc. 3 目次
 • 会社紹介
 • Cloud Spannerを導入したプロダクト


    • Cloud Spannerの導入により目指した状態と現状 
 • 開発1年プロダクト運用1年で見えたリアルな課題と失敗 
 • 今後の展望

  3. © ASOVIEW Inc. 4 アソビューについて 
 Mission Vision Value 生きるに、遊びを。

    
 FOR YOU すべては顧客の期待を超えるために
 PROFESSIONAL ONE TEAM プロであり続けるために
 
 チームに貢献するために

  4. © ASOVIEW Inc. 6 目次
 • 会社紹介
 • Cloud Spannerを導入したプロダクト


    • Cloud Spannerの導入により目指した状態と現状 
 • 開発1年プロダクト運用1年で見えたリアルな課題と失敗 
 • 今後の展望

  5. © ASOVIEW Inc. 7 Cloud Spannerを導入したプロダクト
 新規事業: エンターテインメント業界向け 座席予約型チケッ ティングSaaS

    • B2B2Cモデル ◦ パートナー向け機能とゲスト向け機能の両⽅を提供 ◦ 主催者としても、プレイガイドとしても振る舞う • 機能の⼀元管理 ◦ 会場データ登録 ◦ プラン⼊稿 ◦ チケット販売 ◦ 在庫管理 ◦ 現地着券 ◦ 精算 etc.. • 座席指定型エンターテインメントに最適 イベント運営の全プロセスをサポート
  6. © ASOVIEW Inc. 9 Cloud Spannerを導入したプロダクト ~ Spannerを取り巻く技術
 • バックエンドAPI群はJavaとSpring

    Bootで構成 • DDDとCQRSの思想で開発 ◦ Command ServiceではRead Write TransactionとRead Only Transaction併⽤ ◦ Query ServiceではRead Only Transaction • O/R MapperにはDoma2 ✖ Spanner JDBCを利⽤ ◦ クライアントライブラリの⽅が細かな制御が可能だが、メンバーの馴染みやす さ‧書きやすさを重視 • キャッシュにはDynamoDBを利⽤
  7. © ASOVIEW Inc. 10 目次
 • 会社紹介
 • Cloud Spannerを導入したプロダクト


    • Cloud Spannerの導入により目指した状態と現状 
 • 開発1年プロダクト運用1年で見えたリアルな課題と失敗 
 • 今後の展望

  8. © ASOVIEW Inc. 11 Cloud Spannerの導入により目指した状態と現状 ~ 想定される課題
 プロダクト⾯ •

    トランザクションの急激な増加 ◦ 扱う興⾏によっては販売と同時にスパイク • 在庫データ管理の難易度‧複雑さ ◦ 申込、配券などの在庫管理操作トランザクションの競合の可能性 • 特定の興⾏への負荷集中による影響が全体へ波及する懸念 • 今後のサービス規模の拡⼤で上記の課題が更にリスクとなること 運⽤⾯ • 新規プロダクトゆえの⼈員リソースの問題 ◦ 限られたメンバーで開発と並⾏して運⽤が回せること ◦ チームに完結しやすい運⽤‧管理
  9. © ASOVIEW Inc. 13 目指した状態 現状 可用性の高さ ◎: 安定稼働。ただし現状のトランザクション 規模がまだ課題になるようなレベルにない

    ダブルブッキングの心配のない強整合性 ◎: 1年稼働してダブルブッキングなし。設計や実 装も非常に重要 運用コスト ◎: 運用管理がチームに完結。コンソール画面が 充実している。外部キーが貼りやすい。 Cloud Spannerの導入により目指した状態と現状

  10. © ASOVIEW Inc. 14 目指した状態 現状 可用性の高さ ◎: 安定稼働。ただし現状のトランザクション 規模がまだ課題になるようなレベルにない

    ダブルブッキングの心配のない強整合性 ◎: 1年稼働してダブルブッキングなし。設計や実 装も非常に重要 運用コスト ◎: 運用管理がチームに完結。コンソール画面が 充実している。外部キーが貼りやすい。 Cloud Spannerの導入により目指した状態と現状

  11. © ASOVIEW Inc. 15 Cloud Spannerの導入により目指した状態と現状 ~ 強整合性
 • Cloud

    Spannerのロックはトランザクション分離レベル「Serializable」相当 • 更新系のユースケースでは対象EntityをSELECTするだけでロックOK ◦ SELECT FOR UPDATEなどは意識不要。 ◦ 簡単なユースケースでは宣⾔的トランザクションだけで OK(@Transactionalなど) ◦ そもそもSELECT FOR UPDATEは存在しなかった ◦ 最近Abortの頻度を減らしたいケースでSELECT FOR UPDATEを利⽤できる ようになった
  12. © ASOVIEW Inc. 16 Cloud Spannerの導入により目指した状態と現状 ~ 強整合性、ただし...
 ロックが⾮常に強⼒ →広範囲な検索クエリはRead

    Write TransactionではAbortや待ちの原因になるこ とも ユースケース例: 指定条件においておすすめ順に座席を確保し予約
  13. © ASOVIEW Inc. 17 Cloud Spannerの導入により目指した状態と現状 ~ 強整合性、ただし...
 アプローチ 1

    ‒ 単⼀ Read Write Transaction • 座席の取得から予約更新までを1つの Read Write Trsancation トランザクション 内で実施 • メリット ◦ 取得から更新までの間に状態が変わるリスクがなく、⼀括で原⼦性を保証 • デメリット ◦ 同時予約リクエストが殺到すると、1トランザクション内での競合が頻発 し、Abort(コミット失敗)率が上昇する可能性がある
  14. © ASOVIEW Inc. 18 Cloud Spannerの導入により目指した状態と現状 ~ 強整合性、ただし...
 アプローチ 2

    ‒ 2段階トランザクション(Read Only → Read Write) • Step1: Read Only Transactionで指定条件の予約可能な座席候補を取得 • Step2: 候補の中からランダムに選択 • Step3: Read Write Trasancationでその座席を再度取得→予約 • Step4: Step3で状態が変わっているとアプリケーション上でRetry • メリット ◦ 読み取り時のロック範囲が抑えられるため、初期負荷を軽減できる ◦ 座席候補取得段階で競合リスクを部分的に低減可能 • デメリット ◦ 2トランザクションにギャップがあるため、候補取得後に他の予約で更新される リスクが残る
  15. © ASOVIEW Inc. 19 目指した状態 現状 可用性の高さ ◎: 安定稼働。ただし現状のトランザクション 規模がまだ課題になるようなレベルにない

    ダブルブッキングの心配のない強整合性 ◎: 1年稼働してダブルブッキングなし。設計や実 装も非常に重要 運用コスト ◎: 運用管理がチームに完結。コンソール画面が 充実している。外部キーが貼りやすい。 Cloud Spannerの導入により目指した状態と現状

  16. © ASOVIEW Inc. 21 目次
 • 会社紹介
 • Cloud Spannerを導入したプロダクト


    • Cloud Spannerの導入により目指した状態と現状 
 • 開発1年プロダクト運用1年で見えたリアルな課題と失敗 
 • 今後の展望

  17. © ASOVIEW Inc. 22 • Cloud Spannerのナレッジは世間的に増えている (印象)
 ◦ 一般的な特徴やベストプラクティスは各所で語られている

    
 ▪ 可用性の高さ・運用コストの低さ 
 ▪ 強整合性
 ▪ インターリーブ、mutations、セカンダリインデックス などの概念
 ▪ ホットスポット etc…
 
 開発1年プロダクト運用1年で見えたリアルな課題と失敗 ~ 前提

  18. © ASOVIEW Inc. 23 • とは言え、Spannerの知見ゼロから始まった新規プロダク ト開発...
 ◦ 時間・人数リソースの制約
 ◦

    初見のものを学びながら開発する難しさ 
 • 結果...
 ◦ (世間で語られているような)目に見えてるバッドプラク ティスを見事に踏み抜いたり
 ◦ (観測した限りだと)初見なものにハマったり...
 開発1年プロダクト運用1年で見えたリアルな課題と失敗 ~ 前提
 世間で既に言われているものであっても、 改めて触れておきたい Cloud Spannerの導入におけるリアルな課題と失敗 について、開発 メンバー視点でいくつか紹介
  19. © ASOVIEW Inc. 24 外部キーを利用した正規化に拘りすぎると Spannerのパフォーマンスは損なわれやすい 
 
 開発1年プロダクト運用1年で見えたリアルな課題と失敗
 •

    HogeParentとHogeChild
 ◦ インターリーブなので高速
 • HogeParentとFoo
 ◦ 外部キー結合になるためイン ターリーブよりパフォーマンス が落ちやすい
 • HogeParentとPiyo
 ◦ 多対多の関係となるためパ フォーマンスが出にくい
 

  20. © ASOVIEW Inc. 26 外部キーを利用した正規化に拘りすぎると Spannerのパフォーマンスは損なわれやすい (対策編)
 
 開発1年プロダクト運用1年で見えたリアルな課題と失敗
 •

    外部キーであればクエリヒントで @{JOIN_METHOD=APPLY_JOIN}を忘 れない
 • 双方にインターリーブした中間テーブル を作成する
 ◦ 図参照
 • 非正規化する
 こちらの公式ドキュメントも参考に 
 https://cloud.google.com/blog/ja/products/databases/resolve-and-optim ize-many-to-many-relationships-in-spanner

  21. © ASOVIEW Inc. 27 FlywayによるDDLバッチ適用の際の工夫 
 開発1年プロダクト運用1年で見えたリアルな課題と失敗
 • 弊社ではデータマイグレーションツールとして Flywayを採用している


    • Spannerの開発環境にFlywayで初期構築用の大量のDDLを適用したところある時点か らDDLの実行が進まなくなる事象が発生 
 • 原因: SpannerがDDL実行をスロットリングするため
 • DDL実行をバッチ実行にするため、SpannerがサポートしているSTART BATCH DDLと RUN BATCHステートメントを付与
 START BATCH DDL; CREATE TABLE ... CREATE INDEX ... ...(略) RUN BATCH; • しかし、これが上手くいかない。 

  22. © ASOVIEW Inc. 28 開発1年プロダクト運用1年で見えたリアルな課題と失敗
 FlywayによるDDLバッチ適用の際の工夫 
 
 原因: flyway(の少なくともcommunity

    edition版)はこちらを上手く扱えない 
 解決: flyway-coreのMigrationExecutorを自前で実装し直し、 START BATCH DDLを利用 できるようにする 
 
 詳しくはこちらの記事で
 https://tech.asoview.co.jp/entry/2023/12/15/090000

  23. © ASOVIEW Inc. 29 各種制限によるエラーやケア 
 開発1年プロダクト運用1年で見えたリアルな課題と失敗
 • Cloud Spannerには1回トランザクションで扱える登録・更新・削除のデータ量に限りが

    ある
 ◦ トランザクション実行時に扱うデータ量を考慮しないと本番で実行時エラーも起こりう る(実際起きた)
 ◦ 論理データセット次第では1回のトランザクションでは登録・更新・削除が終わらない ためトランザクションループが必要 
 • JOIN数には20という制限がある
 ◦ 複雑なSELECTをしようとすると稀に超えてしまうことがある 
 ◦ そうなるようなデータベース構造にしないことを意識 
 ◦ リードモデルテーブルの導入を検討 

  24. © ASOVIEW Inc. 30 オプティマイザの想定外動作とクエリヒント 
 開発1年プロダクト運用1年で見えたリアルな課題と失敗
 • Spannerのオプティマイザは大量データを扱う場合やインデックスが複数存在する場 合などに最適な実行計画を組めなくなることがある

    
 • 他のデータベースではクエリヒントを付けることは避けられる傾向もあるが、 Spanner の場合は積極的に付けてあげたほうが想定の挙動を示す場合が多い (体感)
 ◦ JOIN_METHOD(結合方式の強制)
 ◦ FORCE_INDEX(利用するインデックスの強制)

  25. © ASOVIEW Inc. 31 今思えばこうすればと思ったこと 
 開発1年プロダクト運用1年で見えたリアルな課題と失敗
 • 目線合わせ・インプット会の重要性 


    ◦ 勉強会・共有会の時間を惜しまない 
 ◦ 長期的には回収できる
 • ベスト・バッドプラクティスを自分で検証してみる 
 ◦ 記事で呼んでも踏み抜いてみるまで実感できないもの 
 ◦ ローカルではだめ(エミュレーターは実際のデータ分散時と挙動が異なる ため)
 ◦ 早く検証環境を作り、論理データを仮でも良いのでたくさん投入できる ようにすること

  26. © ASOVIEW Inc. 32 目次
 • 会社紹介
 • Cloud Spannerを導入したプロダクト


    • Cloud Spannerの導入により目指した状態と現状 
 • 開発1年プロダクト運用1年で見えたリアルな課題と失敗 
 • 今後の展望

  27. © ASOVIEW Inc. 33 今後の展望
 • グロースに伴うトランザクション増加への対応 
 ◦ オートスケールの本格導入検討

    
 • データ量増加によるパフォーマンス対応におけるナレッジ蓄積 
 ◦ 顕在化していない危ないクエリやデータ構造が眠っているかも ..
 • 一部負債化している正規化し過ぎたテーブル構造の見直し