システム負荷対策

システム負荷対策 #

システム負荷対策は多様な方法で行うことが出来るため、まずは一般的な内容を記載します。 個人的な思いになるが、コンピューティングリソースは大切に、水筒にたまった水を無駄にしないように大切に使っていきたいものです。

前提 #

  • 前提としてアプリケーション側でパフォーマンスの悪いクエリや処理を確認して最適化、DBにインデックスをはる等のパフォーマンスチューニング、適切なコーディングが出来ていること。

  • システム負荷対策において、単にサーバー台数を増やすということは、チューニング出来ていない不完全なインフラを拡張することになり不利益が大きいので、アプリケーションが最適化されていること。

計測=何がボトルネックになっているのか #

  • まず何がボトルネックになっているのか計測する必要があります。
  • 計測は、負荷問題が起きてからではなく、日常的に計測していく必要があります。
  • 日常的な計測は、CPU負荷であったり、メモリの使用量、1受注当たりの速度等指標のロギングと、処理速度の閾値を超えた場合にアラート通知が備わっている事が求められます。
  • 一般的にシステムは構築後、劣化していくので、機能を追加するだけではなく、パフォーマンスを維持する事も重要な運用業務になります。
  • 一般的なボトルネックは、WEBサーバー、DBサーバー、ネットワーク、外部連携部分(例えば決済代行との連携)のケースがあります。
  • またボトルネックは、ECサイトの状況(PV増、トランザクション増、データ量増)によって問題個所が移動していくので、終わりなき探求となります。
  • 本稿では計測部分は別途記載とし、ECシステムで基本的に採用されているシステム負荷対策を紹介します。
  • システム負荷対策には、システムアーキテクチャで対応する事と、プログラミングで対応する事があり、それぞれ説明します。

システムアーキテクチャで対応する場合の基本指針 #

  • システムは事業の成長過程に応じて、増強していくことが出来る必要があります。(最初から必要以上の構成は不要)
  • システム負荷対策にはスケールアップとスケールアウトの方式があります。

スケールアップとスケールアウト

  • スケールアップとは当該システムのCPUやメモリなどのスペックを上げることで、スケールアウトは水平にサーバーを足していくこと。
  • 一般的にWEBサーバーは水平にスケールアウトがしやすく、データベースなどはスケールアップして対応するケースが多い。※ソーシャルゲームの場合はシャーディングという形をとって、データベースサーバーを水平に足していくやり方があります。
  • 上記が一般的なシステム負荷対処であるが、ECシステム負荷対策の基本方針として、オリジンサーバー(購入時の受注等ECのコア業務が行われるサーバー)への負荷を減らすことが重要です。

オリジンサーバーへの負荷を減らす

  • オリジンサーバーへの負荷を減らすために、キャッシュの多用やサービス分割を行っていきます。
  • キャッシュはシステム上の複数の層で行うことが出来ます。(後述)
  • サービス分割とは、検索やレコメンドのサービスを別に切り出したり、通販基幹システムをECフロントとは別にしたりすることです。
  • 他にも使用するプロトコルなどでシステム負荷は変わるので、対応する必要があります。

キャッシュ #

CDN(Contents Delivery Network)、WEBサーバーでのキャッシュ、DBサーバーでのキャッシュ、クライアントでのキャッシュなどキャッシュ可能な場所は多岐にわたります。

CDN(Contents Delivery Network) #

  • リクエストに対するレスポンスを単一のサーバーから配信すると当然負荷が高まります。
  • CDNとはContents Delivery Network で大規模な配信サーバー群、外部のサーバーからコンテンツ配信を行うため、オリジンサーバーへの負荷を減らすことが出来ます。
  • 具体的には商品の画像を中心としたメディアをCDNから配信することが出来ます。
  • HTML自体もCDNにキャッシュすることが出来る仕様にすれば、よりオリジンサーバーへの負荷を減らすことが出来ます。
  • キャッシュ効率を上げる設定の考慮余地があります。URLに付加する検索クエリパラメータでURLが異なる場合、どの単位でキャッシュするか等。
  • Google bot やその他botのクロールによる大量アクセスがあっても問題がなくなります。
  • CDNはCloudfrare、Fastly、Cloudfront、Akamai、KeyCDN、Stackpath, Verizonなど複数社が提供しており、適切なものを選ぶと良いでしょう。
  • 付加機能としてWAF(Web Application Firewall)やその他有用なネットワーク機能を提供するCDNサービスがあるので、価格など含めて検討します。
  • キャッシュするメディアの容量によっては高額になるので、商品画像などの軽量化や最適化をきちんと行ったうえで利用します。
  • N時スタートのセールでちょうどキャッシュをパージするなど、そういった運用部分も含めて、設計する必要があります。

