• 検索結果がありません。

秋山研究室 sasagawa

N/A
N/A
Protected

Academic year: 2018

シェア "秋山研究室 sasagawa"

Copied!
44
0
0

読み込み中.... (全文を見る)

全文

(1)

コンピュータ理工学部特別研究 II A ・ B

「イベント駆動 I/O システムコールを用いた

事前 fork サーバの性能調査」

A performance evaluation of the prefork server using

event-driven I/O system call

秋山特研

笹川 駿

平成 24 年 2 月 7 日

(2)

概要

近年,イベント駆動ネットワークサーバが高性能を示すことで注目を集めている.イベント駆動の Web サーバ Nginx は最も広く用いられている Web サーバ Apache httpd (以下 Apache) に対して性能面で優れて いるという報告がある.しかし,Apache の開発も進められており,これまでに示された結果が現在でも有 効かどうかは不明である.また,イベント駆動ネットワークサーバも様々な実装があるため,必ずしも一 つの側面からでは比較することができない.そこで,本研究ではまずイベント駆動ネットワークサーバの 動向について調査し,Nginx と Apache の実装の違いについてその概要を確認した.さらに,Nginx との比 較評価を実施するための準備実験として,イベント駆動 I/O システムコールの一種である epoll を用いた Apacheの事前 fork サーバ実装について,性能調査を実施した.Nginx との比較を目標としているため,実 験に利用する PC の性能を最大限まで利用した状態での,1 秒あたりの同時コネクション数,1 秒あたりの リクエスト処理数等を得る方法について調査を行った.実験時には,サーバに負荷を与えるクライアント側 の性能評価ツールである httperf においても性能を出すための調整を実施した.本研究で得られたパラ メータを用いて,今後は Nginx の詳細な実装および性能チューニング方法の調査,Nginx との性能比較を実 施する必要がある.

Abstract

In recent years, event-driven network servers have attracted considerable attention because of its high perfor- mance. A web server, Nginx, based on the event-driven implementation was reported to defeat the major HTTP daemon Apache httpd. However, since Apache itself is also improved day by day, it is uncertain that the reported results are still valid or not. Furthermore, since there are various event-driven network server implementations, it is difficult to compare them from a one-sided view. So thus, firstly we investigated the trend of event-driven network servers and confirm the overview of the difference between Nginx and Apache. Then we evaluated Apache httpd with prefork MPM which uses a kind of event-driven I/O system call epoll. Since the goal of this research is to compare it with Nginx, we investigated and found the maximum concurrent connection/second, processed requests/second and so on. In the experiments, we also tuned the performance measurement tool httperf which generate http traffic to load the server. As future work, we must investigate the detail implementation of Nginx and the methods to tune its performance, then compare with Apache by using the parameters obtained in this research.

(3)

目 次

目 次

1 はじめに 4

2 イベント駆動ネットワークサーバ 5

2.1 基本的なシステムコールの動作 . . . 5

2.1.1 ソケット. . . 5

2.1.2 fork . . . 6

2.2 I/Oモデル . . . 7

2.2.1 ブロッキング I/O . . . 8

2.2.2 非ブロッキング I/O . . . 9

2.2.3 多重化 I/O . . . 9

2.2.4 非同期 I/O . . . 11

2.3 多重化 I/O の事例 . . . 11

2.3.1 クライアントがネットワークと標準入出力に同時にアクセスする場合 . . . 12

2.3.2 クライアントが複数のソケットを同時に扱う場合 . . . 12

2.3.3 TCPサーバがリスニングソケットと接続済みソケットを同時に扱う場合 . . . 12

2.3.4 TCPと UDP の両方のプロトコルを同時に扱う場合 . . . 12

2.3.5 複数のサービスを同時に扱う場合 . . . 13

2.4 クライアント-サーバシステムの設計方法 . . . 13

2.4.1 事前 fork サーバ: accept を用いた実装 . . . 15

2.4.2 事前 fork サーバ: ディスクリプタパッシング . . . 15

2.4.3 事前 fork サーバ: select 等の I/O 多重化システムコールを用いた実装 . . . 15

2.5 Apache, Nginxでの実装. . . 16

3 Webサーバと性能評価ツール 16 3.1 Apache httpd . . . 17

3.2 webサーバの性能評価ツール. . . 17

3.2.1 Apache HTTP server benchmarking tool. . . 17

3.2.2 httperf . . . 18

3.3 本研究で調査する内容 . . . 18

4 Webサーバ及び性能評価ツールの性能チューニング 18 4.1 実験用 Web サーバの立ち上げ . . . 18

4.1.1 サーバの立ち上がりを ab を用いて確認する . . . 20

4.1.2 サーバの立ち上がりをブラウザで確認する . . . 20

4.2 Webサーバのチューニング. . . 21

4.2.1 MaxClients . . . 21

4.2.2 ServerLimit . . . 22

4.2.3 ulimit . . . 23

4.2.4 ulimitの変更 . . . 23

(4)

目 次

4.2.5 sysctl. . . 24

4.2.6 制限解除のまとめ. . . 25

4.2.7 Macのプロセス数制限 . . . 26

4.3 性能評価ツール . . . 26

4.3.1 Segmentation faultの原因 . . . 26

4.3.2 FD SETSIZE . . . 27

5 性能調査 29 5.1 実験環境. . . 29

5.1.1 MacOSXを用いた実験環境 . . . 29

5.1.2 agileを用いた実験環境 . . . 29

5.2 processの立ち上がりの遅延の調査. . . 29

5.2.1 Apacheの CPU 使用率 . . . 30

5.2.2 forkにかかる時間. . . 31

5.3 Connection timeの調査 . . . 31

5.3.1 FD SETSIZE変更. . . 32

5.3.2 httperfを複数クライアントで実行 . . . 32

5.3.3 Webサーバの使用 CPU をひとまとめにする . . . 33

5.3.4 結果検証. . . 33

5.3.5 得られた結果 . . . 34

6 おわりに 35 7 付録 35 7.1 httperfのインストール . . . 36

7.1.1 Unixの場合 . . . 36

7.1.2 Linuxの場合 . . . 37

7.2 プロセスの立ち上がりの遅延で使用したスクリプト . . . 39

7.3 crontabを用いた httperf の同時実行 . . . 40

(5)

1 はじめに

近年,ネットワークサーバを運用をする際に,ハードウェア性能は問題が無くても,クライアント数があ まりに多くなるとサーバ側でクライアントのリクエストを処理できなくなる問題があり,C10K 問題 [1]と 呼ばれている.本研究ではとくに HTTP を処理する Web サーバにおける C10K 問題に着目する.Web サー バにおける C10K 問題を解決するために開発された Nginx は,その高い処理性能で注目されている.Nginx と現在 Web サーバシェア No.1 である Apache httpd[4](以下 Apache と呼ぶ) の性能を比較したサイト [2]から 比較結果を引用する (図1).このサイトでは,Nginx はイベント駆動型ネットワークサーバであり,Apache よりも消費メモリが少なく,高性能であると述べている.

図 1: Apache と Nginx の性能比較結果の例

