注目の記事

【レポート】楽天の大規模決済システムを支えるAWSアーキテクチャ #AWSSummit

DA事業本部の春田です。

AWS Summit Online絶賛開催中!ということで、本記事では「CUS-65: ペイメントプラットフォームにおける AWS の活用」の内容についてまとめていきます。

セッション情報

  • 楽天株式会社 グローバルテクノロジー統括部 國谷 彩 氏

AWS上でのPayment Platformシステムの歴史についてお伝えします。AWSへ移行してからこれまでの課題と解決方法について説明します。

※セッション動画は以下リンク

アジェンダ

  1. 楽天グループについて
  2. ペイメントプラットフォームについて
  3. ペイメントプラットフォームにおけるアマゾンウェブサービス(AWS)の歴史

楽天グループについて

  • Eコマースのサービス「楽天市場」をはじめ、Fintech事業やエンターテイメント事業まで、さまざまなビジネスを展開
  • 各サービスが楽天共通IDで繋がることで、サービスを跨いだグループシナジーを生み出す、楽天エコシステムを形成
  • 日本だけでなく、アジア、アメリカ、ヨーロッパでもサービスを展開

ペイメントプラットフォームについて

  • ペイメントプラットフォームとは?
    • 楽天の各サービスが利用する決済プラットフォーム
    • ユーザーが楽天サービスを利用して、ネットショッピングの利用代金やサービスの料金を支払う際のバックエンド
    • 決済に必要な複雑な手続きが、サービスプロバイダーとの間で発生
    • 楽天ペイメントプラットフォームが様々な決済方式の代理業務を一括で請け負い、各サービスへの負担を減らしている
    • 主に、「決済ゲートウェイ」と「クレジットカードトークンシステム」で構成される

  • 決済ゲートウェイ
    • 楽天グループ内のサービスと、楽天カードや各種決済プロバイダーをつなぐ、グローバルプラットフォーム
    • 決済方法の違いを吸収し、クライアントサービスが簡単に決済システムが導入できるよう支援

  • トークンシステム
    • 顧客が登録したクレジットカード情報をトークンと呼ばれる文字列に変換
    • それぞれのサービスがカード情報を保持する必要がなくなる
    • 2022年までに、楽天グループ全てのサービスに導入予定

ペイメントプラットフォームにおけるアマゾンウェブサービス(AWS)の歴史

2015年 - 2017年

  • 2015年
    • オンプレからAWSへ移行した背景
      • PCI-DSSの準拠が目的
      • PCI-DSS = 世界的に統一されたクレジットカード情報保護のためのセキュリティ基準
      • もともとオンプレでPCI-DSSに準拠しようとしていたが、すでに稼働している巨大で複雑なシステムの見直しは敷居が高く、リードタイムやコスト面で厳しかった
    • AWSにした理由
      • 当時、PCI-DSSの完全準拠を謳っていたのは、AWSのみだったから
  • 2016年
    • 内部監査により、PCI-DSS merchantを取得
    • AWS移行後トランザクションが増えたため、PCI-DSS Service Provider Level1の取得が必須となる
  • 2017年
    • 外部監査により、PCI-DSS Service Provider Level1を取得
    • 監査員がパブリッククラウドに詳しいかを非常に重要視した

  • 要件
    • PCI-DSSに準拠
  • 課題
    • ネットワークセグメンテーション
    • ネットワーク設定の可視化、敏速な設定変更
      • サーバーが何台あろうとも手元のコードで仕様やセキュリティの状況を把握できる必要がある
    • カードデータへのアクセス保護
      • 業務上必要な範囲内に制限
      • データの暗号化
    • 本番前の確実なテストと再現性

  • 解決策1: AWSへの移行と細かいセグメンテーションの実施
    • サービスに応じてネットワーク境界線(VPCレベル)を分離
    • インスタンス単位でのセキュリティグループ適用
    • IPアドレスとポート番号単位でのアクセス制御
    • WAFの導入
    • KMSの導入

  • 解決策2: CloudFormationの導入
    • サーバーが何台あろうとも手元のコードで仕様やセキュリティの状況を把握できる
    • Gitのバージョン管理により、いつ誰が何を変更したのか履歴が追える
    • → ネットワーク設定の可視化と敏速な設定変更

  • 解決策3: MFAによるアクセス制御とクレジットカード番号の暗号化
    • DUOセキュリティによる二要素認証
      • DBアクセス専用サーバー(db-access)に入るには、MFA入力とマネージャーの承認の2つが必要
    • 全ての通信が、DBとdb-accessの間にプロキシ(db-proxy)を経由し、カード番号はマスキングされる
      • DBにアクセスできるDBAは、db-proxyへログインすることができない
      • db-proxyにログインできるServer Adminは、DBへアクセスすることができない
    • 責任点を分けることで内部に悪意ある人間がいても互いに牽制することができる
    • → カード情報の保護

  • 解決策4: コードベースでのリリース
    • アプリはJenkins、ミドルウェアはChef、インフラはCloudFormationでデプロイ
    • ステージング環境と本番環境で必ず同じ内容をデプロイできる
    • → 再現性の担保

