Mercurial > hg > Papers > 2014 > toma-master
changeset 35:ec3488a9ddd4
fix
author | Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Mon, 03 Feb 2014 17:24:15 +0900 |
parents | 345eacdf29e4 |
children | 8a998d8c391d |
files | paper/appendix1.tex paper/chapter2.tex paper/chapter3.tex paper/chapter4.tex paper/introduciton.tex paper/master_paper.pdf |
diffstat | 6 files changed, 165 insertions(+), 7 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/paper/appendix1.tex Mon Feb 03 17:24:15 2014 +0900 @@ -0,0 +1,155 @@ +\clearpage +\addcontentsline{toc}{chapter}{付録} +\appendix +\def\thesection{付録\Alph{section}} +\section{計測環境の構築} +ウェブアプリケーションのベンチマークを行う際、サーバの設定に注意を払う必要がある。 +適切に設定を行わないと、サーバがボトルネックとなってしまい正しい結果が得られない。 +ウェブアプリケーションのベンチマークを行う際の注意点について述べる。 + +データを受信したり送信したりするのは OS カーネルである。 +多くの TCP パケットを要求し、各パケットのサイズが1500バイトといった大きなファイルを提供する場合、 +ウェブアプリケーションというよりOSカーネルのテストになってしまう。 + +接続には、HTTP Keep-Alivesを利用する。 +新しい TCP 接続を確立するのはとても遅く、OS カーネルによって行われる。 +毎秒多くの新しい接続を作成するようなベンチマークを行うと、OSカーネルのテストとなってしまう。 + +アプリケーションやOSカーネルが完全にハードウェアを使用できるようにするためにいくつか調整を行う必要がある。 +最初の問題は、ファイル記述子の欠如である。 +デフォルトはプロセスあたり、1,024 files で非常に貧弱な結果しか得られない。 +ファイル記述子の現在のリミットは以下のコマンドで取得できる。 + +\begin{lstlisting}[caption=ファイル記述子のリミットの取得] +$ ulimit -aH +\end{lstlisting} + +リミットを変更するには、以下のコマンドを実行する。 + +\begin{lstlisting}[caption=ファイル記述子のリミットの設定] +$ sudo sh -c ulimit -HSn 200000 +\end{lstlisting} + +再起動後も有効にするためには、システムファイルの編集を行う。 + +/etc/security/limits.conf へ以下の記述を追加する。 + +\begin{lstlisting}[caption=リミットの設定の追加] + * soft nofile 200000 + * hard nofile 200000 +\end{lstlisting} + +次に問題となるのは listenキューの制限である。 +listen キューとは、保留中のコネクションが繋がれるキューのことである。 +このキューの長さの制限が小さいと、同時にたくさんのコネクション要求がきた場合、制限を超えた要求を拒否する。 +listen キューや、その他の設定も含めてベンチマーク用にサーバの設定を変更する。 + +/etc/sysctl.conf に以下の記述を追加する。 + +\begin{lstlisting}[caption=システム設定の変更] +fs.file-max = 5000000 +net.core.netdev_max_backlog = 400000 +net.core.optmem_max = 10000000 +net.core.rmem_default = 10000000 +net.core.rmem_max = 10000000 +net.core.somaxconn = 100000 +net.core.wmem_default = 10000000 +net.core.wmem_max = 10000000 +net.ipv4.conf.all.rp_filter = 1 +net.ipv4.conf.default.rp_filter = 1 +net.ipv4.ip_local_port_range = 1024 65535 +net.ipv4.tcp_congestion_control = bic +net.ipv4.tcp_ecn = 0 +net.ipv4.tcp_max_syn_backlog = 12000 +net.ipv4.tcp_max_tw_buckets = 2000000 +net.ipv4.tcp_mem = 30000000 30000000 30000000 +net.ipv4.tcp_rmem = 30000000 30000000 30000000 +net.ipv4.tcp_sack = 1 +net.ipv4.tcp_syncookies = 0 +net.ipv4.tcp_timestamps = 1 +net.ipv4.tcp_wmem = 30000000 30000000 30000000 +net.ipv4.tcp_tw_reuse = 1 +net.ipv4.tcp_tw_recycle = 1 +\end{lstlisting} + +ファイルを保存後、設定を反映させるには以下のコマンドを実行する。 + +\begin{lstlisting}[caption=設定の反映] +$ sudo sysctl -p /etc/sysctl.conf +\end{lstlisting} + +ベンチマークを行う際、小さなテストでは妥当性が低くなってしまうので注意する。 +TCP/IPのスタックは保守的な方法で動作し、ダウンロード速度に合わせて徐々に速度を増大させるためである。 + +また、テストするサーバより遅いベンチマーククライアントを用いると正しい結果は得られない。 +シングルスレッドで稼働したり、Ruby や Python といった低速なベンチマークツールでテストを行うと、 +すべてのテストする対象が同じようなパフォーマンスを持っているように見えてしまう。 + +\subsubsection{weighttp} +ウェブアプリケーションの性能測定には、weighttpを用いる。 +weighttpはWebサーバの性能測定ツールで、マルチコアCPUを使ってテストできる\cite{weighttp}。 +また、livev を使うことで、モダンなポール・システムコールを利用し、測定性能を向上できるといった特徴を持つ。 +同様の性能測定ツールには、Apache Benchやhttprefが存在するが非力であり、ボトルネックとなってしまうため使用しない。 + +weighttp を起動するには、以下の様にコマンドを入力する。 +\begin{lstlisting}[caption=weighttpの起動] +$ weighttp -n 1000000 -c 1000 -t 10 -k "http://bldsv12.cr.ie.u-ryukyu.ac.jp:3000" +\end{lstlisting} + +起動時には対象のサーバの URL を記述する他に、いくつかのオプションを指定できる。 +\begin{itemize} + \item n ... HTTP リクエストの総数 + \item c ... 同時に接続するコネクションの数 + \item t ... 作製するネイティブスレッドの数 + \item k ... HTTP Keep-Alives を有効にする +\end{itemize} + +\clearpage + +\section{Warp を用いたウェブアプリケーションの構築} +Warp は、軽量・高速な HTTP サーバである\cite{warp}。 +Haskell の軽量スレッドを活かして書かれている。 +Haskell のウェブフレームワークである Yesod のバックエンドとして用いられており、現在も開発が続けられている。 + +Warp を用いてウェブアプリケーションを構築する方法について説明する。 + +% Source Codeは実行可能な状態でsrcに置いてある +% firstline, lastlineで、どの範囲を表示するか指定できる +\lstinputlisting[label=warp_sample, caption=Warpを用いたウェブアプリケーションの例, firstline=9]{src/warp.hs} + +ソースコード \ref{warp_sample}は、URLによって出力する結果を変更するウェブアプリケーションである。 +/hello/worldへアクセスがあった場合は、インクリメントされる counter が表示される。 + +\paragraph*{main} +HTTP サーバを起動するには、Warp の run 関数を利用する。 +run 関数は、利用する Port 番号と、application というリクエストを受けて何かしらのレスポンスを返す関数の2つを引数として受け取る。 + +関数型言語では、関数を第一級オブジェクトとして扱える。 +また、今回は Haskell のカリー化された関数の特性を利用し、main 内で作成した IORef 型の counter を部分適用させている。 + +IORef を用いることで、Haskell で更新可能な変数を扱うことができる。 +参照透過性を失うようにみえるが、Haskell は IO モナドを利用することで純粋性を保っている。 +IORef 自体が入出力を行うわけではなく、単なる入出力操作の指示にすぎない。 +IO モナドとして糊付けされた単一のアクションに main という名前を付けて実行することで処理系が入出力処理を行う。 + +\paragraph*{application 及び routes , findRoute} +application の実装では、routes という関数を独自に定義して、URL によって出力を変更している。 +application に渡されるリクエストはデータ型で様々な情報が含まれている。 +その中のひとつに pathInfo という、URL から hostname/port と、クエリを取り除いたリストがある。 +この情報を routes という関数に渡すことで、routeSetting というリストから一致する URL がないか調べる。 +routeSetting は、URL のリストとレスポンスを返す関数のタプルのリストである。 + +\paragraph*{notFound 及び hello} +レスポンスを返す関数は、いくつか定義されている。 +その中で利用されている responseLBS は文字列からレスポンスを構築するためのコンストラクタである。 + +\paragraph*{world 及び incCount} +world は、インクリメントされる counter を表示するための関数である。 +IORef 内のデータは直接触ることができないため、incCount 内で atomicModifyIORef を利用してデータの更新を行なっている。 +atomicModifyIORef は、データの更新をスレッドセーフに行うことができる。 +また、responseLBSで構築したレスポンスは、Resource Tというリーソスの解放を安全に行うために使われるモナドに包まれている。 +lift 関数を用いて、incCountの型を持ち上げ調整している。 + + +プログラムを例にして説明したが、Warp は容易にプログラムに組み込むことができる。 +本研究では、非破壊的木構造データベース Jungle と Warp を組み合わせて、掲示板ウェブアプリケーションを開発した。
--- a/paper/chapter2.tex Mon Feb 03 16:54:48 2014 +0900 +++ b/paper/chapter2.tex Mon Feb 03 17:24:15 2014 +0900 @@ -1,6 +1,6 @@ \chapter{Haskellによる並列データベースの設計}\label{ch:design} -\section{マルチプロセッサで十分な性能を得るためには} +\section{マルチコアプロセッサで十分な性能を得るためには} 現在、CPU はマルチコア化が進んでいる。 マルチコアプロセッサで線形に性能向上をするためには、処理全体で高い並列度を保たなければならない\cite{amdahl}。 % ウェブサービスでは、ニーズの変化に柔軟に対応できる能力が求められる。
--- a/paper/chapter3.tex Mon Feb 03 16:54:48 2014 +0900 +++ b/paper/chapter3.tex Mon Feb 03 17:24:15 2014 +0900 @@ -24,6 +24,8 @@ Jungle は複数の Tree の集まりである。Jungle と木構造の名前を利用して最新のルートノードを取得することができる。 Node は子と属性を任意の数持てる。 +データ型として定義することで、データ内部の整合性が保たれ、また型検査でエラーがないか検出することができる。 + \begin{table}[!htbp] \caption{内部のデータ型} \label{tab:components} @@ -39,6 +41,7 @@ \end{center} \end{table} + \newpage \subsubsection{Jungle と木の作成} @@ -70,6 +73,7 @@ createTree jungle "name of new tree here" \end{lstlisting} +\newpage \subsubsection{ルートノード} 非破壊的木構造データベース Jungle では、木の最新の状態を更新・参照するのにルートノードを使う。 ルートノードは、最新の木構造の根がどれかの情報を保持している(図\ref{fig:getrootnode})。 @@ -108,6 +112,7 @@ updateRootNode jungle "your tree name here" node \end{lstlisting} +\newpage updateRootNodeWithは、ノードを更新する関数とデータベース、木の名前を渡して利用する。 ノードを更新する関数とは、ノードを受け取ってノードを返す関数である。 このupdateRootNodeWithを利用することで、getRootNodeをした後、編集しupdateRootNodeを行う一連の操作がatomicallyに行われることが保証される。 @@ -207,7 +212,6 @@ nodelist = assocsChildren node [1,2] \end{lstlisting} - あるNodeに存在する全ての属性に対して、参照を行いたい場合に利用する。 assocsAttribute は、対象の Node が持つ全ての属性を、Key と Value のタプルとし、そのタプルのリストを返す。
--- a/paper/chapter4.tex Mon Feb 03 16:54:48 2014 +0900 +++ b/paper/chapter4.tex Mon Feb 03 17:24:15 2014 +0900 @@ -34,7 +34,7 @@ Haskell および Java のバージョンを表\ref{tab:compiler}に示す。 -\begin{table}[!htbp] +\begin{table}[!ht] \caption{ベンチマークで利用したHaskellとJavaのバージョン} \label{tab:compiler} \begin{center} @@ -164,7 +164,7 @@ \clearpage \section{ウェブアプリケーションに組み込んでの性能評価} -実用的なウェブアプリケーションに組み込んで、妥当な性能が出ているか調査を行う。 +実用的なウェブアプリケーションに組み込んで、妥当な性能が出るか調査を行う。 \subsection{掲示板ウェブアプリケーションの実装} 木構造データベース Jungle と Haskell の HTTP サーバ Warp を用いて掲示板ウェブアプリケーションを開発する。 @@ -257,7 +257,6 @@ 並列で実行した場合、実行時間が短くなっているが性能向上率が低いことが分かる。 これも HTTP サーバ Warp がボトルネックとなってしまっているためだと考えられる。 -\newpage \begin{table}[!htbp] \caption{掲示板を利用した書き込みの計測結果} \label{tab:bbs_write}
--- a/paper/introduciton.tex Mon Feb 03 16:54:48 2014 +0900 +++ b/paper/introduciton.tex Mon Feb 03 17:24:15 2014 +0900 @@ -13,9 +13,9 @@ データベースの実装には、純粋関数型言語 Haskell を用いる。 Haskell は、モダンな型システムを持ち、型推論と型安全により簡潔で信頼性の高いプログラムを書くことが可能である\cite{types}。 -データベースのやり取りするデータにも型が付くため、セキュリティホールを突くような攻撃の多くが無害化される。 +データベースのやり取りするデータにも型が付くため、セキュリティホールを突くような攻撃の多くが無害化される効果が期待できる。 また、Haskellは純粋であるため、関数は引数が同じならば必ず同じ値を返すことが保証されている。 これは、並列処理において並列化に適した部分が分かりやすくなるというメリットがあり、また状態に依存したバグから解放されることも意味する。 -本論文では、Haskellを用いて非破壊的木構造データベースを実装し、読み込みに関して高い並列化率を達成することができ、マルチコアプロセッサの性能を引き出すことができた。 +本論文では、Haskellを用いて非破壊的木構造データベースを実装し、読み込みに関して 98.96 \% という高い並列化率を達成することができ、マルチコアプロセッサの性能を引き出すことができた。 また、掲示板ウェブアプリケーションを開発し、既存の Java の非破壊的木構造データベースとの比較をおこない、Java のおよそ 2倍の性能を確認することができた。