このサイトではメモリの消費量の違いが大きく取り上げられているが,近年 PC のメモリ価格も大幅に 低下しており,メモリ消費量が大きくなっても問題なく動作する可能性がある.また Apache でもイベント ベースの処理方法が実装されており,機能面で改善されている可能性がある.そこで,本研究ではイベン ト駆動型ネットワークサーバについて現在広く利用されている Apache との違いを調査する.また,Apache と Nginx を比較するための準備実験として,Apache を事前 fork サーバとして利用した場合の性能について 調査する.

第2章では,イベント駆動ネットワークサーバについて,I/O モデルやクライアント-サーバシステムの設 計手法などの概念との比較を踏まえて説明する.

第3章では本研究に関連する Web サーバ及び用いた性能評価ツールの紹介を行い,本研究で調査を行う Apacheについてや調査内容を記す.第4章では Web サーバの性能測定を行うために必要な Web サーバ及 び性能評価ツールのチューニング事項,またその設定の際に注意や設定が必要な事について記す.そして第 5章では性能調査の内容及び得られた結果について述べる.

(6)

2 イベント駆動ネットワークサーバ

以下の節ではイベント駆動ネットワークサーバについて述べる.イベント駆動ネットワークサーバにつ いて理解するには,まずソケット,fork などの基本的なシステムコールの動作,I/O モデル,クライアント- サーバシステムの設計手法について理解する必要がある.これらの概念について文献 [6]で述べられている 内容を中心にイベント駆動ネットワークサーバの理解に必要な事前知識について述べる.I/O モデルの中で も特に多重化 I/O モデルは本研究に深く関係するので,別途節を設けてこのモデルの利用が必要な事例につ いて説明する.以下2.1節で基本的なシステムコールの動作について,2.2節では I/O モデル,2.3節では多 重化 I/O の事例について述べる.さらに,2.4節でクライアント-サーバシステムの設計手法について述べ, 最後に2.5節で本研究が対象としている Apache, Nginx がどのようなモデルに基づいているのか,その実装 について触れる.

2.1 基本的なシステムコールの動作

以下では基本的なシステムコールについて,本稿での取り扱いについて述べる.個々のシステムコールの 詳細については文献 [6]を参照されたい.

2.1.1 ソケット

ソケットはネットワーク入出力のための API(socket()) の意味とネットワークのエンドポイント (接続 点) の 2 つの意味をもつ.図2に本稿でのソケットの記載方法について示す.ソケットの詳細については文 献 [6]の 3,4 章を参照のこと.

デバイスやファイルの入出力と同様,カーネル上での入出力インスタンスはファイルディスクリプタで識 別される. 慣習でファイルディスクリプタと呼ばれているが,ネットワーク入出力も対象とするため,以 下ではディスクリプタと呼ぶ.ソケットはアプリケーション側からは,ネットワーク入出力用のディスクリ プタのように見える.

PC2 (172.16.10.2) PC1 (192.168.10.1)

ネッ ワーク

TCP サーバ TCP

ク ン

ソケッ ソケッ ソケッ ソケッ

ネッ ワーク入出力用 スク プタ

TCP|192.168.10.1:50000|172.16.10.2:8000 |送信元 ス:ポー |宛先 ス:ポー

TCP|192.168.10.1:50000|172.16.10.2:8000

フ その他の

入出力用 スク プタ

ソケッ 記録 エン 情報

の場合現在の読み込み

位置 の情報が記録

図 2: ソケットとその他の入出力用ディスクリプタ

(7)

2.1 基本的なシステムコールの動作

図3に TCP ソケットの概要を示す.UDP ソケットと異なり,TCP ソケットには「リスニングソケット」 と「接続済みソケット」がある.TCP では通信開始時に新規コネクションを確立する必要があり,この場 合クライアントはリスニングソケットに接続を要求する.サーバ側はリスニングソケットで要求を受信する と,接続済みソケットを生成し,その後の通信は接続済みソケットで行う.これは TCP のコネクション確 立後はシーケンス番号,ふくそうウインドウなど,コネクションごとに状態を管理する必要があるため,新 規にディスクリプタを作成し,ディスクリプタと関連付けて状態を記録しているためである.なお,ファイ ル I/O においても次データの読み込み位置等の情報をディスクリプタに関連付けて記録している.UDP の 場合はコネクションを確立しないため,フロー (送信元アドレス,ポート,宛先アドレス,ポート,プロト コルの 5 つ組) に対して 1 つ状態管理すれば良いため,新たにソケットを生成する必要はない.

PC2 (172.16.10.2) PC1 (192.168.10.1)

ネッ ワー TCP

イアン

TCP サーバ

スニン

接続済み TCP|192.168.10.1:50000|172.16.10.2:8000 TCP|*:*|*:8000

TCP|192.168.10.1:50000|172.16.10.2:8000 (1)接続要求

(2)接続確立 ータ送受信

図 3: TCP ソケットにおけるリスニングソケットと接続済みソケット

2.1.2 fork

forkは,Unix における子プロセスを生成するためのシステムコールである.fork の詳細は文献 [6]の 4.7節を参照のこと.以下では特に 4.8 節で述べられている並行サーバを実現する際の fork の動作につい て説明する.

単一のサーバプロセスでクライアントから送られてくる要求を逐次処理するサーバを反復サーバ (iterative server)と呼ぶ.これに対し,単一のサーバを単一のクライアント専用に貼り付けるのではなく,複数のク ライアントを同時に処理するサーバを並行サーバ (concurrent server) と呼ぶ.UNIX で最も簡単に並行サー バを実現する方法として fork システムコールを用いる方法がある.TCP ソケットでサーバがコネクショ ンを accept した図3の (2) の状態で fork が実行されると,図4に示すようにディスクリプタ,この場 合,リスニングソケットおよび接続済みソケットも含めてサーバプロセスのコピーが生成される.それぞ れのディスクリプタには参照数 (reference count) が記録されており,コピーが生成された時点でそれぞれの ディスクリプタの参照数が加算される.ディスクリプタはプロセスからクローズされても,参照数が 0 に なるまで破棄されることはない.

そのため,図5のように,リスニングソケットで接続を待ち受けする親プロセスと,接続済みソケット で受信するデータを処理するプロセスに役割分担し,それぞれのプロセスで不要なソケットをクローズす

(8)

2.2 I/Oモデル

PC2 (172.16.10.2) PC1 (192.168.10.1)

ネットワーク TCP

クライアント

TCP サーバ TCP|192.168.10.1:50000|172.16.10.2:8000 TCP|*:*|*:8000

TCP|192.168.10.1:50000|172.16.10.2:8000

TCP サーバ TCP|*:*|*:8000

TCP|192.168.10.1:50000|172.16.10.2:8000 参照数 2

参照数 2 参照数 2

参照数 2

fork

図 4: fork による並行サーバの実現 (1)

ることで,並行サーバが実現できる.fork を用いることで,単純な反復サーバと同様に 1 つのディスクリ プタを 1 つのプロセスが受け持つ形でサーバ側のプログラムを開発できる.

PC2 (172.16.10.2) PC1 (192.168.10.1)

ネットワーク TCP

クライアント

TCP サーバ TCP|192.168.10.1:50000|172.16.10.2:8000 TCP|*:*|*:8000

TCP サーバ

TCP|192.168.10.1:50000|172.16.10.2:8000

