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

二重開発負債をOne Application化で解くペアーズのグローバルRe:Architect戦略

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.

二重開発負債をOne Application化で解くペアーズのグローバルRe:Architect戦略

Avatar for Watanabe Takeshi(Buzz)

Watanabe Takeshi(Buzz)

May 13, 2026

More Decks by Watanabe Takeshi(Buzz)

Other Decks in Technology

Transcript

  1. Buzz | Takeshi Watanabe @buzz_tkc COMPANY 株式会社エウレカ ROLE Senior Backend

    Engineer HOBBIES トライアスロン, スノボ, サッカー INTRODUCTION About Me 2
  2. 3

  3. Agenda Agenda 1 単⼀国の前提がグローバルでは崩れる 2 広範囲に現れる差分の解消 3 ペアーズにおけるグローバル展開 〜初期‧並⾛期〜 4

    ペアーズにおけるグローバル展開 〜分離期〜 5 ペアーズにおけるグローバル展開 〜Re:Architect編〜 まとめ 6 4
  4. Chapter 1 アプリをグローバル展開することで暗黙の前提が崩れる ⽇本単⼀展開 暗黙に固定されている前提 ⾔語 ⽇本語 通貨 JPY タイムゾーン

    JST サーバー 国内を前提に配置 グローバル展開 暗黙の前提の再考が必要 ⾔語 展開国の⾔語を考慮する? 英語だけ追加でサポートする? 通貨 展開国ごとに異なる タイムゾーン 展開国の現地時間の考慮 サーバー レイテンシーをどう解消するか 前提を⾒直した再設計が必要になる 8
  5. Chapter 2 広範囲に現れる差分 1 ⾔語‧⽂⾔ 翻訳、複数形、RTL、⽇付表記 2 通貨‧税 JPY /

    TWD、消費税 4 レイテンシ‧配信距離 画像 / 静的資産、API レイテンシ、帯域 3 時刻‧タイムゾーン JST / CST / KST、⽇境界 6 個⼈データの置き場所 保存先、保持期限、削除義務 5 機能の ON / OFF 国ごとに出す機能∕隠す機能 7 画像‧コンテンツ デザイン、禁⽌表現 8 顧客対応 多⾔語での問い合わせの対応 etc… 10
  6. Chapter 2 拡張性を考慮した差分の解消法 etc… 11 種類 解消の仕組み 具体例 ① ⾔語‧⽂⾔

    Crowdin コードに⽇本語を埋めない ② 機能の ON / OFF Feature Toggle 国ごとに機能を出し分ける ③ 個⼈データの置き場所 Cluster routing (Infra) 端末の地域でデータ置き場を振り分け ④ 通貨‧税‧決済 Billing / Pricing util Apple, GoogleなどのProviderで吸収 ⑤ レイテンシ‧配信距離 CDN / Edge 配信経路は Infra で吸収する ⑥ 時刻‧タイムゾーン TZ util (UTC 基準) 内部は UTC、表⽰だけ現地 ⑦ 画像‧コンテンツ CMS / Asset variant 画像はコードでなく CMS で差し替え ⑧ 顧客対応 Automation AIChatbotや問い合わせサービスデスク化
  7. Chapter 3 ペアーズにおけるグローバル展開 ⽇本に専念 グローバル展開初期 ⽇本‧台湾 (2013年頃) 14 ⽇本版と海外版(TW /

    KR)アプリとして開発を進める 海外版 ペアーズ ⽇本版 ペアーズ ⽇本版リリース (2012年頃) グローバル展開並⾛期 ⽇本‧台湾‧韓国 (2017年頃) ⽇本と台湾に注⼒ ⽇本と台湾と韓国に注⼒
  8. Chapter 3 ペアーズにおけるグローバル展開 ⽇本に専念 グローバル展開初期 ⽇本‧台湾 (2013年頃) 15 ⽇本版と海外版(TW /

    KR)アプリとして開発を進める 海外版 ペアーズ ⽇本版 ペアーズ ⽇本版リリース (2012年頃) グローバル展開並⾛期 ⽇本‧台湾‧韓国 (2017年頃) ⽇本と台湾に注⼒ ⽇本と台湾と韓国に注⼒
  9. Chapter 3 特にアプリケーション層の差分が⼤きかった     ⚪ インフラ 層 問題はありつつも、ある程度共通の⼟台があった Cache Redis バッチ

    / 集計 Batch / ETL 監視 / アラート Metrics / Alert × アプリケーション層 特にフロントエンドの別リポジトリ開発とサーバーサイドのAPI差分が大きかった Frontend (Web / iOS / Android) 別リポジトリ — JP と TW / KR で repository が独⽴ 別バイナリ‧別アプリ申請 — ストア審査も別 リリースも完全独⽴ — デプロイ系統‧バージョンすべて別 Backend (サーバー) TW / KR は SSR 中⼼ — テンプレート / セッション / HTML ⽣成 JP は REST API 中⼼ — JSON / stateless / クライアント主導 AIモデル — JPでのアセットを使い回せない RDB MySQL Server EKS 17
  10. Chapter 3 2019年以降は⽇本市場に注⼒ ⽇本に専念 グローバル展開初期 ⽇本‧台湾 (2013年頃) 19 海外版は最低限の⼯数でオペレーションモードへ 海外版

    ペアーズ ⽇本版 ペアーズ ⽇本版リリース (2012年頃) グローバル展開並⾛期 ⽇本‧台湾‧韓国 (2017年頃) グローバル展開分離期 ⽇本‧台湾‧韓国 (2019年頃) ⽇本と台湾に注⼒ ⽇本と台湾と韓国に注⼒ ⽇本に注⼒し、 海外版はオペレーション モードへ
  11. Chapter 4 並⾏開発を続けるか、One Applicationに統合するか A 案:並⾏開発を続ける(現状維持) JP とTW / KR

    の 2 並列でそれぞれ運⽤し続ける B 案:One Application に統合 アプリをOne Codebaseへ ◦ 短期(JP と TW / KR) 最速。現⾏コードをそのまま回せる × 短期(JP と TW / KR) 移⾏コストが先に発⽣する × 機能追加‧保守 恒常的に 2 倍コスト ◦ 機能追加‧保守‧規制対応 1 実装‧1 リリースで済む × 他地域展開(新規国追加) 国追加のコストが⾼い ◦ 他地域展開(新規国追加) 国追加のコストが下がる 21 将来的なスケーラビリティを考慮し、One Applicationに統合することを決断
  12. Chapter 4 One Application 化を3 つの層に分けて再設計する 共通化層 Frontend / Backend

    • 1 Codebase / 1 Deploy Pipeline • ログ / 監視も共通規約 → 2重開発を解消する 差分吸収層 i18n / Feature Toggle • 多⾔語化:message catalog + fallback • 機能差分:Feature Toggle + country → 海外展開のスケーラビリティを担保 分離層 RDB / Blob • 国別に物理分離(JP / TW / KR) • スキーマ‧命名規約は共通 • マイグレーションも共通パイプ ライン → 運⽤⾯でのメリットを担保 スケールする共通の基盤は作りつつ、差分を吸収する層とあえて分離する層に分けて開発 22
  13. Chapter 4 なぜデータ層を分離したままにしたのか 23 国毎の法規制やData Privacy周りのポリシーの違いから、分離して保存しておく運⽤⾯のメリットも あった。 2 One DB統合は構想にはあったが、ID衝突、巨⼤データのマイグレーション、データ連携しているデー

    タ基盤の修正コストが⾮常に⾼く、ROIを踏まえてスコープアウトした。 1 One Application Projectでは、開発速度を落とさず、⽔平展開の⼯数を限りなく低くする状態を⽬指した ⽬安として2割ぐらいの⼯数で⽔平展開できる状態
  14. Chapter 5 One Application 化を3 つの層に分けて再設計する 共通化層 Frontend / Backend

    • 1 codebase / 1 deploy pipeline • ログ / 監視も共通規約 → 2重開発を解消する 差分吸収層 i18n / Feature Toggle • 多⾔語化:message catalog + fallback • 機能差分:Feature Toggle + country → 海外展開のスケーラビリティを担保 分離層 RDB / Blob • 国別に物理分離(JP / TW / KR) • スキーマ‧命名規約は共通 • マイグレーションも共通パイプ ライン → 運⽤⾯でのメリットを担保 スケールする共通の基盤は作りつつ、差分を吸収する層とあえて分離する層に分けて開発 25
  15. Chapter 5 OneClusterでクライアントの端末起点で地域と⾔語を判定 クライアント (iOS / Android / Web) 表⽰される⾔語

    → 端末の⾔語 展開されるリージョン(機能) → 端末の地域情報 KR ALB TW ALB JP ALB JP Pod TW Pod KR Pod 26
  16. Chapter 5 CI/CD Pipelineは統⼀ JP Pod TW Pod KR Pod

    27 Backend Repo Manifest Repo Argo CD ECR master mergeでGAを起動 1 image push 2 dispatch PR Creator 3 manifest 更新PRを auto-merge 4 Argo Sync 5 Rolling Update 6
  17. Chapter 5 One Application 化を3 つの層に分けて再設計する 共通化層 Frontend / Backend

    • 1 codebase / 1 deploy pipeline • ログ / 監視も共通規約 → 2重開発を解消する 差分吸収層 i18n / Feature Toggle • 多⾔語化:message catalog + fallback • 機能差分:Feature Toggle + country → 海外展開のスケーラビリティを担保 分離層 RDB / Blob • 国別に物理分離(JP / TW / KR) • スキーマ‧命名規約は共通 • マイグレーションも共通パイプ ライン スケールする共通の基盤は作りつつ、差分を吸収する層とあえて分離する層に分けて開発 → 運⽤⾯でのメリットを担保 29
  18. Chapter 5 Crowdin で多⾔語化を実現 30 Crowdin は AI機械翻訳‧Git/Figma 連携を備えたローカライゼーション管理 SaaS。

    100以上のファイル形式に対応し、多⾔語化ワークフローを⾃動化できる。 1 開発者‧翻訳者 がリアルタイム協業でき⽂字列の追加〜翻訳〜リリースを継続的に回せるのが強み。 2 ペアーズでは、 全プラットフォームの⽂⾔リソースを同期し翻訳者と協業する⽤途に活⽤している。 3
  19. Chapter 5 Crowdin で多⾔語化を実現 開発者はkeyを作成し、crowdinに登録 → search.pickup.title ⽂⾔差分をCrowdinに集約 し、コードには key

    だけを残すことでスケーラビリティを担保 1 翻訳者はkeyを元に翻訳を追加 - en:Today's Recommendation - ja:本⽇のおすすめ - zh-TW:今⽇推薦 - ko:오늘의 추천 2 翻訳されたcatalogを取り込む 3 Build時にcatalogをartifactへ 4 31 端末の⾔語に応じて表⽰ 5
  20. Chapter 5 FeatureToggle で国別機能を出し分け Feature JP TW KR FeatureA ON

    — — 国 × feature の判断は Toggleを 1 か所で管理することでメンテナンス性が向上 FeatureB ー ON ON 32 × Before — 全体像が⾒えずらい // ... 各所に散らばる if IsJP() { return true } if IsTW() | IsKR() { return true } ⚪ After — Feature Toggle で宣⾔的に // toggle を定義し, 1fileにまとめておく func IsFeatureAEnabled() { return IsJP() } func IsFeatureBEnabled() { return IsTW() | IsKR() } 「この機能はどこでON/OFFされるか」が関数名で明⽰され1fileにまとめることで検索性も上がり、保守性が上がる。
  21. Chapter 5 Cacheはregion prefixを付与してClusterを統⼀できる形へ Before Key: user:profile:12345 Value: {"id": 12345,

    "name": "Taro", ...} GET user:profile:12345    After Key: jp:user:profile:12345 Value: {"id": 12345, "name": "Taro",...} Key: tw:user:profile:12345 Value: {"id": 12345, "name": "Nacy", …} GET jp:user:profile:12345 33
  22. Chapter 5 One Application 化を3 つの層に分けて再設計する 共通化層 Frontend / Backend

    • 1 codebase / 1 deploy pipeline • ログ / 監視も共通規約 → 2重開発を解消する 差分吸収層 i18n / Feature Toggle • 多⾔語化:message catalog + fallback • 機能差分:Feature Toggle + country → 海外展開のスケーラビリティを担保 分離層 RDB / Blob • 国別に物理分離(JP / TW / KR) • スキーマ‧命名規約は共通 • マイグレーションも共通パイプ ライン → 運⽤⾯でのメリットを担保 スケールする共通の基盤は作りつつ、差分を吸収する層とあえて分離する層に分けて開発 34
  23. Chapter 5 RDBは分離したままに JP Pod TW Pod KR Pod JP

    DB TW DB KR DB マイグレーションのコストと独⽴性の恩恵から統合は⾒送る 35
  24. Chapter 5 分離層をスケーラブルにするためにマイグレーターを導⼊ JP DB TW DB KR DB コードベースを共通化したため、スキーマ差分を無くし全環境で安全に使⽤するためにマイグレーターを導⼊

    36 PR上で クエリレビュー 1 PR Mergeで SQSにEnquete 2 KEDAがSQS をPull 3 ScaledJob を起動 4 DDL → 全リージョンへ DML →指定したリージョンへ 5
  25. Chapter 6 One Application Projectを終えてどう変わったか One Application 化 Frontend /

    Backend • 1 codebase / 1 deploy pipeline 化 • 1実装‧1リリース体制へ   国別差分の吸収 i18n / Feature Toggle • アプリを分けず共通基盤で管理 • 仕組みで差分を吸収し解決 データの分離と共通化 RDB / Migration • DBは分離したまま運⽤メリッ ト維持 • スキーマ‧命名規約等は共通化 し、マイグレーターを導⼊ 差分を仕組みで吸収しつつ共通基盤化と適切な分離を両⽴させ、開発効率とスケーラビリティを最⼤化した 38 → 2重開発を解消する → 海外展開のスケーラビリティを担保 → 分離するメリットを残しつつ、 スケーラブルな仕組みへ