ウェブアプリケーションサーバの Degradation Schemeの 制御に向けて 東京工業大学 情報理工学研究科 光来健一 日比野秀章 松沼正浩 千葉滋
アプリケーションサーバ 商用サイトの構築 DBサーバにアクセス 複雑な計算を伴う動的な ページ 3 層構造 アプリケーションサーバ 計算量増加 複数のサービス 例:帰り荷 Web トラック運送の帰り荷を有効に利用するための B to B システム 様々な条件を考慮したマッチング リクエストの受付 動的なページの生成 ファイルI/O
複数のサービスによる サーバへの負荷 ウェブアプリケーションサーバで複数のサービス 高負荷時に、各サービスの性能が低下 例:帰り荷 Web 複数のサービスによる サーバへの負荷 ウェブアプリケーションサーバで複数のサービス 例:帰り荷 Web 様々な条件を考慮したマッチング 顧客に応じたログインページ 高負荷時に、各サービスの性能が低下 実行環境によって決まる 特定のサービスが優先される 負荷の高い処理が優先されると、全体的に反応時間が悪化 各サービスが公平に処理される
degradation scheme 意味 制御の必要性 負荷に応じた各サービスの性能低下の度合い 実行環境に依存 共有するシステムリソースの配分で決まる 制御の必要性 実行環境に依存 開発者とユーザの実行環境は異なる可能性あり バージョンアップ サービス内容や実行コンテキストによって異なるべき
研究の目標 アプリケーションサーバのdegradation scheme をミドルウェアで制御 まず、本発表では 高負荷時の性能を制御 実行環境に依存しない制御 まず、本発表では 複数の OS で degradation scheme が異なることを 確認 OS 間で degradation scheme が異なる要因分析 制御する上で必要
実験の説明 目的 内容 OS 間 の degradation scheme の違いを明らかにする サーバの OS Solaris9, Linux2.6.7/2.6.5/2.4.18, FreeBSD5.2.1, Windows 2003 Server Enterprise Edition 負荷の異なる 2 種類のサービス フィボナッチ数の計算(軽いサービス) XML ファイルのパース・探索(重いサービス) ワークロード 軽いサービスへの並行リクエスト数 = 30 重いサービスへの並行リクエスト数 = 0 ~ 40
OS 間での相違
バージョン間での相違 OSによって degradation scheme は変わる
OS 間の相違の要因分析 目的 方法 OS 間で degradation scheme が異なる 主な要因を解明 accept完了 目的 OS 間で degradation scheme が異なる 主な要因を解明 degradation scheme を制御できるようにするため 方法 リクエスト処理時間の内訳を比較 対象:軽いサービスを実行するスレッド (Solaris 9, Linux 2.6.7) CPU スケジューリングとシステムコールに関するイベント Solaris : prex (プロファイリングツール) Linux : kev (prex と類似のツールを開発) accept開始
リクエスト毎のスレッド処理時間 リクエストの処理 (ms) Solaris Linux CPU 利用時間 3.71 3.91 待ち時間 accept完了 リクエストの処理 accept 完了~accept 完了 内訳の特徴 CPU利用時間 ほぼ同じ 待ち時間 ロック待ちがほとんど ロック待ちは Linux が 2.6 倍 (ms) Solaris Linux CPU 利用時間 3.71 3.91 待ち時間 137 375 (accept) 1.19 2.44 (poll) 0.41 19.4 (ロック) 136 348 2.6倍 accept開始
リクエスト処理中のロック待ち Solaris Linux システムコールにかかる時間(ms) 64.6 65.2 システムコールの頻度 accept完了 リクエスト処理中 接続の受付~スレッドプールに入る ロック待ちシステムコール mutex_lock, cond_wait (Solaris) Futex (Linux) pool へ Solaris Linux システムコールにかかる時間(ms) 64.6 65.2 システムコールの頻度 1.3 2.9 待ち時間の合計(ms) 82.0 189 2.2倍 accept開始
システムコールの頻度の 差の理由 (1) Solaris の JVM 1.4.2 の実装 Solaris のスレッドライブラリの実装 ロック獲得時にシステムコールの発行を抑える mutex_trylock 関数を呼んでロック獲得を試みる 獲得できなければ、mutex_lock 関数により システムコール発行 Solaris のスレッドライブラリの実装 アダプティブロック スピンロックとmutex_lockシステムコールの両方を使用 スピン中に獲得できれば、システムコールを発行しない
システムコールの頻度の 差の理由 (2) Linux では cond_wait システムコールを未実装 4つのロック獲得操作を使用して実装 システムコールの発行頻度増
スレッドプール スレッドプールに入る スレッドプールから出る thread-5 thread-1 wakeup thread-4 時間 スレッドプールに入る スレッドプールから出る thread-5 wakeup thread-4 thread-3 thread-2 woken up CPU を獲得
スレッドプールでの待ち時間 Solaris Linux 各スレッドの 処理時間 (ms) 4.34 11.7 待ちスレッドの 平均数 accept完了 Solaris Linux 各スレッドの 処理時間 (ms) 4.34 11.7 待ちスレッドの 平均数 12.7 13.0 待ち時間 (ms) 52.6 154 wakeup thread-5 thread-4 thread-3 thread-2 pool へ 2.7倍 woken up cpu 獲得 accept開始
次のスレッドを起こす際に 要する時間の内訳 次のスレッドを起こす際に 要する時間の内訳 accept完了 wakeup thread-5 thread-4 thread-3 thread-2 accept開始 accept完了 wakeup CPUを獲得 woken up pool へ 1.90 7.52 4.0倍 woken up cpu 獲得 accept開始
スケジュールされた延べスレッド数
タイムスライス 5.6倍
長いタイムスライスの原因 CPUスケジューラの スレッド優先度管理 Solaris Linux 頻繁に変動 頻繁にプリエンプト ほぼ一定 プリエンプトされない
検証実験 目的: 方法: ミドルウェアで degradation scheme を 制御するための第一歩 Linux 2.6.7 のカーネルを修正 最大タイムスライス 200ms -> 2ms 最小タイムスライス 10ms -> 1ms 同様のワークロードで、スループット・処理時間の 内訳を計測
タイムスライスを短くした効果(1)
タイムスライスを短くした効果(2) 待ち時間の内訳 スレッドプールでの待ち時間
まとめ degradation scheme を制御する必要性 OS 間での degradation scheme の相違を確認 Linux, Solarisにおける相違の原因解析 ロック待ちシステムコールの発行頻度 JVM の実装 スレッドライブラリ (アダプティブロック) Linux での cond_wait システムコールの未実装 CPUスケジューラのスレッド優先度 プリエンプトの頻度に相違 タイムスライスの変更による degradation scheme の 変更
今後の展開 ミドルウェアでOSの違いを考慮して degradation scheme を制御 Java で実装 AOPを利用 バイトコードの様々な箇所へ sleep, yield を挿入 タイムスライスの変更と同様の効果 具体的な制御手法については現在検討中
関連研究 高負荷時のウェブサーバの挙動 高負荷時のウェブアプリケーションサーバの挙動 スケジューリング手法 OSのスケジューリングの変更 カーネル内 IO 処理がボトルネック [Almeida’96] ワークロードによりボトルネックは異なる [Pradhan’02] 高負荷時のウェブアプリケーションサーバの挙動 DB [McWherter’04] スケジューリング手法 shortest-connection-first [Crovella’99] 優先度に基づいたスケジューリング [Elnikety’04] 関数定義によるスケジューリング [Shen’02] OSのスケジューリングの変更 Gray-Box [Andrea’01] Infokernel [Andrea’03]