参照数 1 参照数 1

図 5: fork による並行サーバの実現 (2)

2.2 I/O モデル

文献 [6]の 6.2 節で述べられているとおり,Unix で利用できる I/O モデルには次のようなものがある. (1) ブロッキング I/O

(9)

2.2 I/Oモデル

(2) 非ブロッキング I/O

(3) I/Oの多重化 (select, poll, kqueue, epoll) (4) シグナル駆動 I/O

(5) 非同期 I/O (Posix.1 の aio 関数群)

これらの I/O モデルのうち,(4) のシグナル駆動 I/O については本研究で扱う epoll や kqueue などの I/O 多重化のためのシステムコールに似ているが,直接本研究に関係しないため説明を省略する.以下では他 の 4 つの I/O モデルの概要について述べる.以下の説明では,受信が完了したことが判定しやすい UDP で 通信する場合の例について述べる.また,アプリケーションとカーネル (オペレーティングシステム) を区 別して表記する.なお,TCP では送信,受信バッファをもつため,より複雑な処理となる.I/O モデルにつ いては,記事 [7]でも解説されており,文献 [6]の説明を必要に応じて補足しながら説明する.

2.2.1 ブロッキング I/O

ブロッキング I/O のフローの例を図6に示す.図中の縦矢印はアプリケーションあるいはカーネルの時間 軸を示しており,点線部分はアプリケーションがブロックしている (待ち状態になっている) ことを示して いる.recvfrom 等のシステムコールを呼ぶことでアプリケーションからカーネルに制御が移る.これを 明示するため,システムコールの呼び出しを示す右方向の矢印上には「カーネルコンテキストスイッチ」と 示されている.左向きの矢印でアプリケーションに制御が戻る.

ブロッキング I/O では recvfrom システムコールを発行してから,カーネルがデータグラムを受信する までブロックする.ブロックしている間 recvfrom を呼び出したプロセスは他の処理を実行できない.同 時に他の処理を実行するには,2.1節で述べた並行サーバのように,複数プロセスで並行して処理する必要 がある.一方で,プログラムはシステムコールの処理を含めて逐次実行されるため,プログラミングが容易 になる.

ーション カーネ

recvfrom

ロセス recvfrom 呼び出しで

ロッ

シス ムコー /カーネ コン キス スイッチ

ータ

ータ ムあ ータ コピー

コピー完了 ータ

処理

OKを返す

ータ待ち

カーネ ーション

ータをコピー

図 6: ブロッキング I/O のフロー

(10)

2.2 I/Oモデル

2.2.2 非ブロッキング I/O

非ブロッキング I/O のフローの例を図7に示す.最初の 3 回の recvfrom の呼び出しでは返すべきデー タがないので,カーネルは即座にエラーとして EAGAIN または EWOULDBLOCK を返す.4 回目の recvfrom の呼び出しではデータグラムが到着しているので,アプリケーションバッファにコピーされ,recvfrom は 成功する.

このように,アプリケーションがループ中で非ブロッキングソケットに対する recvfrom 呼び出しを繰り 返すことをポーリング (polling) と呼ぶ.図中にも記載があるとおり,このモデルでは CPU 時間を無駄にす る可能性がある.

アプ ーション カーネ

recvfrom

プロセス 連続して recvfromを 呼び出し OKを待つ

ポー

※CPU時間 の浪費

ータ

ータ ムあ ータ ムのコピー

コピー完了 ータ

の処理

OKを返す

ータ待ち

カーネ アプ ーション

ータをコピー EAGAIN/EWOULDBLOCK

ータ recvfrom

EAGAIN/EWOULDBLOCK recvfrom

EAGAIN/EWOULDBLOCK recvfrom

ータ

シス ムコー /カーネ コン キス スイッチ

シス ムコー /カーネ コン キス スイッチ

シス ムコー /カーネ コン キス スイッチ

シス ムコー /カーネ コン キス スイッチ

図 7: 非ブロッキング I/O のフロー

2.2.3 多重化 I/O

I/Oの多重化 (I/O multiplexing) を行う場合は,実際の入出力でブロックするのではなく,select ある いは poll を呼び出し,これらの関数の中でブロックする.図8は,多重化 I/O モデルのフローの例を示し ている.

最初は select の呼び出し内でブロックし,データグラムソケットが読み出し可能になるのを待ってい る.select から戻るとソケットは読み出し可能になっているので,recvfrom を呼び出してアプリケー ションバッファにデータをコピーする.図6と図8を比較すると,select 用いた場合には利点がなく,逆 に select を使用している分必要なシステムコールが 2 つに増加しており,損失がある.select の利点 は,複数のディスクリプタに対して,それらの準備ができるのを待つことが可能になる点にある.

さらに,I/O 多重化のためのシステムコールについて,最近の動向を補足する.select や poll には図 8中の (a) に示したように,ディスクリプタの状態を記録した配列 (ディスクリプタ配列) をカーネルから受 け取った後,アプリケーション側でどのディスクリプタが準備できているか確認する必要がある.また,シ ステムコール呼び出しの際およびディスクリプタが読み出し可能になった際に,アプリケーションとカーネ

(11)

2.2 I/Oモデル

ーション カーネ

select ロセス

読み出し

可能

間っ select 呼び出し ロッ

ータ

ータ ムあ

ータ

ー完了

ータ

処理

OKを返す

ータ待ち

カーネ ーション ータをコ 読み出し可能を返す

recvfrom

ロセス ーション バッ ータ ー完了

を待っ ロッ ロセスあた 利用可能

タ配列

準備

タを検索

(a)

シス ムコー /カーネ コン キス ッチ

シス ムコー /カーネ コン キス ッチ

図 8: 多重化 I/O のフロー (select)

ルの間で,ディスクリプタ配列をコピーする必要がある.カーネルは読み出し可能を通知する時点でどの ディスクリプタの準備ができているか把握できているため,すべてのディスクリプタの状態を含むディスク リプタ配列を渡すのではなく,準備ができたディスクリプタのみを通知するのが望ましい.そこで,カーネ ルレベルで準備ができたディスクリプタのみを通知する機能が実装され提供されている.BSD 系の OS で は kqueue,Linux では epoll を用いることで,図9に示したように,(a) の分の処理時間およびディスク リプタ配列のコピー時間を短縮できる.なお,select,poll と異なり,kqueue,epoll にはいくつか のシステムコールが用意されており,kqueue では,kevent(),epoll では epoll wait() などのシ ステムコールでブロックすることになる.

ーション カーネ

kqueue/epoll ロセス

読み出し

可能

間っ select 呼び出し ロッ

ータ

ータ ムあ

ータ

ー完了

ータ

処理

OKを返す

ータ待ち

カーネ ーション ータをコ 読み出し可能を返す

recvfrom

ロセス ーション バッ ータ ー完了

を待っ ロッ

シス ムコー /カーネ コン キス ッチ

シス ムコー /カーネ コン キス ッチ

図 9: 多重化 I/O のフロー (kqueue/epoll)

(12)

2.3 多重化I/Oの事例

2.2.4 非同期 I/O