WEBサーバー上でのキャッシュ #

  • WEBサーバー上で特定の実行結果をメモリにキャッシュします。
  • 各パーツやページ、もしくはAPIの戻り値単位など、色々な粒度で検討する事が可能です。
  • 一般的に、ユーザーにより都度更新がかかるトランザクションデータについては、キャッシュが難しくなるでしょう。

DBでのキャッシュ #

  • 特定の情報をDB上にキャッシュします。
  • 問い合わせのSQLクエリ単位であったり、その結果をキャッシュします。

クライアントでのキャッシュ(TODO) #

  • サーバーからHTTPステータスコードの304レスポンスを受け取ると、ブラウザはローカルのキャッシュを利用し、サーバーへの通信が削減されます。
  • HTML5のServiceWorkerは、ブラウザのメインスレッドとは別に動くワーカーで、コンテンツキャッシュや同期処理などを行う。ブラウザのストレージ内にデータをキャッシュすることが出来、高速化をはかることができます。

サービス分割で対応すること #

検索 #

  • 商品情報を検索するのは負荷が非常に高い。商品点数が増えるほどに高くなります。
  • よって、検索自体を別サーバーや別サービス(以降検索サービスと呼ぶ)で行い、EC機能(購入のトランザクション)とは別にする事が望ましいです。
  • 外部の検索サービス(ASP)を使うケースだと、商品情報を特定のタイミング(数時間単位か、数分単位)で、検索サービス(ASP)に全件送ります。
  • この際の商品全件取得は、件数やデータ構造によっては負荷が高いので、注意する必要があります。
  • 検索サービスとECを切り離すと、商品情報や在庫情報の連携(商品追加や価格をはじめとした商品情報の変更、在庫の変更)にタイムラグが生まれる。タイムラグを考慮した仕様、画面仕様にすることが重要です。

ECのフロントエンドも閲覧系と購入フロー(カート)のサーバーを分ける #

  • ECのフロントエンドも、トランザクション(購入や会員登録)が発生するものと、閲覧が中心でトランザクションがないもの(TOP、カテゴリTOP、商品詳細)にわけることができます。

ECのフロントエンドとEC基幹システムを別にする #

  • 管理側で受注情報や商品情報の大量ダウンロードや更新を行うと、フロントサイトのパフォーマンス自体に影響を及ぼすことがあります。
  • ECのフロントエンドとEC基幹システムを別にする(データベースを別にする)と、バックエンドの業務がフロントエンドに負荷を与えるようなことがなくなります。

メール送信サービスを利用する #

  • メール送信については、メルマガを中心にシステム負荷となるケースが多い。
  • SendGridなど外部サービスを積極的に利用した方が良いです。

その他(利用するプロトコルなど)で対応 #

HTTP/2に対応する #

gzip圧縮での配信 #

  • gzip圧縮してコンテンツを配信する

プログラミングで対応する事 #

非同期 #

  • 外部API(決済、検索等)を呼び出した際に同期処理だと先方の速度によってはこちらの処理が待ち状態となり、サーバー負荷が不要に上がることがあります。
  • 非同期にすることによって、待ち状態や待ち行列を減らすことが出来ます。
  • 例としてAmazonの決済は、注文処理とは別になっており、非同期に行われます。決済代行業者などが提供するAPIが同時接続数の制限があることからこのような非同期を選択したと思われます。
  • その他の例だと、外部の検索やレコメンドサービスを利用した際に、そちらのサーバーからの戻り時間を待ってHTMLをレンダリングするとレスポンスが悪くなり、サーバーに待ち行列が発生するため、JavaScriptを使って、非同期に取得してHTMLレンダリングするという手法がある。

非同期(クライアントサイド) #

  • 商品一覧における画像の遅延ロードも有効な手法です。
  • 商品一覧に一度に商品数を表示しすぎると当然サーバーに多量のリクエストが飛びます。これは一覧においてページスクロールで読み込まれる直前に画像を読み込む「遅延ロード」と言われる技術で対応する事が出来ます。
  • Googleの検索ボットに対して、遅延ロードはSEO上良くないという議論もありましたが現在は対処済みというのが一般認識になっています。
  • Search Consoleで動作を確認すると良いでしょう。

データの大量出力を控える #

  • 全件出力が与えるシステム負荷は非常に大きいです。外部と連携する場合は、可能な限り差分を検討したい。

知識の仕入れ方 #

体制 #

  • 計測(運用)と対策・チューニング(開発)のチーム連携が密な方がよい。同一チームが理想とCommerbleでは考えています。

終わりに #

  • システム負荷対策は比較的日進月歩領域なので、注意してトレンドを追っていきましょう。