パフォーマンス・チューニングに関するブログの第1回目です

PayPayは、日本でもっともよく知られているQR決済サービスとなりました。2018年10月5日のローンチ後、2018年12月より実施した100億円あげちゃうキャンペーンは、その後のプロダクトの急成長に合わせたシステムのスケール拡張という長い道のりのスタート地点でもありました。

ここ数ヶ月の新規ユーザーの増え方[1]を見るにつけても、PayPayが驚異的な成長を続けていることは間違いありません。スタートアップ企業はまるで竹のように成長するとはこのことではないでしょうか。(竹は24時間で最大約90cmも伸びるそうです)

PayPayの成長速度は?

ユーザー数の伸び

2018年10月に初めてユーザーが増え、キャンペーンや日々メディアで報道されることによるユーザー数の増加もあり、1年後には1500万人を突破しました。2020年5月現在、サービス開始からわずか1年7ヶ月で、2,800万人を超えました。日本の人口比で約22%です(2018年の日本の人口は1億2600万人 [2])。

トランザクションの伸び

ユーザーや加盟店の増加により、1秒あたりのトランザクション数(TPS)も伸びています。

2018年のサービススタート時に比べると、1日あたりのトランザクション数はおよそ50倍に増えています。

こうした成長の中、システムの容量が追い抜かれてしまう前に、成長に合わせたスケール拡張の必要性に直面したのです。

システムのスケール拡張始動

1000TPSに対応する。そこに大きく力を入れ始めたのは、2019年10月5日に行なった1年記念キャンペーンの後でした。当時は、より小さなTPSをサポートし、トランザクション量は前日と比較して大幅に増加しました。

これにより、対応可能な最大TPSを割り出すことと、最低1000TPSには対応できるよう設計を改善することへとバックエンド業務のパラダイムシフトが起こりました。

パフォーマンステストの実施

最初に必要だったのが、ボトルネックの場所の特定と、システムの実際の能力を確認することでした。

そのために、「パフォーマンス」環境(本番環境と全く同様のレプリカ環境)を用いて、最大どの程度のTPSまで対応できるかを検証しました。また、パフォーマンス環境で定期的にテストを実施することで、システムのボトルネックを特定することにもつながりました。

そして、このパフォーマンス環境でテストを実施してから数日後、以下のような課題に直面したのです。

  1. パフォーマンス環境と本番環境の負荷に差分が発生。
  2. パフォーマンス環境では不規則で大容量のテストを実施することから、両者のデータベースのスペックは類似しているものの、データ量が異なる。
  3. アプリケーションのボトルネックを深掘りして調査するには、標準的な日常レベルのオペレーションメトリクスでは不十分。

そこで、本番環境と同様の負荷をかけるため、専任チームがパフォーマンス環境を再構築し、シナリオ設計も行いました。また、システムパフォーマンステスト用にツールも使用しました。この一連の内容に関しては、テックブログで一つのストーリーが出来上がってしまうほどの内容です。トラフさん、別途詳しいお話を楽しみにしていますね!

観測可能性の向上

観測可能性の向上とデータポイントの検証に際し、以下のようなツールを使用しました。

  1. NewRelic
  2. Datadog
  3. VividCortex

Datadogにはカスタムのメトリックスを追加し、New Relicでは分散トレーシング機能を使用することで、マイクロサービスアーキテクチャのボトルネックを検証しました。また、AWS Performance Insights[4] で、データベースのパフォーマンスの視認性を向上させました。

まだPayPay BackEnd入門編を読んだことがない方は、一度ご覧になってみてください。

上記のブログが書かれた時期以降、実はマネージドデータベースをRDSからAuroraに移行しました。ただ、残りのものはほぼ当時と変わっていません。

データベースが最大のボトルネック

PayPayのバックエンドシステムは、マイクロサービスアーキテクチャに基づいており、各コンポーネントが分散化され、水平方向にスケール拡張可能です。と、いう風に実は思っていたのですが 、テストを重ねるにつれ、ボトルネックがPaymentシステムにあるということが判明しました。各決済のデータベースの負荷が原因で、DBのインサートとアップデートに、 大きなレイテンシーが発生していたのです。

データベースオペレーションカウント(トランザクション毎の平均)平均レイテンシー(ms
インサート(挿入)1200
アップデート(更新)4300
セレクト(抽出)110

上記の平均レイテンシーは、アプリケーション側から見たデータベーストランザクション[3]毎のレイテンシーを指す。

テスト開始直後は、Paymentサービスに対してAurora r4.8xlargeを使用していました。ちなみに、Aurora r4.8xlargeというのは32 vCPUs と244GM以上のメモリーを兼ね備えたパワフルなスペックのマシンを指します。

Auroraの調査

パフォーマンスインサイトを用いてAuroraのインスタンスを調査していく中で、負荷に対するパフォーマンスのボトルネックがなぜ発生しているのかが次第に見えてくるようになりました。

Auroraのインスタンスは、長い時間を費やしてMySQLバイナリログのflush(フラッシュ)完了を待っていたのです。 

災害復旧やその他の要件を目的に、PayPayのシステムではバイナリログの複製が必要でした。たとえバイナリログの複製が準同期だとしても、パフォーマンス環境におけるレイテンシーが600TPS程度にまで高くなり不安定な状態になってしまいます。

そこで我々は、より高いストレージパフォーマンスを持つインスタンスタイプを使うためにAuroraの微調整を行いました。これにより、バイナリログのフラッシングにおけるボトルネックが軽減されたのです。しかしながら、それでも達成した最高TPSは400にとどまりました。すなわち、100%向上しただけで、目標を達成するには更に300%の改善が求められている、ということを意味します。

では、この先どのようにしてPayPayが大きくパフォーマンス改善を達成したのかは、このブログの続きであるパート2をお見逃しなく!

パート2では、分散型データベースへの移行を取り上げ、如何にしてスムーズかつ堅牢な移行を達成したか説明します。


用語

  1. TPS:Transaction per Second(一秒あたりのトランザクション)
  2. パフォーマンス環境:本番環境と全く同じレプリカ環境
  3. DB: データベース
  4. vCPUs:Virtual CPU

参考資料

  1. PayPay’s PR for user growth(PayPayのユーザー数増加に関するプレスリリース)
  2. Japan’s population(日本の人口)
  3. AWS Performance Insights(AWSパフォーマンスインサイト)
  4. Database Transaction(データベーストランザクション) 

PayPayのエンジニアは、日本の将来の商取引を変えるにつれ、さまざまなエキサイティングな課題に取り組んでいます。あなたも チームに参加してみませんか? 採用サイトはこちら