Save 37% off PRO during our Black Friday Sale! »

SaaS型ECプラットフォームにおける高負荷対策

 SaaS型ECプラットフォームにおける高負荷対策

Transcript

  1. SaaS型ECプラットフォーム における高負荷対策 株式会社インターファクトリー CTO 水野 謙

  2. 自己紹介  略歴  2006年 日本IBM 東京基礎研究所 入社  マルチコア環境におけるJavaの高速化

     設計書(Word, Excel)の品質検証ツールの作成、適用  2013年 インターファクトリー 入社  2016年 CTO就任  興味  パフォーマンスチューニング
  3. 今日話すこと  下記のような特徴をもつサービスでの 高負荷時の課題と解決策 EC:瞬間的な高負荷がある(セール、SNS拡散) 共用環境:同一サーバーで複数の店舗が稼働 拡張性:店舗により負荷傾向が異なる Java, Tomcat, Linux,

    PostgreSQL
  4. 先に結論  各サーバーの、各リソースについて、 店舗ごとの閾値を設ける  閾値を超えたときに、より「マシな」 エラーの出し方をする

  5. サービスの特徴:拡張性と最新性の両立 ASP ebisumart パッケージ 拡張性 △ 〇 ・標準のJavaクラスを拡張して カスタマイズを記述 ・API経由でカスタマイズ

    〇 最新性 〇 〇 カスタマイズしていても 標準機能は自動でアップデート ×
  6. 共用環境最大の課題:他店舗影響  ある店舗でアクセスが集中したことにより 他の店舗も遅くなってしまう  ある店舗のカスタマイズロジックの パフォーマンスバグにより、 他の店舗も遅くなってしまう パフォーマンスバグがあるのは悪いこと それにより他店舗影響が出るのは最悪なこと

  7. アプリケーションサーバーの リソース制御

  8. 解決策1:スレッド数制限  ある店舗のリクエストを処理している スレッド数が閾値を超えたら、 それ以上は受け付けない 処理が滞留したら確実に 制御が発動する SLA(秒間PV)未満でも 発動する可能性がある

  9. 解決策2:秒間PV制限  ある店舗にSLA以上のアクセスが発生したら それ以上は受け付けない 店舗管理者への説明が しやすい SLA(秒間PV)未満でも サーバーが高負荷になる ことはある ⇒「最悪なこと」を防げない

  10. ここまでの対策で十分? 以下のようなサービスならたぶん十分 ⚫ SNS ⚫ Web検索 以下のようなサービスでは不十分 ⚫ EC ⚫

    東京オリンピックの ボランティア申し込み
  11. None
  12. None
  13. ここまでの対策で十分? 以下のようなサービスならたぶん十分 ⚫ SNS ⚫ Web検索 以下のようなサービスでは不十分 ⚫ EC ⚫

    東京オリンピックの ボランティア申し込み リクエスト単位で ほぼ目的達成 複数のリクエスト を経て目的達成
  14. ECシステムの難しさ  セッションレスなプロトコル ユーザーの離脱を正確に判定できない SLAは秒間PVで定義  セッションフルなアプリケーション 複数の通信を経て目的達成 完了直前のエラーはユーザー体験として最悪

  15. ユーザー体験として「マシな」 アクセス制御  新規ユーザーは混雑時に一定の確率でエラー  回遊中ユーザーはエラーにはなりにくい  「回遊中ユーザー」の定義は?  一回でもアクセスしたら

     カートに商品を投入したら  注文情報入力画面を表示したら  離脱の判定方法は?  一定期間アクセスがなかったら  ブラウザのタブを閉じたら
  16. ユーザー体験として「マシな」 アクセス制御  新規ユーザーは混雑時に一定の確率でエラー  回遊中ユーザーはエラーにはなりにくい  「回遊中ユーザー」の定義は?  一回でもアクセスしたら

     カートに商品を投入したら  注文情報入力画面を表示したら  離脱の判定方法は?  一定期間アクセスがなかったら  ブラウザのタブを閉じたら
  17. 具体的な制御の方法  新規ユーザーだった場合  回遊中ユーザー数が閾値以上ならエラー  そうでなければ、回遊中ユーザー一覧として登録  回遊中ユーザーだった場合 

    最終アクセス日時から一定時間以上たっていたら新規ユーザーとして処理  そうでなければ、最終アクセス日時を更新 制限発動時のユーザー体験が 比較的良い PVやサーバー負荷が低くても 制限が発動する場合がある 適切な閾値の設定が難しい
  18. 代替案:二段階の秒間PV制限(未採用)  1秒間に一定のリクエスト数までは無条件に 受け付ける  それを超えた場合、回遊中ユーザーからの アクセスのみ受け付ける 閾値を決めやすい 高負荷時も一定の新規ユーザー を受け付ける

    ⇒回遊中ユーザーにエラーを 表示する可能性が増える
  19. まとめ: アプリケーションサーバーのリソース制御  スレッド数制限 ⇒サーバーを守るため  秒間PV制限 ⇒SLAに関する説明のしやすさのため  回遊ユーザー数制限

    ⇒ユーザー体験をよくするため
  20. DBサーバーのリソース制御

  21. 解決策1:接続数制限  店舗ごとにコネクションプールを用意し、 接続数上限を設定 技術的に簡単 負荷が低くても制限が発動 する

  22. ケースA:他店舗の負荷状況の違い  1店舗のみの負荷の場合 店舗A: 1/10コネクション利用 店舗B:10/10コネクション利用  複数店舗同時の負荷の場合 店舗A:10/10コネクション利用 店舗B:10/10コネクション利用

    低負荷なのに 制限発動 高負荷で 制限発動
  23. 解決策2:二段階の接続数制限  一定数までは無条件に確保  それを超えた場合、全店舗の接続数合計が 閾値以下ならコネクション追加  プール上限に達したら拒絶  参考:店舗共通のプールにしない理由

     他店舗影響防止  DBサーバーのメモリ使用量削減
  24. ケースB:コネクションを保持して も使っていない  クエリを投げた後、アプリサーバーで処理 商品一覧画面:商品ごとの金額計算 購入処理:トランザクション保持中に多数の処理  単にコネクションを解放していない フレームワークにてメソッド末尾で解放 複数処理で単一コネクションを使いまわし

    こまめに開放すると、今度はコネクション取得の オーバーヘッドがかかる
  25. 解決策3:アクティブ接続数制御  「クエリを投げて結果待ち」の状態の接続数 をカウント  一定数を超えたらそれ以上クエリを投げない 他のクエリが終わるまで待つ 待っている数が処理が多ければエラー

  26. ここまでの対策で十分? 例:受注処理 1. 入力値のチェック 2. 決済連携 3. 在庫更新&受注登録 4. メール送信

  27. ここまでの対策で十分? ⇒障害を防ぐための制限で障害発生 例:受注処理 1. 入力値のチェック 2. 決済連携 3. 在庫更新&受注登録 4.

    メール送信 制限発動でエラー 決済連携済みなので 手動リカバリーが必要
  28. 解決策4:リクエスト開始時のチェック  接続数・アクティブ接続数を、リクエスト処 理開始時にもチェック  その時点で閾値を超えていたら、処理を開始 せずにエラー画面を表示

  29. まとめ: DBサーバーのリソース制御  2段階の接続数制限 ⇒複数店舗間の負荷制御  アクティブ接続数制限 ⇒「実際にDB負荷となる接続」の数の制御  リクエスト開始時のチェック

    ⇒致命的なタイミングでのエラーを防ぐ
  30. 今日話したこと  下記のような特徴をもつサービスでの 高負荷時の課題と解決策 EC:瞬間的な高負荷がある(セール、SNS拡散) 共用環境:同一サーバーで複数の店舗が稼働 拡張性:店舗により負荷傾向が異なる Java, Tomcat, Linux,

    PostgreSQL
  31. 結論  各サーバーの、各リソースについて、 店舗ごとの閾値を設ける  アプリケーションサーバー、 DBサーバー  PV数、スレッド数、ユーザー数、etc. 

    閾値を超えたときに、より「マシな」 エラーの出し方をする  回遊中ユーザーは優先  エラーはなるべく処理の最初に