2018年

  • 背景
    • 当初は海外のサービスをメインターゲットとしていたため、AWS環境はN.Virginiaリージョンに集約していた
    • 2018年に、メインサービスの楽天市場がペイメントプラットフォームを導入すること決定
    • ネットワークレイテンシーの改善、親和性を高めるためにTokyoリージョンへ移行することに
  • 要件
    • 楽天市場のサービスレベルへコミット
  • 課題
    • 楽天市場のトラフィックを捌くためのシステム導入
    • 安定したネットワークの提供
    • ネットワークレイテンシーの改善

  • 解決策1: RDSからAuroraへの移行
    • 楽天スーパーセール時のトラフィック1,200 request/secに耐えられるシステムが必要
    • 既存のRDSだとパフォーマンス要件は満たせなかった
    • 並行処理に強くRDSと比較するとDisk I/Oの負荷軽減が見込まれるAuroraへ移行した
    • → DBパフォーマンス条件はクリア

  • 解決策2: スーパーセール時の暖気申請、BLUE-GREENデプロイメント対応
    • 暖気申請
      • ALBは負荷に応じて自動スケール
      • 急激なトラフィックで瞬間的に急増する場合は、ALBのスケーリングが間に合わないので事前に暖気申請でALBをWarm upしておく
    • BLUE-GREENデプロイメント対応
      • スーパーセール中にメモリーリークが発生してもすぐにeb swapできるよう事前に環境準備

  • 解決策3: Direct Connectの導入とTokyoリージョンへの移行
    • As-Is
      • Rakuten DCとAWS N.Virginaリージョンが離れているためパフォーマンスが良くない
      • Rakuten DCとAWS N.Virginaリージョンのネットワークが不安定
      • ネットワークのルートが一つしかなく、 耐障害性に弱い
    • To-Be
      • Rakuten DCとAWSの距離が近くなることでレイテンシーが改善
      • AkamaiからCloudFrontへの切り替えにより、Rakuten DCとAWS Tokyoリージョンのネットワークが安定
      • インターネットとプライベートの両方のルートを用意し耐障害性を強化

  • N.VirginiaリージョンからTokyoリージョンへの移行
    • サービス無停止でのシステム移行が要求
  • サービス無停止の定義
    • アプリケーションにエラーを返さない
    • ユーザーからはレスポンスが少し遅いかな?と感じる程度に止める( > 30sec)
      • 今は10秒を切ることが目標

  • 移行前のニュートラルな状態
  • N.Virginiaリージョンと全く同じ構成を、Tokyoリージョンに予め準備
    • Binary Log ReplicationでDBを同期
  • CloudFrontはN.VirginiaリージョンのALBに直接処理を流している

  • CloudFrontとALBの間にConductorを導入する
    • Conductor = 楽天がElastic Beanstalk上に独自開発したAPIのゲートウェイ
  • Route53の設定で、アプリケーションに設定されているエンドポイントをConductorに付け替える

  • サスペンドモードを適用する
  • リクエストを一時的にコンダクターに溜める

  • N.VirginiaのDBとTokyoのDB間で、完全に同期が取れたらTokyoのDBを有効化

  • Conductorに溜めておいたリクエストをTokyoリージョンへ流す
  • サスペンドモードから、このトラフィックの切り替えまで約15秒
  • ユーザーから見たらスローダウンしているようにしか感じない

  • 作業後、Route53でConductorにエンドポイントを元のアプリケーションに付け替える
  • コンダクターを外す

