システム負荷対策
システム負荷対策は多様な方法で行うことが出来るため、まずは一般的な内容を記載する。 ここにはない独自の対応をしている場合は、是非ご指摘頂きたい。
前提
- 前提としてアプリケーション側でパフォーマンスの悪いクエリや処理を確認して最適化、DBにインデックスをはる等のパフォーマンスチューニング、適切なコーディングが出来ていること。
- システム負荷対策において、単にサーバー台数を増やすということは、チューニング出来ていない不完全なインフラを拡張することになり不利益が大きいので、アプリケーションが最適化されていることが前提となる。
- 個人的な思いになるが、コンピューティングリソースは大切に、水筒にたまった水を無駄にしないように大切に使っていきたい。
計測=何がボトルネックになっているのか
- システム負荷対策として、まず何がボトルネックになっているのか計測する必要がある。
- 計測は、負荷問題が起きてからではなく、日常的に計測していく必要がある。
- 日常的な計測は、CPU負荷であったり、メモリの使用量、1受注当たりの速度等指標のロギングと、処理速度の閾値を超えた場合にアラート通知が求められる。
- 一般的にシステムは構築後、劣化していくので、機能を追加するだけではなく、パフォーマンスを維持する事も重要な運用業務である。
- 一般的なボトルネックは、WEBサーバー、DBサーバー、ネットワーク、外部連携部分(例えば決済代行との連携)のケースがある。
- またボトルネックは、ECサイトの状況(PV増、トランザクション増、データ量増)によって問題個所が移動していくので、終わりなき探求である。
- 本稿では計測部分は別途記載する(TODO)のでECシステムで基本的に採用されているシステム負荷対策を紹介する。
- システム負荷対策には、システムアーキテクチャで対応する事と、プログラミングで対応する事があり、それぞれ説明する。
システムアーキテクチャで対応する場合の基本指針
- システムは事業の成長過程に応じて、増強していくことが出来る必要がある。(最初から必要以上の構成は不要である。)
- システム負荷対策にはスケールアップとスケールアウトの方式がある。
- スケールアップとは当該システムのCPUやメモリなどのスペックを上げることで、スケールアウトは水平にサーバーを足していくこと。
- 一般的にWEBサーバーは水平にスケールアウトがしやすく、データベースなどはスケールアップして対応するケースが多い。※ソーシャルゲームの場合はシャーディングという形をとって、データベースサーバーを水平に足していくやり方がある。
- 上記が一般的なシステム負荷対処であるが、ECシステム負荷対策の基本方針として、オリジンサーバー(購入時の受注等ECのコア業務が行われるサーバー)への負荷を減らすことが重要。
- オリジンサーバーへの負荷を減らすために、キャッシュの多用やサービス分割を行っていく。
- キャッシュはシステム上の複数の層で行うことが出来る。(後述)
- サービス分割とは、検索やレコメンドのサービスを別に切り出したり、通販基幹システムをECフロントとは別にしたりすることである。
- 他にも使用するプロトコルなどでシステム負荷は変わるので、対応する必要がある。
キャッシュ
- CDN(Contents Delivery Network)、WEBサーバーでのキャッシュ、DBサーバーでのキャッシュ、クライアントでのキャッシュなどキャッシュ可能な場所は多岐にわたる。
CDN(Contents Delivery Network)
- リクエストに対するレスポンスを単一のサーバーから配信すると当然負荷が高まる。
- CDNとはContents Delivery Network で大規模な配信サーバー群、外部のサーバーからコンテンツ配信を行うため、オリジンサーバーへの負荷を減らすことが出来る。
- 具体的には商品の画像を中心としたメディアをCDNから配信することが出来る。
- HTML自体もCDNにキャッシュすることが出来る仕様にすれば、よりオリジンサーバーへの負荷を減らすことが出来る。
- キャッシュ効率を上げる設定の考慮。(URLに付加する検索クエリパラメータの調整)
- Google bot やその他botのクロールによる大量アクセスがあっても問題がなくなる。
- CDNはCloudfrare、Fastly、Cloudfront、Akamai、KeyCDN、Stackpath, Verizonなど複数社が提供している。
- 付加機能としてWAF(Web Application Firewall)やその他有用なネットワーク機能を提供するCDNサービスがあるので、価格など含めて検討する。
- キャッシュするメディアの容量によっては高額になるので、商品画像などの軽量化や最適化をきちんと行ったうえで利用する。
- N時スタートのセールでちょうどキャッシュをパージするなど、そういった
WEBサーバー上でのキャッシュ(TODO)
- WEBサーバー上で特定の実行結果をメモリにキャッシュする。
DBでのキャッシュ(TODO)
- 特定の情報をDB上にキャッシュする。
クライアントでのキャッシュ(TODO)
- サーバーからHTTPステータスコードの304レスポンスを受け取ると、ブラウザはローカルのキャッシュを利用し、サーバーへの通信が削減される。
- HTML5のServiceWorkerは、ブラウザのメインスレッドとは別に動くワーカーで、コンテンツキャッシュや同期処理などを行う。ブラウザのストレージ内にデータをキャッシュすることが出来、高速化をはかることができる。
サービス分割で対応すること
検索
- 商品情報を検索するのは負荷が非常に高い。商品点数が増えるほどに高くなる。
- よって、検索自体を別サーバーや別サービス(以降検索サービスと呼びます)で行い、EC機能(購入のトランザクション)とは別にする。
- よくある例としては、商品情報を特定のタイミング(数時間単位か、数分単位)か、検索サービス(ASP)に全件送るケースが多い。
- 商品の全件取得は、件数やデータ構造によっては負荷が高いので、注意する。
- 検索サービスとECを切り離すと、商品情報や在庫情報の連携(商品追加や価格をはじめとした商品情報の変更、在庫の変更)にタイムラグが生まれる。タイムラグを考慮した仕様、画面仕様にすること。
ECのフロントエンドも閲覧系と購入フロー(カート)のサーバーを分ける
- ECのフロントエンドも、トランザクション(購入や会員登録)が発生するものと、閲覧が中心でトランザクションがないもの(TOP、カテゴリTOP、商品詳細)にわけることができる。
ECのフロントエンドとEC基幹システムを別にする
- 管理側で受注情報や商品情報の大量ダウンロードや更新を行うと、フロントサイトのパフォーマンス自体に影響を及ぼすことがある。
- ECのフロントエンドとEC基幹システムを別にする(データベースを別にする)と、バックエンドの業務がフロントエンドに負荷を与えるようなことがなくなる。
メール送信サービスを利用する
- メール送信については、メルマガを中心にシステム負荷となるケースが多い。
- SendGridなど外部サービスを積極的に利用して良い分野と考える。
その他(利用するプロトコルなど)で対応
HTTP/2に対応する
- HTTP/2に対応すると、サイトの高速化を図ることが出来る。
- CDNを採用してHTTP/2に対応したい。
- 普及が進む「HTTP/2」の仕組みとメリットとは
gzip圧縮での配信
- gzip圧縮してコンテンツを配信する
プログラミングで対応する事
非同期
- 外部API(決済、検索等)を呼び出した際に同期処理だと先方の速度によってはこちらの処理が待ち状態となり、サーバー負荷が不要に上がることがある。
- 非同期にすることによって、待ち状態や待ち行列を減らすことが出来る。
- 例としてAmazonの決済は、注文処理とは別になっており、非同期に行われる。決済代行業者などが提供するAPIが同時接続数の制限があることからこのような非同期を選択したと思われる。
- その他の例だと、外部の検索やレコメンドサービスを利用した際に、そちらのサーバーからの戻り時間を待ってHTMLをレンダリングするとレスポンスが悪くなり、サーバーに待ち行列が発生するため、JavaScriptを使って、非同期に取得してHTMLレンダリングするという手法がある。
非同期(クライアントサイド)
- 商品一覧における画像の遅延ロード。商品一覧に一度に商品数を表示しすぎると当然サーバーに多量のリクエストが飛ぶ。これは一覧においてページスクロールで読み込まれる直前に画像を読み込む「遅延ロード」と言われる技術で対応する事が出来る。
- Googleの検索ボットに対して無効ではという議論もあったが現在は対処済みというのが一般認識になっている。
- Search Consoleで動作を確認すると良い。
データの大量出力
- 全件出力が与えるシステム負荷は非常に大きい。外部と連携する場合は、可能な限り差分を検討したい。
知識の仕入れ方
- アーキテクチャで対応することは既にソフトウェアデザインパターンとして、公開されている。
- Microsoftが提供するAzure アーキテクチャ センターには、利用しているクラウドを問わないノウハウが体系化されているので、是非一読されたい。
- 特にパフォーマンスとスケーラビリティのパターンは、ECサイトのアーキテクチャにとって参考になる知見が多い。
体制
- 計測(運用)と対策・チューニング(開発)のチーム連携が密な方がよい。同一チームが理想である。
終わりに
- システム負荷対策は比較的日進月歩領域なので、注意してトレンドを追いたい。