非同期 I/O (Asynchronous I/O) では,I/O 操作を開始し,操作が完了した時 (カーネルからアプリケーショ ンバッファへのコピーを含む) に通知するようカーネルに対して指示する.図10に非同期 I/O のフローの例 を示す.最初に aio read を呼び出し1,ディスクリプタ,バッファへのポインタ,バッファのサイズ2,ファ イルオフセット3および操作が完了した際の通知方法をカーネルに渡す.このシステムコールはただちに制 御を返し,プロセスは I/O の完了を待ってブロックすることはない.この例では,何らかのシグナルを用い るかスレッドのコールバックを用いて操作の完了を通知することをカーネルに指示してあると仮定する.

アプ ーション カーネ

aio_read

セス 処理 を続け

ータ

ータ ムあ ータ コピー

コピー完了

また コー

ータ 処理

aio_readで指定さ 配送or コー 呼び出し

ータ待ち

カーネ アプ ーション

ータをコピー

非同期I/O

シス ムコー /カーネ コン キス スイッチ

図 10: 非同期 I/O のフロー

2.3 多重化 I/O の事例

本節では2.2で述べた多重化 I/O モデルを用いて I/O を多重化する必要がある事例について触れる.

(1) クライアントがネットワークと標準入出力に同時にアクセスする場合 (2) クライアントが複数のソケットを同時に扱う場合

(3) TCPサーバがリスニングソケットと接続済みソケットを同時に扱う場合 (4) TCPと UDP の両方のプロトコルを同時に扱う場合

1Posixの非同期 I/O 関数の名前は aio で始まる

2readに対する引数と同じ 3lseekで用いる引数と同様

(13)

2.3 多重化I/Oの事例

(5) 複数のサービスを同時に扱う場合 以下それぞれの状況について説明する.

2.3.1 クライアントがネットワークと標準入出力に同時にアクセスする場合

遠隔ログインのように,ユーザの入出力と遠隔のサーバへの要求および応答を同時に扱う必要がある場 合,1 つのプログラムが複数のディスクリプタを同時に扱う必要があり,I/O の多重化が必要になる.図11 に telnet や ssh など,遠隔ログインのアプリケーションの例を示す.図に示したとおり,基本的にはク ライアント側,サーバ側共に I/O の多重化が必要になる.

以下 資料 基本的 下記 書籍 情報 参考 スタ TCP/IP 内容 一通 学生向け 作成し

[1] W. チャー (),篠田 陽一(翻訳) UNIXネッ ワー プロ Vol.1ネッ ワー API: XTI 2 ーショ 1999

図 11: ネットワークと標準入出力に同時にアクセスする例

2.3.2 クライアントが複数のソケットを同時に扱う場合

TCP の理論的なスループット (TT CP) は Round Trip Time (RT T ) とウインドウサイズ (W ) によって TT CP = W

RT T のように表されるが,RT T の値が大きくなると,高いスループットが得られなくなることが 知られている.そのため,複数のコネクションを同時に利用してスループットを向上させる手法が用いられ ている.例えば Web ブラウザでは 4 つ程度のコネクションを同時に利用している.このような場合,クラ イアントが同時に複数のソケットを扱う必要がある.また,本研究で利用する HTTP の負荷生成ツールで ある httperf も複数のコネクションを利用することで大量のコネクションおよびリクエストを同時に生成 する.httperf では,select を用いて I/O の多重化を実現している.図12に複数のソケットに同時に アクセスする例について示す.

2.3.3 TCPサーバがリスニングソケットと接続済みソケットを同時に扱う場合

2.1節で述べたように,TCP サーバは TCP コネクション確立要求パケットを扱う「リスニングソケット」 とコネクション確立済みのパケットを扱う「接続済みソケット」を区別して扱う必要がある.そのため,単 一のサーバで接続後のパケット処理も担当する場合,複数のディスクリプタを同時に扱う必要がある.図 13にリスニングソケットと接続済みソケットを同時に扱う例を示す.

2.3.4 TCPと UDP の両方のプロトコルを同時に扱う場合

図14に TCP と UDP の両方のプロトコルを同時に扱う場合の例について示す.この場合も複数のディス クリプタを同時に扱う必要がある.

(14)

2.4 クライアント-サーバシステムの設計方法

PC3 (172.16.10.3) PC2 (172.16.10.2) PC1 (192.168.10.1)

ネットワーク

TCPサーバ TCPクライアント

TCPサーバ

TCP|192.168.10.1:50000|172.16.10.2:80 TCP|192.168.10.1:50000|172.16.10.2:80

TCP|192.168.10.1:50000|172.16.10.3:80 TCP|192.168.10.1:50000|172.16.10.3:80 TCP|192.168.10.1:50001|172.16.10.2:80 TCP|192.168.10.1:50001|172.16.10.2:80

図 12: 複数のソケットに同時にアクセスする例

PC3 (192.168.10.3)

ネットワーク

PC2 (172.16.10.2) PC1 (192.168.10.1)

TCPクライアント

TCP|192.168.10.1:50000|172.16.10.2:8000

TCPクライアント

TCPサーバ TCP|*:*|*:8000

TCP|192.168.10.1:50000|172.16.10.2:8000

TCP|192.168.10.3:50000|172.16.10.2:8000 TCP|192.168.10.3:50000|172.16.10.2:8000

図 13: リスニングソケットと接続済みソケットを同時に扱う例

2.3.5 複数のサービスを同時に扱う場合

最後に複数のサービス (異なるポート番号) を同時に扱う場合について示す.inetd のような多数のサー ビスを同時に扱う場合や同一サービスについて,暗号化用のポートと平文用ポートを同時に扱う場合など が相当する.図15に例を示す.

2.4 クライアント-サーバシステムの設計方法

文献 [6]の 27 章で述べられているとおり,Unix 上でサーバを構築する場合,次のようなタイプのプロセ ス制御を利用することができる.

(1) 反復サーバ (iterative server)

(2) forkによる並行サーバ (concurrent server)

(15)

2.4 クライアント-サーバシステムの設計方法

ネットワーク

PC2 (172.16.10.2) PC1 (192.168.10.1)

TCPクライアント TCPサーバ

TCP|192.168.10.1:50000|172.16.10.2:8000 TCP|192.168.10.1:50000|172.16.10.2:8000

UDP|192.168.10.1:50000|172.16.10.2:8000 UDP|192.168.10.1:50000|172.16.10.2:8000

図 14: TCP と UDP の両方のプロトコルを同時に扱う場合

PC2 (172.16.10.2) PC1 (192.168.10.1)

ネットワーク

TCPクライアント TCPサーバ

TCP|192.168.10.1:50000|172.16.10.2:8000 TCP|192.168.10.1:50000|172.16.10.2:8000

TCP|192.168.10.1:50000|172.16.10.2:9000 TCP|192.168.10.1:50000|172.16.10.2:9000

図 15: TCP と UDP の両方のプロトコルを同時に扱う場合

(3) I/O多重化を用いて単一プロセスで任意の数のクライアントを処理するサーバ (4) スレッドによる並行サーバ

(5) サーバが起動した際に fork し,子プロセスのプールを作成しておく事前 fork (preforking) を用いた サーバ

