SaaS型ECプラットフォームにおける高負荷対策
by
株式会社インターファクトリー
×
Copy
Open
Link
Embed
Share
Beginning
This slide
Copy link URL
Copy link URL
Copy iframe embed code
Copy iframe embed code
Copy javascript embed code
Copy javascript embed code
Share
Tweet
Share
Tweet
Slide 1
Slide 1 text
SaaS型ECプラットフォーム における高負荷対策 株式会社インターファクトリー CTO 水野 謙
Slide 2
Slide 2 text
自己紹介 略歴 2006年 日本IBM 東京基礎研究所 入社 マルチコア環境におけるJavaの高速化 設計書(Word, Excel)の品質検証ツールの作成、適用 2013年 インターファクトリー 入社 2016年 CTO就任 興味 パフォーマンスチューニング
Slide 3
Slide 3 text
今日話すこと 下記のような特徴をもつサービスでの 高負荷時の課題と解決策 EC:瞬間的な高負荷がある(セール、SNS拡散) 共用環境:同一サーバーで複数の店舗が稼働 拡張性:店舗により負荷傾向が異なる Java, Tomcat, Linux, PostgreSQL
Slide 4
Slide 4 text
先に結論 各サーバーの、各リソースについて、 店舗ごとの閾値を設ける 閾値を超えたときに、より「マシな」 エラーの出し方をする
Slide 5
Slide 5 text
サービスの特徴:拡張性と最新性の両立 ASP ebisumart パッケージ 拡張性 △ 〇 ・標準のJavaクラスを拡張して カスタマイズを記述 ・API経由でカスタマイズ 〇 最新性 〇 〇 カスタマイズしていても 標準機能は自動でアップデート ×
Slide 6
Slide 6 text
共用環境最大の課題:他店舗影響 ある店舗でアクセスが集中したことにより 他の店舗も遅くなってしまう ある店舗のカスタマイズロジックの パフォーマンスバグにより、 他の店舗も遅くなってしまう パフォーマンスバグがあるのは悪いこと それにより他店舗影響が出るのは最悪なこと
Slide 7
Slide 7 text
アプリケーションサーバーの リソース制御
Slide 8
Slide 8 text
解決策1:スレッド数制限 ある店舗のリクエストを処理している スレッド数が閾値を超えたら、 それ以上は受け付けない 処理が滞留したら確実に 制御が発動する SLA(秒間PV)未満でも 発動する可能性がある
Slide 9
Slide 9 text
解決策2:秒間PV制限 ある店舗にSLA以上のアクセスが発生したら それ以上は受け付けない 店舗管理者への説明が しやすい SLA(秒間PV)未満でも サーバーが高負荷になる ことはある ⇒「最悪なこと」を防げない
Slide 10
Slide 10 text
ここまでの対策で十分? 以下のようなサービスならたぶん十分 ⚫ SNS ⚫ Web検索 以下のようなサービスでは不十分 ⚫ EC ⚫ 東京オリンピックの ボランティア申し込み
Slide 11
Slide 11 text
No content
Slide 12
Slide 12 text
No content
Slide 13
Slide 13 text
ここまでの対策で十分? 以下のようなサービスならたぶん十分 ⚫ SNS ⚫ Web検索 以下のようなサービスでは不十分 ⚫ EC ⚫ 東京オリンピックの ボランティア申し込み リクエスト単位で ほぼ目的達成 複数のリクエスト を経て目的達成
Slide 14
Slide 14 text
ECシステムの難しさ セッションレスなプロトコル ユーザーの離脱を正確に判定できない SLAは秒間PVで定義 セッションフルなアプリケーション 複数の通信を経て目的達成 完了直前のエラーはユーザー体験として最悪
Slide 15
Slide 15 text
ユーザー体験として「マシな」 アクセス制御 新規ユーザーは混雑時に一定の確率でエラー 回遊中ユーザーはエラーにはなりにくい 「回遊中ユーザー」の定義は? 一回でもアクセスしたら カートに商品を投入したら 注文情報入力画面を表示したら 離脱の判定方法は? 一定期間アクセスがなかったら ブラウザのタブを閉じたら
Slide 16
Slide 16 text
ユーザー体験として「マシな」 アクセス制御 新規ユーザーは混雑時に一定の確率でエラー 回遊中ユーザーはエラーにはなりにくい 「回遊中ユーザー」の定義は? 一回でもアクセスしたら カートに商品を投入したら 注文情報入力画面を表示したら 離脱の判定方法は? 一定期間アクセスがなかったら ブラウザのタブを閉じたら
Slide 17
Slide 17 text
具体的な制御の方法 新規ユーザーだった場合 回遊中ユーザー数が閾値以上ならエラー そうでなければ、回遊中ユーザー一覧として登録 回遊中ユーザーだった場合 最終アクセス日時から一定時間以上たっていたら新規ユーザーとして処理 そうでなければ、最終アクセス日時を更新 制限発動時のユーザー体験が 比較的良い PVやサーバー負荷が低くても 制限が発動する場合がある 適切な閾値の設定が難しい
Slide 18
Slide 18 text
代替案:二段階の秒間PV制限(未採用) 1秒間に一定のリクエスト数までは無条件に 受け付ける それを超えた場合、回遊中ユーザーからの アクセスのみ受け付ける 閾値を決めやすい 高負荷時も一定の新規ユーザー を受け付ける ⇒回遊中ユーザーにエラーを 表示する可能性が増える
Slide 19
Slide 19 text
まとめ: アプリケーションサーバーのリソース制御 スレッド数制限 ⇒サーバーを守るため 秒間PV制限 ⇒SLAに関する説明のしやすさのため 回遊ユーザー数制限 ⇒ユーザー体験をよくするため
Slide 20
Slide 20 text
DBサーバーのリソース制御
Slide 21
Slide 21 text
解決策1:接続数制限 店舗ごとにコネクションプールを用意し、 接続数上限を設定 技術的に簡単 負荷が低くても制限が発動 する
Slide 22
Slide 22 text
ケースA:他店舗の負荷状況の違い 1店舗のみの負荷の場合 店舗A: 1/10コネクション利用 店舗B:10/10コネクション利用 複数店舗同時の負荷の場合 店舗A:10/10コネクション利用 店舗B:10/10コネクション利用 低負荷なのに 制限発動 高負荷で 制限発動
Slide 23
Slide 23 text
解決策2:二段階の接続数制限 一定数までは無条件に確保 それを超えた場合、全店舗の接続数合計が 閾値以下ならコネクション追加 プール上限に達したら拒絶 参考:店舗共通のプールにしない理由 他店舗影響防止 DBサーバーのメモリ使用量削減
Slide 24
Slide 24 text
ケースB:コネクションを保持して も使っていない クエリを投げた後、アプリサーバーで処理 商品一覧画面:商品ごとの金額計算 購入処理:トランザクション保持中に多数の処理 単にコネクションを解放していない フレームワークにてメソッド末尾で解放 複数処理で単一コネクションを使いまわし こまめに開放すると、今度はコネクション取得の オーバーヘッドがかかる
Slide 25
Slide 25 text
解決策3:アクティブ接続数制御 「クエリを投げて結果待ち」の状態の接続数 をカウント 一定数を超えたらそれ以上クエリを投げない 他のクエリが終わるまで待つ 待っている数が処理が多ければエラー
Slide 26
Slide 26 text
ここまでの対策で十分? 例:受注処理 1. 入力値のチェック 2. 決済連携 3. 在庫更新&受注登録 4. メール送信
Slide 27
Slide 27 text
ここまでの対策で十分? ⇒障害を防ぐための制限で障害発生 例:受注処理 1. 入力値のチェック 2. 決済連携 3. 在庫更新&受注登録 4. メール送信 制限発動でエラー 決済連携済みなので 手動リカバリーが必要
Slide 28
Slide 28 text
解決策4:リクエスト開始時のチェック 接続数・アクティブ接続数を、リクエスト処 理開始時にもチェック その時点で閾値を超えていたら、処理を開始 せずにエラー画面を表示
Slide 29
Slide 29 text
まとめ: DBサーバーのリソース制御 2段階の接続数制限 ⇒複数店舗間の負荷制御 アクティブ接続数制限 ⇒「実際にDB負荷となる接続」の数の制御 リクエスト開始時のチェック ⇒致命的なタイミングでのエラーを防ぐ
Slide 30
Slide 30 text
今日話したこと 下記のような特徴をもつサービスでの 高負荷時の課題と解決策 EC:瞬間的な高負荷がある(セール、SNS拡散) 共用環境:同一サーバーで複数の店舗が稼働 拡張性:店舗により負荷傾向が異なる Java, Tomcat, Linux, PostgreSQL
Slide 31
Slide 31 text
結論 各サーバーの、各リソースについて、 店舗ごとの閾値を設ける アプリケーションサーバー、 DBサーバー PV数、スレッド数、ユーザー数、etc. 閾値を超えたときに、より「マシな」 エラーの出し方をする 回遊中ユーザーは優先 エラーはなるべく処理の最初に