2020年

  • 背景
    • 新型コロナウィルス感染症対策のため、2020年2月から段階的に原則在宅勤務へ
    • それまで
      • 常に周囲に複数の第三者がいる状態
      • 本番作業の立会い体制も万全
    • コロナ後
      • 周囲に会社関係者はおらず独立した環境
      • 本番作業の立会いはリモートで実施するしかない
      • 社内ルールの規制緩和(モバイルPCの持ち帰りなど)

  • 要件
    • WFHでのリスクを減らす
  • 課題
    • オペレーションミスによるサービス停止
      • 環境間違えによる予期せぬ修正
      • 本番環境を確認するつもりだけだったのにまちがって更新をしてしまう
    • 予期せぬデータ漏洩

  • 解決策1: 参照用ユーザーと管理用ユーザーの分離
    • 参照用ユーザー
      • 自分自身の認証でログインでき、全てのリソースにアクセス可能
      • 変更は一切不可
      • トラブルシューティング時のログの確認などに使用
      • 本番環境の操作の80%はこのユーザーでまかなえる
    • 管理用ユーザー
      • 全ての変更作業が可能
      • マネージャーの二要素認証による許可が必要
      • 本番へのリリース作業やリカバリ作業に使用
    • → 間違った変更を行うリスクが軽減

# 管理用ユーザー 参照用ユーザー
Root userへの切り替え
サービスステータスの確認
サービスの起動/停止
ファイルの参照
ファイルの更新
  • 解決策2: プロキシによる個人情報マスキングとクエリの自動振り分け
    • MariaDB maxscaleで、SQLのタイプを自動的に管理
    • 全ての個人情報をマスキング

2021年

  • 要件
    • Global展開
      • 世界中に点在する楽天グループの各サービスそれぞれに対して、低レイテンシを実現する
      • カード情報が全てのリージョンで同期され、どの海外サービスからでもそのカード情報を利用可能にする
    • BCP
      • リージョン災害時の切り替えを可能にし、災害時のF/Oのダウンタイムを限りなくゼロにする

  • 現状
    • Tokyoリージョンのみ利用
    • 3Tier構成のシステム
      • ユーザーからのリクエストはCloudFrontで受ける
      • Web-Appレイヤには、Elastic Beanstalkを利用
      • RDBにAurora MySQL 5.7を利用
        • AuroraのWriterとReaderは1台ずつで、決済処理のR/WすべてをWriterに向けている
        • ReaderはF/O用途

  • 課題
    • クエリーのレイテンシーの改善
      • エンドユーザーやサービスに地理的に近いロケーションにシステムが必要とされる
    • 日本、ヨーロッパ、アメリカの3リージョンで構成
      • メインターゲットのサービスがこの3拠点に存在している
    • リージョン単位でのデータを分割ができない
      • あるリージョンで登録したクレジットカードは、海外からでも利用できることが要件のため分割できない
    • ゼロダウンタイムを目指す
      • F/Oなどによるサービス影響をユーザーに感じさせないレベルまで極小化したい

  • 解決策1: Route 53 Geo routing
    • 接続元の位置情報に基づいてトラフィックをルーティングする機能
    • アプリケーションレイヤーが地理的位置を意識する必要がない
    • → クライアントから最も近いリージョンに自動的にアクセスさせ、レイテンシーの課題をクリア

  • 解決策2: Amazon Dynamo DB Global Tablesを利用したR/L-W/L構成
    • 3リージョンを利用
    • データベースはDynamoDBを利用し、各リージョンに配置
    • リージョン間のデータプロパゲーションはDynamoDB streamsによって双方向に同期
    • READ LOCALとWRITE LOCAL
      • ReadとWriteの両方のプロセスは各リージョンのローカルで実行