(6) サーバが起動した際にスレッドのプールを作成しておく事前スレッド生成 (prethreading) を用いたサーバ (1), (2)は2.1節で述べた基本的なサーバ構築手法である.(3) は2.2節で述べた多重化 I/O モデルに基づ くサーバ構築手法であり,2.3節の (3) の事例に相当する.(4) はスレッドにより,fork のコストを低減した 手法であり,(5), (6) は,事前生成により (2), (4) において,プロセス生成,スレッド生成のコストを低減し た手法である.

Nginxは (3) の手法において,後述のとおり,I/O 多重化ではなく非同期 I/O を用いた実装になっている. Apacheについては,(2), (4), (5), (6) について実装しており,Nginx と同様な実装についても実験的に実装を 進めている.なお,本研究では,後述のとおり,Apache の事前 fork について調査を実施するので,以下で は (5) の実装について述べる.事前 fork では新規接続時の子プロセス生成のコストを低減できるため,プー ルしておくプロセス数を調整すれば,(2) よりも良い性能を示すことが知られている.

(16)

2.4 クライアント-サーバシステムの設計方法

2.4.1 事前 fork サーバ: accept を用いた実装

以前は accept をカーネル内に実装している BSD 系のカーネルでしか実行できないという制約があった が,最近のカーネルでは,複数プロセスでの accept がサポートされている.そのため,図16で示すとお り,親プロセスがリスニングソケットを作成し,子プロセスがリスニングソケットの複製に対して accept すれば,複数の子プロセスが同時に接続要求を待ち受けることができる.このとき,到着した接続要求によ り,accept でブロックし,スリープしていたすべてのプロセスが起こされるため,プールされるプロセ ス数が多くなると CPU に負荷がかかる.この状況は獣群の暴走 (thundering herd) と呼ばれる.実際には, Apacheでは http (80), https (443) など複数のサービスを同時に扱う必要があり,2.3節で述べた「複数サー ビスを同時に扱う場合」に相当するため,単純にリスニングソケットを accept することはできず,後述 の I/O 多重化用システムコールを用いる必要がある.

PC2 (172.16.10.2)

PC1 (192.168.10.1) TCP イアント

TCP サーバ

TCP|192.168.10.1:50000|172.16.10.2:8000

TCP|*:*|*:8000

TCP サーバ

TCP|*:*|*:8000 参照数 4 参照数 4

(2)fork

TCP サーバ

TCP|*:*|*:8000 参照数 4

TCP サーバ

TCP|*:*|*:8000 参照数 4 (3) TCP

接続要求 接続要求 接続要求 接続要求 (1)親プロセス親プロセス親プロセス親プロセス

スニン スニン スニン スニン ット ット ット ット生成生成生成生成

図 16: すべての子プロセスでリスニングソケットを待ち受ける場合

2.4.2 事前 fork サーバ: ディスクリプタパッシング

他に,27.9 節で述べられているとおり,親プロセスだけでリスニングソケットを待ち受けし,接続要求に 対して生成した接続済みソケットのディスクリプタをストリームパイプを用いて子プロセスに受け渡す方法 も存在する.しかしながら,この方法も p.702 の図 27.1 に書かれているとおり,その性能は単純に accept を用いた場合におよばない.

2.4.3 事前 fork サーバ: select 等の I/O 多重化システムコールを用いた実装

文献 [6]の p.716 に書かれているとおり,select で待ち受けすると,accept で待ち受けした場合より も性能は悪くなる.また,獣群の暴走を避けるために 27.7 節,27.8 節に書かれているとおり,ファイルロッ

(17)

2.5 Apache, Nginxでの実装

クやスレッドロックで複数の子プロセスが,同じリスニングソケットに対して同時にアクセスし,ブロッキ ングするのを避ける方法も考えられるが,pp.702-703 に書かれているとおり,その性能は単純にロックなし で accept を利用した場合と比べて低下してしまう.

ここで,新しく作成された kqueue, epoll といったシステムコールを用いることで,必要な子プロセス だけに通知してコネクションを処理させることが可能になり,獣群の暴走を避けながら複数のサービスに 対応することが可能になる.最近の Apache の実装では kqueue, epoll が利用できる環境ではこれらのシ ステムコールを用いるため,事前 fork において文献 [6]で触れられている問題は解消されていると言える. 残る問題は,クライアント接続時の kqueue, epoll の応答によって発生するコンテキストスイッチの負荷 をどれだけ抑えられるかであり,利用する環境に応じて事前生成するプロセス数をチューニングする必要が ある.

2.5 Apache, Nginx での実装

本研究で調査する Apache は,マルチプロセッシングモジュール (Multi-Processing Modules: MPM) という 仕組みにより,複数のクライアント-サーバシステムの設計方法に対応している.すでに述べたとおり,事 前 fork サーバ,事前スレッド生成サーバ,イベント駆動サーバなど,様々な方式に対応している.本研究 では MPM で提供されている設計方法の中でもこれまで最も長い間,多くの組織で利用されてきた事前 fork (prefork)モジュールについて調査する.Apache の事前 fork モジュールは,2.4節で述べたとおり,kqueue, epollを用いて実装されている.

一方 Nginx は epoll は利用しておらず,epoll を独自に拡張したシステムコールを用いている.実際 には通信に aio 関数群により非同期 I/O を用いている.ただし,通信終了の通知に BSD 系のみで利用でき るイベント通知システムコール kqueue を用いている.非同期 I/O を用いているため,読み込み準備が完 了し,バッファのコピーが終了するまでブロッキングする必要がなく,アプリケーション側の他の処理を同 時に実行できる.そのため,単一プロセッサにおける処理を考えた場合,子プロセスの切り替えのためのコ ンテキストスイッチや,バッファのコピーのためにカーネルとのコンテキストスイッチが発生する Apache の事前 fork 方式と比べて性能が向上している可能性がある.そのため,既存の報告にあるとおり,Nginx は Apacheよりも高い性能を持っている可能性があり,その性能差について現時点の実装で確認する価値はあ ると考えられる.なお,Linux では kqueue は利用できないので,同様な機能が実現できているかは確認で きていない.今後調査を進める際には確認する必要がある.

以下では,Apache と Nginx の性能を比較するため,準備したハードウェアにおいて,Apache,Nginx それ ぞれの最大限の性能を計測する方法について調査する.本研究では,HTTP 性能評価ツールとして httperf を用い,まずは Apache の性能を最大限に出す方法について調査する.

3 Web サーバと性能評価ツール

この章では Apache prefork 及び性能評価ツールについて記す.

(18)

3.1 Apache httpd

3.1 Apache httpd

Apacheには複数のリクエスト処理方式があり MPM(Multi-Proccessing Module) として実装されている.今 回の実験ではデフォルトで指定されている prefork を用いる.prefork では,1つの接続を1つのプロセスが 処理する.また,サーバの起動時にあらかじめ複数の子プロセスを用意する事もできる.すでに全てのプロ セスが処理中の場合,新しい接続の発生時に新たなプロセスを生成して対応する.prefork は apche におい て長く利用されている機能である.

preforkはタイトルにもある通り,事前 fork 設計手法をもちいたもので,そこが Nginx との違いであると 言える.

