自己紹介とアジェンダ

信原有志氏(以下、信原):「超PayPay祭による高負荷にショッピングはどのように立ち向かったか」。ヤフー株式会社の信原、小中、大岩で発表します。よろしくお願いします。

まずは自己紹介です。ここは軽く流しますが、信原、小中はYahoo!ショッピングのエンジニアで、大岩はYahoo! JAPANのクラウドエンジニアです。

本日のアジェンダがこちらです。最初に超PayPay祭の概要を説明して、それに向けた負荷対策と発生した障害、そして改善のための負荷対策という流れで進めていきます。

超PayPay祭について

まず始めに超PayPay祭について説明したいと思います。超PayPay祭とは、PayPayが実施したキャンペーンで、対象期間中にPayPayで決済を行うと、PayPayボーナスポイントと呼ばれる残高付与が通常よりも多く付与される、お得なキャンペーンのことです。

Yahoo!ショッピングでは1年に1度大規模なセールを行っていますが、この年は超PayPay祭に合わせて最大44パーセントのポイント還元策を企画し、告知などにも力を入れた過去最大級の大規模セールとなっていました。特にセール最終日はグランドフィナーレと呼ばれ、ポイント還元率が年間をとおして最大となる、1年で最もお得な日となっていました。

こうした還元率の高さから、広告・宣伝費にも多くのコストを割いており、ユーザーはもちろん、経営層からの期待値も非常に高くなっていました。そのため、セール期間、特にグランドフィナーレらのサービスダウンは絶対に許容できない状態となっていました。集客の期待値は通常のセールの数倍が見込まれ、その負荷を捌くために負荷専門の対策チームが組まれ、そこを中心としてサービス全体の膨大な人的リソースを投入し、負荷対策を進めていました。

入念な負荷対策を行うも障害発生

では実際に、どのような負荷対策を行ったかです。前段として、ヤフーの開発組織体制について説明します。ヤフーでは、サービス開発を行うサービス組織と、その基盤を開発・運営をするプラットフォーム組織が存在します。

組織とその責務は明確で、今回のセール対策ではサービス側は自身のシステムにかかる負荷と、それを処理するだけのリソースの見積もり、過負荷になった際にシステムダウンしないような機能の実装。プラットオーム側は、サービス側が要求した各種リソースの確保と、プラットフォームが掲げているSLOの遵守がそれぞれのスキームとなります。

実際に対策した内容の一部を紹介すると、深夜帯の負荷試験や、ユーザーが特定の時間帯に集中しないためのイベント、クーポンの発行、スケジュールの調整。あと、サービスダウンした時のオペレーションの整理や、注文の非同期化のような過負荷対策の機能の実装、そしてキャパシティプランニングとスケールアウトが実際に行った対策の一例となります。

こうした障害対策を実施して、少なくとも内部的には万全な対策で挑んだつもりでしたが、残念ながら障害は発生してしまいました。

発生した障害としては、カートページにアクセスできず、商品購入ができないというものです。最終日の最大還元率を狙ったユーザーが、日付が変わるタイミングで予測の数倍殺到し、カートシステムがクラッシュしたのが原因でした。

この障害によって、当然多くのユーザーにご迷惑をかけてしまう事態となりました。次の大規模セールまでにこの問題を改修するため、急いで障害の原因を捜査し、過負荷時に問題を起こす要因として、コアロジックに依存する複数の問題を確認しました。

それらの改修は注文系ドメインであることから、改修にかなりのコストが必要でした。しかし幸いにも、次の大規模セールは翌年の11月に開始されるため、猶予は1年あり、すべてを対応するには十分現実的な数字だったと言えます。

結果として大きな障害を起こしたわけですが、課題が明確になっており、今回の反省を踏まえて次のセールに向けて対策チームは動き出していました。

障害が起こってしまった原因

なぜ障害が起こってしまったかというお話です。負荷対策チームは、当然今回のセールに向けてさまざまな対策を実施しており、想定される負荷を捌く点においては、十分な対策ができていたと考えています。

ここでの最も大きな落とし穴は、これらの対策はすべて予測負荷が前提になっており、これが大きく上振れてしまった場合にどうなってしまうのかを誰も意識していませんでした。

そもそも、セールなどの特定のイベントによってアクセスがスパイクするケースは、予測が非常に困難なものです。

ショッピングではこの見積もり方法として、前年度のセールの負荷と予算をベースに、今年度の予算との比率を出して予測負荷を計算していました。これはつまり予算が2倍になれば、負荷も2倍になるというものです。要は予算ベースで負荷を決めていたことになります。

