Mercurial > hg > Papers > 2014 > toma-master
annotate paper/appendix1.tex @ 71:98a55a935619
describe slides without rpar
author | Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Thu, 13 Feb 2014 13:02:59 +0900 |
parents | 0644825c43ac |
children | 56e65e2b01c6 |
rev | line source |
---|---|
35 | 1 \clearpage |
2 \addcontentsline{toc}{chapter}{付録} | |
3 \appendix | |
4 \def\thesection{付録\Alph{section}} | |
5 \section{計測環境の構築} | |
47 | 6 ウェブアプリケーションのベンチマークを行う際, サーバの設定に注意を払う必要がある. |
7 適切に設定を行わないと, サーバがボトルネックとなってしまい正しい結果が得られない. | |
8 ウェブアプリケーションのベンチマークを行う際の注意点について述べる. | |
35 | 9 |
47 | 10 データを受信したり送信したりするのは OS カーネルである. |
11 多くの TCP パケットを要求し, 各パケットのサイズが1500バイトといった大きなファイルを提供する場合, | |
12 ウェブアプリケーションというよりOSカーネルのテストになってしまう. | |
35 | 13 |
47 | 14 接続には, HTTP Keep-Alivesを利用する. |
15 新しい TCP 接続を確立するのはとても遅く, OS カーネルによって行われる. | |
49 | 16 毎秒多くの新しい接続を作成するベンチマークを行うと, OSカーネルのテストとなってしまう. |
35 | 17 |
47 | 18 アプリケーションやOSカーネルが完全にハードウェアを使用できるようにするためにいくつか調整を行う必要がある. |
19 最初の問題は, ファイル記述子の欠如である. | |
20 デフォルトはプロセスあたり, 1,024 files で非常に貧弱な結果しか得られない. | |
58
7403d5ee2c92
describe the benchmark
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents:
49
diff
changeset
|
21 ファイル記述子の現在のリミットはソースコード\ref{ulimit} のコマンド取得できる. |
35 | 22 |
58
7403d5ee2c92
describe the benchmark
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents:
49
diff
changeset
|
23 \begin{lstlisting}[label=ulimit, caption=ファイル記述子のリミットの取得] |
35 | 24 $ ulimit -aH |
25 \end{lstlisting} | |
26 | |
58
7403d5ee2c92
describe the benchmark
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents:
49
diff
changeset
|
27 リミットを変更するには, ソースコード\ref{ulimit2} のコマンドを実行する. |
35 | 28 |
58
7403d5ee2c92
describe the benchmark
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents:
49
diff
changeset
|
29 \begin{lstlisting}[label=ulimit2, caption=ファイル記述子のリミットの設定] |
35 | 30 $ sudo sh -c ulimit -HSn 200000 |
31 \end{lstlisting} | |
32 | |
47 | 33 再起動後も有効にするためには, システムファイルの編集を行う. |
35 | 34 |
59
0644825c43ac
add ghc 7.6.3 benchmark
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents:
58
diff
changeset
|
35 /etc/security/limits.conf へソースコード\ref{limit}の記述を追加する. |
35 | 36 |
59
0644825c43ac
add ghc 7.6.3 benchmark
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents:
58
diff
changeset
|
37 \begin{lstlisting}[label=limit, caption=リミットの設定の追加] |
35 | 38 * soft nofile 200000 |
39 * hard nofile 200000 | |
40 \end{lstlisting} | |
41 | |
47 | 42 次に問題となるのは listenキューの制限である. |
43 listen キューとは, 保留中のコネクションが繋がれるキューのことである. | |
44 このキューの長さの制限が小さいと, 同時にたくさんのコネクション要求がきた場合, 制限を超えた要求を拒否する. | |
45 listen キューや, その他の設定も含めてベンチマーク用にサーバの設定を変更する. | |
35 | 46 |
59
0644825c43ac
add ghc 7.6.3 benchmark
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents:
58
diff
changeset
|
47 /etc/sysctl.conf にソースコード\ref{sysctl}の記述を追加する. |
35 | 48 |
59
0644825c43ac
add ghc 7.6.3 benchmark
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents:
58
diff
changeset
|
49 \newpage |
0644825c43ac
add ghc 7.6.3 benchmark
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents:
58
diff
changeset
|
50 \begin{lstlisting}[label=sysctl, caption=システム設定の変更] |
35 | 51 fs.file-max = 5000000 |
52 net.core.netdev_max_backlog = 400000 | |
53 net.core.optmem_max = 10000000 | |
54 net.core.rmem_default = 10000000 | |
55 net.core.rmem_max = 10000000 | |
56 net.core.somaxconn = 100000 | |
57 net.core.wmem_default = 10000000 | |
58 net.core.wmem_max = 10000000 | |
59 net.ipv4.conf.all.rp_filter = 1 | |
60 net.ipv4.conf.default.rp_filter = 1 | |
61 net.ipv4.ip_local_port_range = 1024 65535 | |
62 net.ipv4.tcp_congestion_control = bic | |
63 net.ipv4.tcp_ecn = 0 | |
64 net.ipv4.tcp_max_syn_backlog = 12000 | |
65 net.ipv4.tcp_max_tw_buckets = 2000000 | |
66 net.ipv4.tcp_mem = 30000000 30000000 30000000 | |
67 net.ipv4.tcp_rmem = 30000000 30000000 30000000 | |
68 net.ipv4.tcp_sack = 1 | |
69 net.ipv4.tcp_syncookies = 0 | |
70 net.ipv4.tcp_timestamps = 1 | |
71 net.ipv4.tcp_wmem = 30000000 30000000 30000000 | |
72 net.ipv4.tcp_tw_reuse = 1 | |
73 net.ipv4.tcp_tw_recycle = 1 | |
74 \end{lstlisting} | |
75 | |
59
0644825c43ac
add ghc 7.6.3 benchmark
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents:
58
diff
changeset
|
76 ファイルを保存後, 設定を反映させるにはソースコード\ref{sysctl2}のコマンドを実行する. |
35 | 77 |
59
0644825c43ac
add ghc 7.6.3 benchmark
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents:
58
diff
changeset
|
78 \begin{lstlisting}[label=sysctl2, caption=設定の反映] |
35 | 79 $ sudo sysctl -p /etc/sysctl.conf |
80 \end{lstlisting} | |
81 | |
47 | 82 ベンチマークを行う際, 小さなテストでは妥当性が低くなってしまうので注意する. |
83 TCP/IPのスタックは保守的な方法で動作し, ダウンロード速度に合わせて徐々に速度を増大させるためである. | |
35 | 84 |
47 | 85 また, テストするサーバより遅いベンチマーククライアントを用いると正しい結果は得られない. |
86 シングルスレッドで稼働したり, Ruby や Python といった低速なベンチマークツールでテストを行うと, | |
49 | 87 すべてのテストする対象が同じパフォーマンスを持っているように見えてしまう. |
35 | 88 |
89 \subsubsection{weighttp} | |
47 | 90 ウェブアプリケーションの性能測定には, weighttpを用いる. |
91 weighttpはWebサーバの性能測定ツールで, マルチコアCPUを使ってテストできる\cite{weighttp}. | |
92 また, livev を使うことで, モダンなポール・システムコールを利用し, 測定性能を向上できるといった特徴を持つ. | |
93 同様の性能測定ツールには, Apache Benchやhttprefが存在するが非力であり, ボトルネックとなってしまうため使用しない. | |
35 | 94 |
59
0644825c43ac
add ghc 7.6.3 benchmark
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents:
58
diff
changeset
|
95 weighttp を起動するには, ソースコード\ref{weighttp}のコマンドを入力する. |
0644825c43ac
add ghc 7.6.3 benchmark
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents:
58
diff
changeset
|
96 \begin{lstlisting}[label=weighttp, caption=weighttpの起動] |
35 | 97 $ weighttp -n 1000000 -c 1000 -t 10 -k "http://bldsv12.cr.ie.u-ryukyu.ac.jp:3000" |
98 \end{lstlisting} | |
99 | |
47 | 100 起動時には対象のサーバの URL を記述する他に, いくつかのオプションを指定できる. |
35 | 101 \begin{itemize} |
102 \item n ... HTTP リクエストの総数 | |
103 \item c ... 同時に接続するコネクションの数 | |
104 \item t ... 作製するネイティブスレッドの数 | |
105 \item k ... HTTP Keep-Alives を有効にする | |
106 \end{itemize} | |
107 | |
108 \clearpage | |
109 | |
110 \section{Warp を用いたウェブアプリケーションの構築} | |
47 | 111 Warp は, 軽量・高速な HTTP サーバである\cite{warp}. |
112 Haskell の軽量スレッドを活かして書かれている. | |
113 Haskell のウェブフレームワークである Yesod のバックエンドとして用いられており, 現在も開発が続けられている. | |
35 | 114 |
47 | 115 Warp を用いてウェブアプリケーションを構築する方法について説明する. |
35 | 116 |
117 % Source Codeは実行可能な状態でsrcに置いてある | |
47 | 118 % firstline, lastlineで, どの範囲を表示するか指定できる |
35 | 119 \lstinputlisting[label=warp_sample, caption=Warpを用いたウェブアプリケーションの例, firstline=9]{src/warp.hs} |
120 | |
47 | 121 ソースコード \ref{warp_sample}は, URLによって出力する結果を変更するウェブアプリケーションである. |
122 /hello/worldへアクセスがあった場合は, インクリメントされる counter が表示される. | |
35 | 123 |
124 \paragraph*{main} | |
47 | 125 HTTP サーバを起動するには, Warp の run 関数を利用する. |
126 run 関数は, 利用する Port 番号と, application というリクエストを受けて何かしらのレスポンスを返す関数の2つを引数として受け取る. | |
35 | 127 |
47 | 128 関数型言語では, 関数を第一級オブジェクトとして扱える. |
129 また, 今回は Haskell のカリー化された関数の特性を利用し, main 内で作成した IORef 型の counter を部分適用させている. | |
35 | 130 |
47 | 131 IORef を用いることで, Haskell で更新可能な変数を扱うことができる. |
132 参照透過性を失うようにみえるが, Haskell は IO モナドを利用することで純粋性を保っている. | |
133 IORef 自体が入出力を行うわけではなく, 単なる入出力操作の指示にすぎない. | |
134 IO モナドとして糊付けされた単一のアクションに main という名前を付けて実行することで処理系が入出力処理を行う. | |
35 | 135 |
136 \paragraph*{application 及び routes , findRoute} | |
47 | 137 application の実装では, routes という関数を独自に定義して, URL によって出力を変更している. |
138 application に渡されるリクエストはデータ型で様々な情報が含まれている. | |
139 その中のひとつに pathInfo という, URL から hostname/port と, クエリを取り除いたリストがある. | |
140 この情報を routes という関数に渡すことで, routeSetting というリストから一致する URL がないか調べる. | |
141 routeSetting は, URL のリストとレスポンスを返す関数のタプルのリストである. | |
35 | 142 |
143 \paragraph*{notFound 及び hello} | |
47 | 144 レスポンスを返す関数は, いくつか定義されている. |
145 その中で利用されている responseLBS は文字列からレスポンスを構築するためのコンストラクタである. | |
35 | 146 |
147 \paragraph*{world 及び incCount} | |
47 | 148 world は, インクリメントされる counter を表示するための関数である. |
149 IORef 内のデータは直接触ることができないため, incCount 内で atomicModifyIORef を利用してデータの更新を行なっている. | |
150 atomicModifyIORef は, データの更新をスレッドセーフに行うことができる. | |
151 また, responseLBSで構築したレスポンスは, Resource Tというリーソスの解放を安全に行うために使われるモナドに包まれている. | |
152 lift 関数を用いて, incCountの型を持ち上げ調整している. | |
35 | 153 |
154 | |
47 | 155 プログラムを例にして説明したが, Warp は容易にプログラムに組み込むことができる. |
156 本研究では, 非破壊的木構造データベース Jungle と Warp を組み合わせて, 掲示板ウェブアプリケーションを開発した. |