preforkの設定項目は StartServer, MinSpareServer, MaxSpareServer, MaxClient, MaxRequestPerChild があ る.StartServer でサーバを起動する時に生成するプロセスの数を指定する.MinSpareServer,MaxSpareServer で待機させるプロセス数の最小個数と最大個数を指定する.MaxClient で生成するプロセスの最大数を指定 する.MaxRequestPerChild で個々のプロセスが扱う事のできるリクエストの制限数を指定する,0 とした 場合は無制限の状態を示す.MaxClient の値が最大同時接続数を制御するため,最も影響が大きいと考えら れる.

[select()に代わり kqueue,epoll が実装された事を書く]

3.2 web サーバの性能評価ツール

3.2.1 Apache HTTP server benchmarking tool

Apache HTTP server benchmarking tool(以下 ab と呼ぶ) は Apache をインストールするとデフォルトで 付属する性能評価ツールである.主なコマンドとして-n requests や-c concurrency がある.-n requestsでは性能調査時での生成するリクエスト数の総数を指定する.-c concurrency では一度の 同時リクエスト数を指定する.

使用例は次のようになる. ab使用例

✓ ✏

$ ab -n 1000 -c 100 ’http://hoge.ac.jp/test.html’ This is ApacheBench, Version 2.3 <$Revision: 655654 $>

Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/

ーー 後略 ーー

✒ ✑

使用例では総リクエスト 1000 を 100 ずつ生成し,http://hoge.ac.jp/test.html に対して性能調査を行って いる.

しかし,ab ではコネクション毎のリクエスト数やリクエストの送信間隔の設定などの細かい設定ができ ないようなので,本研究ではより詳細な性能評価ツールを用いる.

(19)

3.3 本研究で調査する内容

3.2.2 httperf

本研究では Web サーバの性能測定に httperf[5]を用いる.httperf では,req/s,同時接続数,conn/s, エラー 数をはじめさまざまな値を計測できる.

本研究では httperf のパラメータとして--wsess 及び--rate を用いた.--wsess=N1,N2,X --rate Yと値を指定する.それぞれ次のような意味をもつ.

N1で対象の web ページへのコネクション数の総数を指定する.N2 で 1 コネクションあたりに要求する リクエスト数を指定する.X で 1 コネクションあたりのリクエスト要求の発生間隔を指定する.Y は 1 秒 あたりに同時に生成するコネクションの数を指定する.

[図を作成し,挿入する]

3.3 本研究で調査する内容

本研究では先に紹介した Apache の prefork についての調査をおこなう.Nginx が注目されたのは,この kqueue,epollを用いて単一スレッドのサーバで実装できたことで高速化がはかれた事にある.しかし現在は Apacheでもこの kqueue,epoll が実装されている.

Nginxと Apache の prefork とでは kqueue,epoll を用いている部分では共通しているが,その用い方に違 いがある.Nginx は 1 プロセス毎に TCP 待ち受けのソケットを用意してそのソケットの監視に用いている. 一方 prefork では複数のプロセスを立ち上げており,それらのどのプロセスに割り当てるかを決定するため に用いている.

[図を作り Nginx と prefork の kqueue,epoll の用い方の違いの説明]

本研究ではその Apache が kqueue,epoll を実装した事でも性能の向上が見られると考え,その実装の仕方 による性能の違いを調べることを目指す.

preforkにける fork の速度を求める.prefork は必要に応じて子プロセスの生成を行うのだが,その速度を 求め必要であれば性能向上を目指す.

また,一つの性能の指標として,一秒あたりのコネクション処理数 (以下 conn/s と呼ぶ) について着目す る.これはコネクションの処理を一秒あたりに平均した値である.

4 Web サーバ及び性能評価ツールの性能チューニング

Webサーバの性能調査を行う際にはその最大性能を求めることが必要である.そのため,Web サーバでど のくらいの性能が出せるかを調べるために Web サーバのチューニングを行う.またその際に性能評価ツー ルについてもチューニングを行った Web サーバに対応できるようにチューニングをする必要がある.

4.1 実験用 Web サーバの立ち上げ

実験を行う際に,まず実験用のサーバを立ち上げる.実験用サーバを立ち上げることで,サーバのポート 番号を新たに指定する事ができるので,計測の際に役に立つだろう.これからその手順を説明する.

Apacheをインストールすると/private/etc/apache2/ができる.この apache2/以下を適当なディ レクトリにコピーする.

(20)

4.1 実験用Webサーバの立ち上げ

実験用サーバを作成

✓ ✏

$ mkdir -p apache2/8000

$ cp -r /private/etc/apache2/ apache2/8000

$ ls apache2/8000

extra httpd.conf magic mime.types original other users

✒ ✑

実験用サーバがコピーできれば,続いてコピーした httpd.conf の編集を行う.httpd.conf ではポート番号 を指定したり,apache を立ち上げる際に読み込む設定ファイルなどが指定されている.

httpd.confの編集

✓ ✏

# Listen 80

Listen 8000  ← port 番号の設定

# error_logを実験用サーバに書き込むようにする

# ErrorLog "/private/var/log/apache2/error_log" ErrorLog "$HOME/apache2/8000/error_log"

# accessを実験用サーバに書き込むようにする

# CustomLog "/private/var/log/apache2/access_log" common CustomLog "$HOME/apache2/8000/access_log" common

# httpd-mpm.confを実験用サーバで編集したものを読み込むようにする

# Include /private/etc/apache2/extra/httpd-mpm.conf Include $HOME/apache2/8000/extra/httpd-mpm.conf

# 最後の行に追記

PidFile "$HOME/apache2/8000/httpd.pid" LockFile "$HOME/apache2/8000/accept.lock"

✒ ✑

httpd.confの編集が完了したらサーバを立ち上げる.サーバの立ち上げる際には実験用に作成した httpd.conf を読み込ませるために-f オプションを用いる.以下に立ち上げる際のコマンドを記す.

サーバの立ち上げ

✓ ✏

$ cd apache2/8000

$ pwd

$HOME/apache2/8000

$ /usr/sbin/httpd -f ‘pwd‘/httpd.conf

✒ ✑

サーバが立ち上がったかを ab を用いて確認する。

(21)

4.1 実験用Webサーバの立ち上げ

4.1.1 サーバの立ち上がりを ab を用いて確認する abを用いた確認

✓ ✏

$ ab localhost:8000/test.html

This is ApacheBench, Version 2.3 <$Revision: 655654 $>

Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking localhost (be patient)...done

Server Software: Apache/2.2.20 Server Hostname: localhost Server Port: 8000

Document Path: /test.html Document Length: 207 bytes

Concurrency Level: 1

Time taken for tests: 0.002 seconds Complete requests: 1

ーー 後略 ーー

✒ ✑

abは性能評価ツールの一つで,値を指定していなければリクエスト要求を一度だけ送る.この結果を見る と Server port: 8000 及び Document path: /test.html となっていることから,ポート 8000 番で test.html に対してテストを行っている事がわかる.また,complete requests が 1 となっている 事からリクエストが完了していることがわかる.

4.1.2 サーバの立ち上がりをブラウザで確認する

テストサイトを作った uri に立ち上げたポート番号でアクセスする.なお,ポート番号の指定は$HOSTNAME のあとに:8000 とすればよい

図17のように立ち上げたポート番号で作成したテストページを閲覧することができれば,サーバが立ち 上がっている事がわかる.

(22)

4.2 Webサーバのチューニング