この計算式は数年間にわたる大規模セールで運用されており、大きく乖離したことがない実績から、予測が大きく外れることはないだろうと一種の盲信状態に陥っていたのが、今回の障害を引き起こした原因となります。

つまり本来我々がすべきだったのは、予測された負荷を耐えるのではなく、予測を超えてもサービスを継続できるようにすることでした。

3ヶ月で実現可能な対応策を模索することに

こうした反省を踏まえた上で、来年度のセールに向けて動き出していたわけですが、ここで、ヤフーとLINEが統合したことを記念する、3月の超PayPay祭が開催されることが発表されます。

当然、前回の障害へのストレス対策は、次のセール、つまり3月までに対応する必要があるわけですが、この時点で残りは3ヶ月。当初予定していた対応は不可能なので、3ヶ月で実現可能な有効打を急遽打つ必要に迫られました。では、実際に残り3ヶ月でどのような対策を打ったのかをサービス側、プラットフォーム側、個別に紹介していきたいと思います。

サービス側で実施した対策

小中史人氏(以下、小中):次に、サービス側で実施した負荷対策についてお話します。その前に、まずはYahoo!ショッピングの開発・運用体制についてお話しします。

Yahoo!ショッピングでは、1チームあたり5人から7人、約30チームでYahoo!ショッピングおよびPayPayモールを提供しています。チームあたりの担当システム数は2つから4つで、各システムに対して仕様検討からテストまでのビジネス開発。リリース作業やアラート対応などの運用作業。そしてリソース見積もりや負荷試験といった、プランニングを行っています。今回はその中でも負荷試験についてお話しします。

Yahoo!ショッピングでは、ユーザーにサービス提供する上で必須のシステムが存在します。サービス側の負荷対策として、本番環境でそれらに対するシステム単体での負荷試験と、ユーザーの行動を模した全体負荷試験の2つを行いました。

まずは単体負荷試験についてお話しします。あるコンポーネントの負荷試験を考える際、どこにリクエストをかけ、依存しているシステムにどの程度の負荷が流れるかを考えますが、実際には依存先のシステムも、他のサービス内のシステムやプラットフォーム組織が提供するシステムなど、さらに別のシステムに依存しています。

システムごとにチームが分かれているため、試験対象のシステム担当から、各システムに対して、どの程度の負荷がかかるかを見積もるのは困難です。

また、依存先のシステムには他のクライアントも存在するため、理想的にはそれらからのトライも考慮した上で、試験時にどのくらいの負荷がかかるかを把握する必要があります。

しかし時間的な余裕がなかったため、必須のシステムに対して依存先まで含めた全体のシステム構成像を作成し、それを元に依存先のシステムに対して負荷を試算しました。試算の際は、主要なシステムからの負荷だけを考慮し、プラットフォーム組織が提供するシステムに対しても想定負荷を試算しました。その結果は、サービス、プラットフォーム負荷対策担当の複眼でチェックしました。

また、負荷試験時にはプラットフォーム組織も待機し、リアルタイムに監視を行いました。試験によっていくつかのシステムで不具合およびキャパシティ不足が確認されたため、増強と実装修正を行って再試験の流れを何度も繰り返しました。

続いて、全体負荷試験についてお話しします。こちらの目的は、単体負荷試験でシステム単体では問題ないことを確認した上で、Yahoo!ショッピング、PayPayモールとして問題なく機能を提供できるかを確認する目的で実施しています。

全体負荷試験ではユーザーの行動を模したシナリオを用意しました。トップページから検索ページや商品ページ、カートページに遷移するユーザーや、直接商品ページやカートページにアクセスするユーザーからのリクエストというかたちで、各システムに対して想定負荷をかけました。

負荷試験時にはプラットフォーム組織も待機し、リアルタイムに監視を行いました。こちらでもいくつかのシステムで不具合およびキャパシティ不足が確認されたため、増強と実装修正を行い、再試験を何度も繰り返しました。

特にこの試験では、複数のシステムが利用しているようなサービス基盤に関わるシステムに対し、単体負荷試験以上の負荷がかかり、その結果ダウンするケースを洗い出せました。何度も何度も試験し、想定負荷がかかってもダウンしないことを担保した上でセール当日に臨みました。

続いてRateLimitについてお話します。単体負荷試験や全体負荷試験で想定負荷を捌けることは確認できたものの、見積もりを超えてしまった場合にはダウンするリスクがあります。特に実機を利用している一部システムは、即時での増強が困難です。こういった条件の中でシステムダウンを防ぎつつ、最低限購入可能な状態を提供するため、RateLimitを導入しました。

