目次
■クラウド&インフラストラクチャ
2019.07.23 2024.02.20 約3分
本連載では、インターネット基盤技術、または、インターネットのインフラ技術と呼ばれる領域に関して、Webホスティングサービスの歴史やWebサーバの設計と実装を中心に執筆していきます。 第4回では、これまで述べてきた基礎概念から少し踏み込んで、高集積マルチテナント環境において非常に重要となるリソース制御や研究動向について紹介します。
連載一覧:まつもとりーのインフラ入門
限られたコンピュータリソースで複数のホストをできるだけ高集積に管理・運用し、全体のコストを低減しながら安定稼働させるためには、特定のホストに対するWebアクセスがサーバ全体のリソースを占有しないように、ホスト単位で公平にリソースを配分するためのリソース分離手法が必要になります。
Jaoはかつて、リソース分離のために、ファイルやホスト単位で同時接続数を制御することによって、大量に同時アクセスがきたとしても、制限値以上のアクセスに対してはエラーを返す手法を提案しています。
David J, mod_limitipconn, http://dominia.org/djao/limitipconn.html
しかし、CPUやDisk I/O等のコンピュータリソースは共有のため、特定ホストにアクセスが集中したり、多くのリソースを消費するアプリケーションへのたった一つのリクエストによりリソースが占有されたりすることで、他のホストに影響を与える問題があります。 そのような課題を解決するために、リソース分離手法がこれまで複数提案されてきました。
Webサーバでは、静的なファイルの配信だけでなく、負荷のかかるCGIプログラムなどの動的コンテンツの生成が行われます。 マルチテナントアーキテクチャにおいては、特定のホストがリソースを占有することで、他のホストが影響を受ける状況はできるだけ回避すべきです。 そのため、サーバ高負荷時の迅速な原因の特定と対処は非常に重要です。
ホスト単位で専用のサーバプロセスを起動するようなマルチテナントアーキテクチャの場合は、リソースを占有しているホストを特定し、最悪の場合、専用のサーバプロセスさえ停止させれば他のホストへの影響を緩和できます。 一方、VirtualHost方式では、単一のサーバプロセス群で複数のホストを処理するために、リソースを多く占有しているホストやファイルを厳密に特定して、問題となるリクエストのみを制限する必要があります。
DSO実行方式で実行されたプログラムは、psコマンドによりプロセス情報を取得すると、プロセス名はプログラムファイル名ではなくサーバプロセス名であるhttpdとなります。 そのため、サーバプロセスがリソースを大量に消費していた場合は、それがどのホストのどのスクリプトによるものであるかを迅速に特定することが困難です。
また、CGI実行方式で実行されたプログラムは、CGIバイナリの引数としてプログラムファイル名が渡され、プロセス名としてはCGIバイナリ名が表示されるため、高負荷時等、迅速に対応しなければならない状況において、該当の原因となるプログラムファイル名を迅速かつ正確に特定するのは困難です。
DSO実行方式であっても、リソースを占有しているプログラムを容易に特定するために、松本らは、クライアントからのリクエストをApacheが受け付け処理を行ってからレスポンスを返すまでに、プロセスが消費したリソース量を測定するモジュール、mod_resource_checkerを提案しています。
このモジュールによって、実行されたプログラムが、管理者によって設定されていたシステムCPU時間、ユーザCPU時間、メモリ使用量の閾値を超えていた場合に、プログラムの絶対パス、VirtualHost名、システムCPU使用時間、ユーザCPU使用時間、メモリ使用量が計測されファイルに記録されます。 そのデータをもとに、高負荷ホストやスクリプトをリアルタイムで調査、検知できます。
chroot環境や仮想マシンでWebサーバを起動している場合は、ホスト毎にサーバプロセスが起動しているため、リソースの制限に関してサーバが持つすべての設定を利用することができます。
しかし、VirtualHostを利用した構成の場合、Apacheでは仕様上仮想ホスト単位で設定できる項目は限られています。 例えば、最大同時接続数を設定するためにMaxClientsを仮想ホスト単位で設定することはできません。 また、VirtualHost上でコンテンツ単位の同時接続数を柔軟に設定する方法がないのも高負荷ホストの制限を困難にしています。
VirtualHostは複数のホストを単一のサーバプロセス群で管理しているため、サーバプロセスが高負荷で停止してしまうと全てのホストの機能が停止します。 そのため、サーバプロセスが高負荷でサービス停止しないように制限することが必要となります。
例えば、Apacheが標準で備えるリソースの制限のための設定としては、メモリやプロセス数等があるが、CPU使用の制限の設定は限られており、 RlimitCPUという設定のみです。
RlimitCPUでは、クライアントからリクエストを受けてレスポンスを生成するまでに、設定したCPU使用時間を超過した場合、カーネルによって処理が強制的に切断されます。 そのため、ミドルウェアやWebコンテンツの実装によらずレスポンス処理が中断され、Webコンテンツの動作として信頼性が低くなります。
高負荷ホスト全体や高負荷スクリプトへのアクセス数を制限するために、松本らは、リクエスト対象への最大同時接続数を設定するモジュールmod_vlimitを提案しています。
設定対象は、任意のホストやファイル名、ファイルへの絶対パス、任意のディレクトリ、正規表現にマッチしたファイルやフォルダ等です。 同時接続数の設定値を超えた場合は、HTTPのステータスコード503(Service Unavailable)を返します。 また、同一クライアントIPからの同時接続数も設定できます。
高集積のホスティング環境においては、単一のサーバに収容しているホスト数が多いことから、リソースを多く占有するスクリプトにアクセスが集中し、サーバが高負荷となってOSが停止してしまうような状況は避けるべきです。 そこで、松本らは、CPU処理やI/O処理の負荷の目安となるロードアベレージの数値に着目し、リクエストを受けた後、ロードアベレージの数値によってレスポンスを返すかどうかをApacheが判断するモジュールmod_lalimitを提案しています。
ロードアベレージの数値を閾値として設定し、その数値を超えた場合はステータスコード503を返すことで安全に処理を中断させます。 1分平均のロードアベレージを閾値に設定できます。
今回は高集積マルチテナントアーキテクチャを採用したWebサーバにおいて、これまで述べてきた基礎概念から少し踏み込んで、マルチテナント環境において非常に重要となるリソース制御や研究動向について紹介しました。 次回も引き続き、リソース制御の研究紹介とその実装を紹介していきます。
本連載は下記の私が執筆した論文を参考に、新しい読者へ広めるために平易な形へと再編集しています。
・ 松本 亮介, 栗林 健太郎, 岡部 寿男, Webサーバの高集積マルチテナントアーキテクチャと運用技術, 電子情報通信学会論文誌B, Vol.J101-B, No.1, pp.16-30, Jan 2018.
・ copyright©2018 IEICE
(記事:松本 亮介)