図 17: ブラウザでのサーバ立ち上がり確認

4.2 Web サーバのチューニング

この節では prefork の性能チューニング事項について記す.

4.2.1 MaxClients

Preforkがデフォルト値の状態で httperf のコネクション数を増加させるとエラーが発生する.

エラーの原因の一つとして,httperf のコネクション数を増やしても Prefork が生成するプロセス数の限界 値がある事が挙げられる.この場合のエラーが発生すると処理されるコネクション数が変わらなくなるの で,結果がふさわしくないものとなってしまう.

そこで,MaxClients を増加させてサーバを立ち上げる.また,5.2節で述べた通り StartServers 及び MaxS- pareServersも MaxClients と同じ値を指定しておく.

StartServers,MaxSpareServers,MaxClientsを 1024 に設定してサーバを立ち上げる. MaxCliets設定時のエラー及びプロセス数

✓ ✏

$ /usr/sbin/httpd -f ‘pwd‘/httpd.conf

WARNING: MaxClients of 1024 exceeds ServerLimit value of 256 servers, lowering MaxClients to 256. To increase, please see the ServerLimit directive.

$ ps aux | grep httpd | wc

-bash: fork: Resource temporarily unavailable

✒ ✑

このようにサーバを立ち上げようとすると,WARNING が表示される.更に立ち上がった httpd を確認す るために ps aux | grep httpd | wc を行ったが.-bash: fork: Resource temporarily unavailableと表示されコマンドが使用できなかった.

この 2 つの原因を調べる.

(23)

4.2 Webサーバのチューニング

4.2.2 ServerLimit

preforkの MaxClients を 256 以上に設定しようとすると,”lowering MaxClients to 256. To increase, please see the serverlimit directiove”というエラーが出力される.MaxClients を 1024 に設定して,サーバを起動さ せると以下のような警告が観測できる.

またそのプロセス数を確認するために別にターミナルを立ち上げておきスーバユーザとなっておく.スー バユーザは$ sudo su とすればよい.

MaxCliets設定時のエラー及びプロセス数

✓ ✏

$ /usr/sbin/httpd -f ‘pwd‘/httpd.conf

WARNING: MaxClients of 1024 exceeds ServerLimit value of 256 servers, lowering MaxClients to 256. To increase, please see the ServerLimit directive.

# ps aux | grep httpd | wc 109 1416 14986

✒ ✑

これは,MaxClients が ServerLimit により制限されているためであることがわかった.これは,MaxClients がメモリの消費過剰になることを防ぐために設定されていて,その初期値が 256 となっている.これらは ダウンロードした httpd ファイルの”/server/mpm/prefork/prefork.c”内に記述されている.

この解消法として,httpd-mpm.conf ファイルに”serverlimit N”を書き込めばよい.N の値まで MaxClients の数を増加させる事ができる.

表 1: httpd-mpm.conf の変更 startserver 1024 startserver 1024 MinSpareServers 1 MinSpareServers 1 MaxSpareServers 1024 → MaxSpareServers 1024 MaxClients 1024 ServerLimit 20000 MaxRequestPerChild 0 MaxClients 1024

MaxRequestPerChild 0

この設定後,サーバを再起動する. ServerLimit設定後のプロセス数

✓ ✏

$ /usr/sbin/httpd -f ‘pwd‘/httpd.conf

# ps aux | grep httpd | wc 113 1468 15538

✒ ✑

この結果を見ると ServerLimit により先ほど観測された WARNING は見られなくなった.しかし値の変更 をしても期待しているプロセス数が生成されていない事がわかった.

(24)

4.2 Webサーバのチューニング

4.2.3 ulimit

現在立ち上がっている全てのプロセス数を ps コマンドで確認したところ,自分のユーザプロセスが ulimit の”max user processes”の値に近いものになっていたた.

ユーザプロセス数確認

✓ ✏

$ ulimit -u 266

# ps aux | grep ’ユーザ名’ | wc 265 3923 63136

✒ ✑

そこで一度”max user processes”の値を低く設定してサーバプロセスの数を調べた.その結果,立ち上がっ たサーバプロセス数が低くなっている事が確認された.そのため,プロセス生成にはこの値で制限がかかっ ていたと考えられる.サーバプロセスを生成する際は”max user processes”の値を考慮する必要がある

4.2.4 ulimitの変更

ulimitの変更は$ ulimit -u N で行う. max user processes変更

✓ ✏

$ ulimit -u 266

$ ulimit -u 532

$ ulimit -u

✒532 ✑

しかし,ここで 533 以上の値を指定しても値が反映されなかった.

その原因を調べたところ ulimit には ulimit にはソフトリミットという値とハードリミットという値が設 定されていることがわかった.ハードリミットはソフトリミットの上限値として働いており,一般ユーザで はハードリミットの値を上げる事ができない.ハードリミットの値を確認するには”ulimit -H -a”と大文字の Hを加える事で確認できる.

”max user processes”の値を確認したところ,532 という値が確認できた.この値のためにそれ以上の値の 変更を行う事ができなかったと考えられる.

ハードリミットの値を上げるためにはスーパユーザで作業を行う必要がある.スーパユーザで値の変更 を行う場合に$ ulimit -u N でハードリミット以上の値が指定された場合はソフトリミットとハードリ ミットのどちらも変更される.

(25)

4.2 Webサーバのチューニング

表 2: ulimit のハードリミットの確認

$ ulimit -H -a

core file size (blocks, -c) unlimited data seg size (kbytes, -d) unlimited file size (blocks, -f) unlimited max locked memory (kbytes, -l) unlimited max memory size (kbytes, -m) unlimited open files (-n) unlimited pipe size (512 bytes, -p) 1 stack size (kbytes, -s) 65532 cpu time (seconds, -t) unlimited max user processes (-u) 532 せ virtual memory (kbytes, -v) unlimited

スーパユーザでの max user processes 変更

✓ ✏

$ sudo su Password:

# ulimit -u 266

# ulimit -u 1024

# ulimit -u

✒532 ✑

しかし,結果を見てもハードリミットを超えて値が反映されなかった.そこでまた別の制限が発生してい ると考え調査する事にした.

なお ulimit については,再度 Terminal を開いた際には値を設定し直す必要がある.

4.2.5 sysctl

#sysctl ulimitの値を変更できないときは sysctl による制限がかかっている可能性がある.sysctl ではカー ネルの設定を閲覧したり設定したりする事ができる.

sysctlでも ulimit の max user processes と同じような制限があることがわかった.kern.maxproc と

kern.maxprocperuidというものがあり,それぞれデフォルトでは kern.maxproc = 532 及び kern.maxproperuid

= 266が設定されていた.

ここで,kern.maxproc の値を見ると4.2.4節で問題となっていた,532 という値と同じ値になっている事 がわかる.この値を変更して ulimit の変更を試みる.sysctl の変更は$ sysctl -w ’ 変数’=N で変更す る事ができる.

(26)

4.2 Webサーバのチューニング

sysctl及び ulimit の変更

✓ ✏

$ sudo sysctl -w kern.maxproc=1024 kern.maxproc: 266 -> 1024

sh-3.2# ulimit -u 1024 sh-3.2# ulimit -u

✒1024 ✑