増強が困難なシステムは、注文システムです。購入するためには必ずカートページを経由する必要があるため、カートページがダウンしない程度で、RateLimitを導入しました。その中で注文手続きに進める人をさらに絞り、安全のため注文システム手前でもう1度RateLimitを仕込みました。

RateLimitに引っかかった際は、カートページに再アクセスするように促すページに遷移させています。これにより、ダウンせずにユーザーにカート表示、注文機能を提供することが可能になりました。

プラットフォーム側で実施した対策

大岩朗氏(以下、大岩):続いて大岩から、プラットフォーム側、特にクラウド領域における大規模セールに向けた具体策を紹介します。

本題に入る前に、簡単にヤフーのプライベートクラウドの概要です。PaaS、IaaS、CaaSといったコンブリッティング基盤があります。その上でYahoo!天気やYahoo!ニュースなどはもちろん、超PayPay祭といった大規模セールに関わるショッピングなどの多くのアプリケーションが稼働しています。

このようなプライベートクラウドでの大規模セールのようなイベントにおける一般的な注意点・課題としまして、CPU、メモリ、ネットワーク帯域などのリソースの把握と確保が必要なことはもちろんです。また、特定のサービスだけに注力せず、常に安定したプラットフォーム提供が必要だったり、大規模サービスになるほど関連コンポーネントが多くなってしまい、超高負荷時のプラットフォームへの影響度合いの把握が困難になる課題もあります。

前のスライドでは一般的な話をしましたが、3月の超PayPay祭の負荷対策についても、いくつか課題が出てきました。主な課題としては、超PayPay祭が影響するプラットフォームの把握不足で緊急時の障害調査が難航したり、セール本番当日にプラットフォーム上で緊急スケールアウトが必要となる利用者が一定数いたりしました。

また、突発セールであったため、プラットフォームのキャパシティプランニングに入っていないリソース要求があったりしました。このような課題が出てきましたが、1つずつ対策を取ることでセール本番に備えました。

まず、プラットフォーム側の把握不足や、本番当日に緊急スケールアウトが必要になった課題の対策についてです。サービス側の具体策の際にも説明がありましたが、主要なシステムの利用、プラットフォームの詳細を含めた構成作成や、本番同等かつそれ以上の負荷の負荷試験を実施してもらい、ボトルネックや問題点を把握してもらうことで、サービス側と連携しつつ、事前に万全な状態にしておくように対策をしました。

また、追加で大量リソースが必要になった課題については、余剰リソースのかき集めなどで500台近くの爆速増強により、負荷対策で理想となるリソースを提供できました。

このようにクラウド側でも負荷体策をしましたが、ここで番外編です。負荷対策中はスライドのとおり、運用者なら必ず恐怖する怖い話がたくさん出てきました。例えば、負荷試験中にCPUが回りすぎて一部のラックの電力が上限付近まで到達しかけてラック丸々落ちかける事件や、PaaS環境の一部でCPUが超高負荷になり、ヒヤヒヤしたりしました。

本編に戻り、サービス、プラットフォーム側でさまざまな負荷対策に奮闘した結果ですが、最も負荷がくる最終日、グランドフィナーレでは、大きな障害もなく無事乗り切ることができました。また、最終日は前回比1.8倍の取扱高と、過去最高記録も達成でき、大成功となりました。

高負荷に立ち向かうために各担当で大切なこと

まとめです。11月に失敗があり、失敗に対しての原因分析や対策を進めることで、3月の超PayPay祭に挑みました。

対策の効果として、万全な状態かつ予想以上の負荷も考慮済みとなった結果、大成功を導き、リベンジ成功となりました。

最後に高負荷に立ち向かうためにということで、サービス、プラットフォーム側それぞれで大切なことをまとめます。

まずサービス運用者ですが、サービス運用者は必要なキャパシティ、リソースを適切に見積もることが大事であり、サービス運用者自身はもちろん、プラットフォーム担当者にもシステムを知ってもらうことが大切です。

また、システムでは、どのような負荷がくるか想定外のことも起きると思うので、そのような事態にも考慮したシステム設計や対策は必要かと思います。

次にプラットフォーム運用者は、サービス側からどのような要求が急にきてもいいように、突発的なイベントに常に備えておくことが大事だと、今回のセールの負荷対策をとおしてあらためて感じました。

さらに、サービス側を自ら知ろうとしてプラットフォーム側からコンサルして相互理解を促していけると、よりよい関係が築いていけると思っています。あとは、やはり適切なプラットフォーム利用の啓蒙もかなり大事かと思います。

このようにサービス、プラットフォーム、それぞれが粗にならずより密になっていけると、今回のような大きな成果も生みやすいのかなと考えています。

以上です。ご清聴、ありがとうございました。