このように kern.maxproc を変更する事で,max user processes の値を変更する事が可能となった. また,kern.maxprocperuid はユーザ毎に制限されているプロセス数のため,こちらも値を定めておく. sysctlは/etc/sysctl.conf を作成しておく事で,terminal 起動時にこれに書かれている値を読み込む ため毎回設定する手間を省く事もできる.

sysctl.conf

✓ ✏

kern.maxproc=2500

kern.maxprocperuid=2500

✒ ✑

4.2.6 制限解除のまとめ

サーバのプロセス数増加に関する制限をまとめる.プロセスを 2400 立ち上げる.MaxClients の値を 2400 に設定して以下の手順で値を設定していけばよい.

プロセス制限の解除

✓ ✏

sh-3.2# sysctl -w kern.maxproc=2500 kern.maxproc: 1024 -> 2500

sh-3.2# sysctl -w kern.maxprocperuid=2500 kern.maxprocperuid: 266 -> 2500

sh-3.2# ulimit -u 2500 sh-3.2# ulimit -u 2500

sh-3.2# pwd

$HOME/apache2/8000

sh-3.2# /usr/sbin/httpd -f ‘pwd‘/httpd.conf sh-3.2# ps aux | grep httpd | wc

2402 31225 321816

✒ ✑

これで,プロセスが 2400 立ち上がっていることの確認ができた.なお,kern.maxproc の値を 2501 以上 に設定すると,sysctl: kern.maxproc: Invalid argument と表示され値が反映されなかった.

(27)

4.3 性能評価ツール

4.2.7 Macのプロセス数制限

kern.maxprocの値が 2500 を超えて設定できない問題を調べたところ,Mac のサポートページで プロセス数制限について書かれているものを見つけた.http://support.apple.com/kb/HT3854? viewlocale=ja JP

ここによるとメモリが 8GB の場合,最大プロセス数が 2500 に制限されている事が書かれていた.その ため MacOSX を用いた場合はここで書かれた値までしか増やす事ができないと考えられる.

4.3 性能評価ツール

この節では性能評価ツールである httperf のチューニング方法を記す.

4.3.1 Segmentation faultの原因

MacOSXで httperf を使用して,値の指定をしていくとすぐにエラーとなってしまう. httperfの Segmentation エラー

✓ ✏

$ httperf -v --wsess=100,2,1 --rate 100 \

--uri akimac05.cse.kyoto-su.ac.jp/test.html --port 8000

httperf --verbose --client=0/1 --server=localhost --port=8000 \ --uri=akimac05.cse.kyoto-su.ac.jp/test.html --rate=100 \ --send-buffer=4096 --recv-buffer=16384 --wsess=100,2,1.000 httperf: warning: open file limit > FD_SETSIZE; limiting max. \

# of open files to FD_SETSIZE

httperf: maximum number of open descriptors = 1024 Segmentation fault

✒ ✑

このように Segmentation fault となり処理が行われない.この原因を gdb を用いて調べたところ,src/core.c に問題があることがわかった.

gdbで発見した core.c の問題の箇所からソースをたどっていくと,1258 行目の変数の型が mask = ((u long) mask) >> 1;となっていた.このエラーは mask が 32bit になっているが,64bit である u long に値を投 げているために値がおかしくなり発生している.

core.cの変更

✓ ✏

#mask = ((u\_long) mask) >> 1; mask = ((u\_int32\_t) mask) >> 1;

✒ ✑

とするとこのエラーは見られなくなる.設定を変更した後は,make 及び make install を行い再コン パイルする.

(28)

4.3 性能評価ツール

httperfの Segmentation fault が見られなくなる

✓ ✏

$ httperf -v --wsess=100,2,1 --rate 100 \

--uri akimac05.cse.kyoto-su.ac.jp/test.html --port 8000 httperf --verbose --client=0/1 --server=localhost --port=8000 \

--uri=akimac05.cse.kyoto-su.ac.jp/test.html --rate=100 \ --send-buffer=4096 --recv-buffer=16384 --wsess=100,2,1.000 httperf: warning: open file limit > FD_SETSIZE; limiting max. \

# of open files to FD_SETSIZE

httperf: maximum number of open descriptors = 1024 Maximum connect burst length: 1

Total: connections 200 requests 300 replies 200 test-duration 1.993 s ーー 後略 ーー

✒ ✑

このように同じ値を指定しても Segmentation fault が見られなくなった.

4.3.2 FD SETSIZE

#define FD SETSIZEの変更 httperf を使用する際に引数に-v を指定すると,httperf: maximum number of open descriptors = 1024という出力が見られる.httperf で値を指定する際にこの値が制限とな るため,変更を行う.

この値を変更するためには config.h 内に以下の記述を追加する. config.h内に追加記述

✓ ✏

#define FD_SETSIZE 65536

#define _DARWIN_UNLIMITED_SELECT

✒ ✑

追加記述が完了したら再コンパイルを行い,httperf を使用する.

(29)

4.3 性能評価ツール

FD SETSIZEの値が反映されているか確認

✓ ✏

$ httperf -v --wsess=100,2,1 --rate 100 --uri akimac05.cse.kyoto-su.ac.jp httperf --verbose --client=0/1 --server=localhost --port=80 \

--uri=akimac05.cse.kyoto-su.ac.jp --rate=100 --send-buffer=4096 \ --recv-buffer=16384 --wsess=100,2,1.000

httperf: warning: open file limit > FD_SETSIZE; limiting max. \

# of open files to FD_SETSIZE

httperf: maximum number of open descriptors = 65536 Maximum connect burst length: 1

ーー 後略 ーー

✒ ✑

この出力から,httperf: maximum number of open descriptors = 65536 となっており, 設定した値が反映されている事がわかる.これで httperf の設定は完了である.

表 2: ulimit のハードリミットの確認 $ ulimit -H -a
図 18 , 図 19 から,StartServers が 10 の時に CPU 使用率が少ない事が見られるが StartServers が 150 の時
図 22: 一秒毎の fork 数 この図 22 は httperf のパラメータを変化させても同じようになった.
図 23: デフォルトでのクライアントの CPU 使用率 図 24: デフォルトでの Web サーバの CPU 使用率 この図 23 ,図 24 を見ると明らかに Web サーバ側の CPU 使用率に余裕がある事がわかる.ここからクラ
+2

参照

関連したドキュメント

 基本波を用いる近似はピクセル単位の時間放射能曲線に対しては用いることができる

 本研究所は、いくつかの出版活動を行っている。「Publications of RIMS」

サーバー費用は、Amazon Web Services, Inc.が提供しているAmazon Web Servicesのサーバー利用料とな

これはつまり十進法ではなく、一進法を用いて自然数を表記するということである。とは いえ数が大きくなると見にくくなるので、.. 0, 1,

ているかというと、別のゴミ山を求めて居場所を変えるか、もしくは、路上に

自閉症の人達は、「~かもしれ ない 」という予測を立てて行動 することが難しく、これから起 こる事も予測出来ず 不安で混乱

(自分で感じられ得る[もの])という用例は注目に値する(脚注 24 ).接頭辞の sam は「正しい」と

・私は小さい頃は人見知りの激しい子どもでした。しかし、当時の担任の先生が遊びを