Mercurial > hg > Papers > 2014 > nobuyasu-master
diff paper/chapter4.tex @ 50:faa708c2958b
Added log
author | Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 31 Jan 2014 17:13:59 +0900 |
parents | c63aaa629330 |
children | c5c761588168 |
line wrap: on
line diff
--- a/paper/chapter4.tex Fri Jan 31 11:19:32 2014 +0900 +++ b/paper/chapter4.tex Fri Jan 31 17:13:59 2014 +0900 @@ -1,214 +1,335 @@ -\chapter{分散木構造データーベース Jungle の評価} -前章では Jungle における分散データベースの詳細な実装について述べた. -本章では実装を行った Jungle に対して Cassandra との性能比較を行い評価をする. -性能比較の為に簡易な掲示板プログラムを Jungle と Cassandra それぞれに作成した. -複数のノードに繋がっている状態においても性能を測りたいため, 学科提供する -VMWare の並列環境を利用する. また, 我々の研究室が利用しているブレードサーバ -上で動いている KVM もノードとして利用する. +\chapter{木構造データベースJungleの分散実装} +本章では Jungle に行った分散実装について述べる. +前章では Jungle のアーキテクチャと分散設計について説明した. +トポロジーの形成と他サーバノードのデータのアクセス方法には Alice を使用する. +また, Jungle ではデータ編集のログとして TreeOperationLog がある. +この TreeOperationLog を Alice により他サーバノードへ送ることでデータの分散を行う. + +\section{Alice のトポロジーマネージャーの利用} + +\subsection{トポロジーマネージャーの起動} +Alice を用いてサーバノードでトポロジーの形成を行う方法を述べる. +Alice のトポロジーマネージャーの起動は\ref{src:alice_dot}の様に行う. +(\ref{src:alice_ntm_run}). +\begin{lstlisting}[frame=lrbt,label=src:alice_ntm_run,caption=Alice によるネットワークトポロジーマネージャーの起動,numbers=left] +% java -cp Alice.jar alice.topology.manager.TopologyManager -p 10000 -conf ./topology/tree5.dot +\end{lstlisting} +-p オプションはトポロジーマネージャーが開くポートの番号, -conf オプションには dot ファイルのパスを渡す. + +ポート番号は Alice により記述された並列分散プログラムの起動時に渡す必要がある. +dot ファイルには, トポロジーをどのように形成するかが書かれている. +以下に, サーバノード数5で, 2分木ツリー構造を形成する dot ファイルの例を示す(\ref{src:alice_dot}). +\begin{lstlisting}[frame=lrbt,label=src:alice_dot,caption=ネットワークトポロジー設定用 dot ファイル,numbers=left] +% cat tree5.dot +digraph test { + node0 -> node1 [label="child1"] + node0 -> node2 [label="child2"] + node1 -> node0 [label="parent"] + node1 -> node3 [label="child1"] + node1 -> node4 [label="child2"] + node2 -> node0 [label="parent"] + node3 -> node1 [label="parent"] + node4 -> node1 [label="parent"] +} +\end{lstlisting} + +node0 や node1 はサーバノードの名前を示す. +サーバノードの間にはラベルがあり, Alice 上ではこのラベル +に指定される文字列(キー)を使うことで他のサーバノードのデータへアクセスすることができる. +node0 -> node1 はサーバノード同士の繋がりを示している. +次に続く label="child1" は, node0 が node1 のデータに"child1"という文字列を使うことでアクセス +できることを示す. + +dot ファイルを読み込んだ Alice のトポロジーマネージャーに対して, サーバノードは +誰に接続を行えばよいかを訪ねる. +トポロジーマネージャーは訪ねてきたサーバノードに対してノード番号を割り振り, dot ファイル +に記述している通りにサーバノード同士が接続を行うよう指示をだす. + +トポロジーマネージャーは接続要求先を聞いてくるサーバノードに対して名前を割り振り, 接続相手を伝える. +dot ファイル\ref{src:alice_dot}により形成されるトポロジーを図\ref{fig:tree_topology}に示す. + + +\begin{figure}[htpb] + \begin{center} + \includegraphics[scale=0.70]{figures/tree_topology.pdf} + \caption{Alice によるネットワークトポロジー形成} + \label{fig:tree_topology} + \end{center} +\end{figure} + +矢印に書かれている文字列は, 相手のデータにアクセスするキーを示す. +"child1", "child2", "parent" というキーを使うことで別のサーバノードにあるデータを取得することができる. +%子共となるノードは "parent" キーにより親の DSM (Remote DSM) にアクセスすることができる. +%また, 親も子供となるノードの DSM に対して "child1" や "child2" キーによりアクセスすることが可能となる. +これでトポロジーマネージャーが起動される. -\section{実験方法} -実験は同じ機能を提供している簡易掲示板プログラムを Jungle と Cassandra それぞれで -動かし, HTTPリクエストにより負荷をかけて行う. -レスポンスが帰ってくるまでの時間をはかる. +\subsection{アプリケーション側の記述} +次は Jungle 側のプログラムが最初に Alice のトポロジーノードと通信を行うようにする. +そのためには Alice の TopologyNode クラスに必要な情報を渡してインスタンスを生成する(\ref{src:app_start}). +\begin{lstlisting}[frame=lrbt,label=src:app_start,caption=アプリケーションの起動,numbers=left] +public static void main( String[] args ) throws Exception +{ + RemoteConfig conf = new RemoteConfig(args); + new TopologyNode(conf, new StartJungleCodeSegment(args, conf.bbsPort)); +} +\end{lstlisting} +TopologyNode クラスは第2引数として CodeSegment を受け取る. +TopologyNode のインスタンスはまず初めにトポロジーマネージャーへ接続を行う. +次にトポロジーマネージャーから受け取った情報を元に別のサーバノードとトポロジーの形成を行う. +その後, 第2引数で渡された StartJungleCodeSegment の実行を行う. +StartJungleCodeSegment には通常のアプリケーションの処理が書かれる. + +アプリケーションの起動時にはコンフィグの情報として, トポロジーマネージャーが動いているサーバのドメインとポート番号を +渡す必要がある. +例えば, mass00.cs.ie.u-ryukyu.ac.jp というサーバ上でポート番号10000を指定してトポロジーマネージャーを +起動した場合は次のようになる(\ref{src:run_program}). +\begin{lstlisting}[frame=lrbt,label=src:run_program,caption=トポロジーマネージャーの利用,numbers=left] +% java Program -host mass00.cs.ie.u-ryukyu.ac.jp -port 10000 +\end{lstlisting} + +\section{Alice を用いての分散実装} +Aliceのポロジー形成と他のサーバのデータへのアクセスする機構を用いるためには, Aliceが +提供するプログラミングスタイルに沿わなければならない. +それはDataSegment(データ)とCodeSegment(タスク)によるプログラムである. +ここではまずDataSegmentとCodeSegmentによるプログラムの方法について説明し, 他サーバとの +通信部分の実装について述べる. -また, 実験は2つ行う. -まず行う実験は, 複数のノードで起動してるうちの1つのノードに負荷をかける方法である. -これはノードの数に比例してレスポンスが遅くなっていないか確かめるためである. +\subsection{Alice によるプログラミング} +AliceはDataSegment(データ)とCodeSegment(タスク)単位でプログラミングを行うことを述べた. +CodeSegmentには計算に必要なDataSegmentが登録される. +そしてDataSegmentが準備され次第CodeSegmentによる計算が実行される. +DataSegmentの取得は文字列のキーを使うことで行える. +以下のコードにCodeSegmentの例を示す. +\begin{lstlisting}[frame=lrbt,label=src:syslog_nfconntrack,caption=CodeSegmentの実行,numbers=left] +public class TestCodeSegment extends CodeSegment { + public Receiver arg1 = ids.create(CommandType.TAKE); + + public TestCodeSegment() { } + + public void run() { + int count = ds.asInteger(); + count++; + System.out.println("count = "+count); + if(c > 10) { exit(0); } + CodeSegment cs = new TestCodeSegment(); + cs.setKey("count"); + ods.update("local", "count", c); + } + + public static void main(String[] args) { + CodeSegment cs = new TestCodeSegment(); + cs.arg1.setKey("local", "count"); // setKey API + cs.ods.update("local", "count", 0); + } +} +\end{lstlisting} +これは, 数字を1から10まで出力を行い終了するプログラムである. +コードの説明を行う. +17行目から19行目の処理が最初に行われる. +まずTestCodeSegmentというCodeSegmentのインスタンスcsを生成する. +csはarg1というReceiverクラスのフィールドを保持しており, Receiverクラスは +DataSegmentを受けとるためのクラスである. +arg1に対しsetKey APIを使うことで, 使用したいDataSegmentのキー"count"を登録することができる. +これによりキー"count"に対してデータが登録された場合, そのデータを受け取りcsの計算が自動で始まる. +setKey APIの第一引数に渡している"local"はどのマシンのDataSegmentにアクセスするのかを指定している. +この場合は自分自身を表す"local"になる. + +データの登録は\verb|ods.update|により行える. +上記のコード19行目ではupdateにより"count"をキーとして数値の0を登録している. +updateがされるとcsの計算が始まり別スレッドにより8行目からの処理が行われる. + +updateによりキー"count"に登録された数値0はReceiverであるdsを使って取ることができる. +7行目から13行目では\verb|ds.asInteger()|により, "count"に登録したデータの中身を受け取りインクリメントし出力する. +そして最後には\verb|ods.update|を行っている. +新たなTestCodeSegmentも生成しており, これはインクリメントされた"count"がupdateされることで実行される. +この一連の処理を"count"の数値が10以上になるまで行う. + +DataSegmentへデータの追加とCodeSegmentの実行について表した図\ref{fig:testcodesegment}になる. \begin{figure}[htpb] \begin{center} - \includegraphics[scale=0.70]{figures/jungle_experiment.pdf} - \caption{複数起動中のJungle の1ノードへの負荷} - \label{fig:jungle_exp} + \includegraphics[scale=0.70]{figures/testcodesegment.pdf} + \caption{DataSegmentとCodeSegmentによるプログラムの例} + \label{fig:testcodesegment} + \end{center} +\end{figure} + + +% Alice の他サーバノードへの"log"のputの問題 + +\subsection{他サーバノードのDataSegmentへアクセス} +Aliceにおける基本的なプログラミングは述べた. +次はネットワークを介して他サーバノードのDataSegmentにアクセスするプログラムについて述べる. + +まず, Aliceにより2分木3ノードのトポロジーが形成された場合を想定する. +その時に実際に作られるトポロジーを図\ref{fig:remote_cs}に示す. +\begin{figure}[htpb] + \begin{center} + \includegraphics[scale=0.70]{figures/remote_codesegment.pdf} + \caption{トポロジーの形成} + \label{fig:remote_cs} + \end{center} +\end{figure} + +ネットワークを介したDataSegmentへのアクセスはそのサーバノードを示す +文字列のキーを追加することで行える. +他サーバノードを示す文字列のキーとは図\ref{fig:remote_cs}に矢印の隣に書かれている文字列 +"parent", "child1", "child2" のことを指す. +例えば, server node0 が server node1のDataSegmentに入っている"count"というデータを +を使用したい場合は, 次のようにsetKeyを行えばよい(\ref{src:remote_cs1}). +\begin{lstlisting}[frame=lrbt,label=src:remote_cs1,caption=CodeSegmentで他サーバノードのDataSegmentを使用する,numbers=left] +CodeSegment cs = new RemoteCodeSegment(); +cs.arg1.setKey("child1", "count"); +\end{lstlisting} +また, 他サーバノードのDataSegmentにデータを送りたい場合は, putを行うときにサーバノードへのキーを +追加すればよい. +例として, server node1やserver node2がserver node0のDataSegmentに"message"というキーでデータを追加したい場合 +次のようになる(\ref{src:remote_cs2}). +\begin{lstlisting}[frame=lrbt,label=src:remote_cs2,caption=他サーバーノードのDatasSegmentにデータを追加する,numbers=left] +ods.put("parent", "message", "Hello parent"); +\end{lstlisting} + +\subsection{独自クラスのインスタンスの送受信} +最後に, 独自クラスのインスタンスのDataSegmentでの扱い方について述べる. +AliceではMessagePackを用いてシリアライズを行い他サーバノードへと送信している. +MessagePackはクラス単位でシリアライズを行うことができる. +そのため, Aliceではプリミティブな型に限らずクラスのインスタンスをDataSegmentとして +扱うことができる. + +MessagePackによりシリアライズとなるクラスはいくつか制限がある. +それはそのクラスに@Messageアノテーションを付けることと, そのクラスが保持するフィールドが +MessagePackによりシリアライズ可能であることである. +例えば次のようなクラスである. +\begin{lstlisting}[frame=lrbt,label=src:msgpack1,caption=MessagePackによりシリアライズ可能なクラス1,numbers=left] +import org.msgpack.annotation.Message + +@Message +public class Student { + String name; + int age; +} +\end{lstlisting} +上記のStudenクラスはプリミティブ型しか保持していない. +そのためシリアライズが可能である +また, 次のようなクラスもシリアライズ可能な型となる. +\begin{lstlisting}[frame=lrbt,label=src:msgpack2,caption=MessagePackによりシリアライズ可能なクラス2,numbers=left] +import org.msgpack.annotation.Message + +@Message +public class Class { + List<Student> studentList; +} +\end{lstlisting} +この場合, フィールドはプリミティブな型でないStudentクラスのフィールドを保持している. +しかし, Studentクラスはシリアライズ可能な形で作成しているため, クラスのフィールドとして +保持しても問題はない. + +これらの制約にそった形で作成しDataSegmentにネットワークを介してクラスのインスタンス +をupdateすることができる. +DataSegmentから受け取ったデータはそのままではシリアライズされたものため, 一度手元で +元のクラスにコンバートすることで扱う. +例として, AliceにおけるStudenクラス(Listing\ref{src:msgpack1})のコンバートを次に示す. +\begin{lstlisting}[frame=lrbt,label=src:msgpack3,caption=DataSegment,numbers=left] +// public Receiver arg1 = ids.create(CommandType.PEEK); +Student s = arg1.asClass(Student.class); +\end{lstlisting} +MessagePackでシリアライズ可能な形としているためDataSegmentはネットワークを介して +送受信が可能である. + + +\section{ログのシリアライズ} +Jungleの具体的な分散実装について述べる. +実装にあたり, 解決しなければならない問題はまず, ログをDataSegmentで扱える形にすることである. +そのためには, @Messageアノテーションを付けたログのクラスの作成を行わなければならない. + + +\subsection{TreeOperationLogのシリアライズ} +TreeOperationLogをシリアライズ可能な形にするにあたって気をつけなければならないのが, フィールドを +シリアライズ可能にする部分である. +TreeOperationLogはTreeOperationをいくつも保持し, TreeOperationはNodePathとNodeOperationを保持するものであった. +そのため, これら全てシリアライズ可能な形にしなければならない. + +基本的にこれらの実装は, フィールドを全てプリミティブなものだけにすればよい. +MessagePackはListを扱うこともできるため, TreeOperationLogで継承されていたIterableの挙動もListを使うことで +実装を行うことができた. + +\subsection{ログに対する情報の追加} +TreeOperationLogをシリアライズ可能な形にした後, 問題が発生した. +それは, TreeOperationLog事態は木の名前を保持していないというものである. +そのため, TreeOperationLogだけを受け取っても, そのログがどの木に対して行われるのか +わからなかった. +そこで, TreeOperationLogの情報だけでなく, 木の名前とUUID, それとtimestampの情報も付与 +してシリアライズが可能なNetworkTreeOperationLogの実装を行った. + +\subsection{NetworkTreeOperationLogの実装} +NetworkTreeOperationLogの実装の一部を以下に示す. + + + + + +% TreeOperationLog に木の名前の情報がない +% そのため木の名前を追加して持たせた +% 木がなければそのばでつくるようにした + +\subsection{local専用の編集の用意} + + +\subsection{} + + + +\section{掲示板プログラムにおけるマージの実装} +Jungle に分散実装を行った後の問題としてデータ衝突がある. +他のサーバノードから送られてくるデータが既に手元で変更を加えた木構造を対象とした +場合に発生する問題である. +Jungle ではこれをアプリケーション毎にマージを実装することで解決させる. + +今回分散実装を行い, 例題として掲示板プログラムを用意した. +掲示板プログラムに実装を行ったマージについて述べる. +まず Jungle を用いた掲示板プログラムのデータ保持方法を図\ref{fig:merge2}に示す. +\begin{figure}[htpb] + \begin{center} + \includegraphics[scale=0.70]{figures/merge2.pdf} + \caption{Jungle による掲示板プログラムのデータ保持方法} + \label{fig:merge2} + \end{center} +\end{figure} + +掲示板プログラムでは各掲示板毎に1つの木構造が作成される. +掲示板への1つの書き込みは子ノードを1つ追加することに相当する. +また, 各子ノードは attributes として書き込みの内容である message と書き込まれた時間を表す timestamp を保持している. +先に追加された順で子ノードには若い番号が割り振られる. + +他サーバノードからの書き込みをそのまま子ノードの後ろに追加してしまうと, データの整合性が崩れてしまう. +この時の状態を表しているのが図\ref{fig:merge_imp1}と\ref{fig:merge_imp2}になる. +\begin{figure}[htpb] + \begin{center} + \includegraphics[scale=0.70]{figures/merge_imp1.pdf} + \caption{他サーバノードの編集データ反映による整合性の崩れ1} + \label{fig:merge_imp1} \end{center} \end{figure} \begin{figure}[htpb] \begin{center} - \includegraphics[scale=0.70]{figures/cas_experiment.pdf} - \caption{複数起動中のCassandra の1ノードへの負荷} - \label{fig:cas_exp} - \end{center} -\end{figure} - -次に行う実験は複数のノードに対し複数のクライアントから負荷をかける方法である. -それぞれ大量のHTTPリクエストをだし, 全てのリクエストの処理にかかる時間を測定する. - -クライアントの数に比例してノードを増やすことでレスポンスを維持できるか -スケーラビリティを調べるためである. -\begin{figure}[htpb] - \begin{center} - \includegraphics[scale=0.70]{figures/clients_request_servers.pdf} - \caption{複数のクライアントから複数のノードへの負荷} - \label{fig:clients_servers} + \includegraphics[scale=0.70]{figures/merge_imp2.pdf} + \caption{他サーバノードの編集データ反映による整合性の崩れ2} + \label{fig:merge_imp2} \end{center} \end{figure} -\subsection{Torque Resource Manager} - -\subsection{weighttp} -最初の実験で1つのノードに負荷をかけるプログラムはウェブサーバの測定ツールであるweighttpを使用する. -weighttpは総リクエスト数, 同時接続数, ネイティブスレッド数をオプションとして指定することができるC言語 -でかかれたプログラムである. - - -\subsection{掲示板プログラム} -今回使用する掲示板プログラムは組み込み用ウェブサーバであるJettyをフロントエンドとして利用し, バックエンド -に Jungle と Cassandra を利用している. - -\begin{table}[!htbp] -\caption{簡易掲示板システムで利用したJettyとCassandraのバージョン} -\label{tab:bulletinboard_components} -\begin{center} -\begin{tabular}{|c||c|} \hline -名前 & バージョン \\ \hline \hline -Jetty & 6.1.26 \\ \hline -Cassandra & 2.0.4 \\ \hline -\end{tabular} -\end{center} -\end{table} - - - -\subsection{実験環境} - -\subsubsection{ノードを実行させるサーバの仕様} -使用するVMWareとKVMのクラスタの使用を以下に示す. -クラスタは仕様を表\ref{tab:cluster_spec_vmware}と表\ref{tab:cluster_spec_kvm}に示す. - -\begin{table}[!htbp] -\caption{ノードを実行させるVMWareクラスタの仕様} -\label{tab:cluster_spec_vmware} -\begin{center} -\begin{tabular}{|c||c|} \hline -名前 & 概要 \\ \hline \hline -CPU & Intel(R) Xeon(R) CPU X5650@2.67GHz \\ \hline -Memory & 8GB \\ \hline -OS & CentOS 5.8 \\ \hline -HyperVisor & VMWare ESXi \\ \hline -JavaVM & Java(TM) SE Runtime Environment (build 1.7.0-b147) \\ \hline -\end{tabular} -\end{center} -\end{table} - -\begin{table}[!htbp] -\caption{ノードを実行させるKVMクラスタの仕様} -\label{tab:cluster_spec_kvm} -\begin{center} -\begin{tabular}{|c||c|} \hline -名前 & 概要 \\ \hline \hline -CPU & Intel(R) Xeon(R) CPU X5650@2.67GHz \\ \hline -Memory & 8GB \\ \hline -OS & CentOS 5.8 \\ \hline -HyperVisor & KVM \\ \hline -JavaVM & Java(TM) SE Runtime Environment (build 1.7.0-b147) \\ \hline -\end{tabular} -\end{center} -\end{table} +\newpage -\subsubsection{1台に負荷をかけるブレードサーバの仕様} -最初の実験で負荷をかける側としてブレードサーバを使用する. -ブレードサーバの仕様を表\ref{tab:server_spec_1}に示す - -\begin{table}[!htbp] -\caption{} -\label{tab:server_spec_1} -\begin{center} -\begin{tabular}{|c||c|} \hline -名前 & 概要 \\ \hline \hline -CPU & Intel(R) Xeon(R) CPU X5650@2.67GHz \\ \hline -物理コア数 & 12 \\ \hline -論理コア数 & 24 \\ \hline -Memory & 132GB \\ \hline -OS & Fedora 16 \\ \hline -\end{tabular} -\end{center} -\end{table} - - +図\ref{fig:merge_imp2}の server node0 の木の状態にするのが理想である. +掲示板のへの書き込みの表示は, 書き込みされた時間が早い順に表示されるようにしたい. +これを timestamp を利用することで行う. +他サーバノードから来たデータに関しては, timestamp を参照し, 次に自分の保持している +木の子ノードの timestamp と比べていくことでデータの追加する場所を決める. +これが今回実装を行った掲示板システムにおけるマージになる. -\subsubsection{サーバの環境} -HTTPによりノードに負荷を掛ける場合気をつけることがある. -それはサーバの設定により最大コネクション数や開くことのできるファイル記述子の数に制限がかかっていることである. -この2つの値はデフォルトでは小さなものとなっており, そのままではカーネル -の設定がネックとなったベンチマーク結果がでる可能性がある. -そこで次のようにコマンドを実行することでコネクション数の制限を増やすことができる. -\begin{lstlisting}[frame=lrbt,label=src:maxconn_up,caption=コネクション数を増やす,numbers=left] -% sudo sysctl -w net.core.somaxconn=10000 -\end{lstlisting} -ファイル記述子の制限を増やす場合は次のコマンドを実行する -\begin{lstlisting}[frame=lrbt,label=src:max_up_filedisc,caption=ファイル記述子の制限を増やす,numbers=left] -% ulimit -n 10000 -\end{lstlisting} - -\section{実験結果1} -サーバノード数は10台から50台まで10台単位でweighttpにより負荷をかけ測定した. -weighttpに付けたオプションは以下のとおりである -\begin{lstlisting}[frame=lrbt,label=src:weighttp_op,caption=weighttpのオプション,numbers=left] -weighttp -n 1000000 -c 1000 -t 10 -k "http://url" -\end{lstlisting} -ネイティブスレッドを10個生成し, 同時接続は1000までで, 百万リクエストを送るオプションとなっている. - -実験の結果を示す. -縦軸は全てのリクエストに対してレスポンスが返ってくるのにかかった時間(秒), 横軸は -サーバノード数を表す. -Jungle と, Cassandra のコンシステンシー・レベルをQUORUM, ONEと両方の結果を測定した. -Cassandraのレプリケーションは5である. - -\begin{figure}[htpb] - \begin{center} - \includegraphics[scale=1.0]{figures/read_bench.pdf} - \caption{読み込みベンチマーク結果} - \label{fig:read_cassandra} - \end{center} -\end{figure} - -\begin{figure}[htpb] - \begin{center} - \includegraphics[scale=1.0]{figures/write_bench.pdf} - \caption{書き込みベンチマーク結果} - \label{fig:write_cassandra} - \end{center} -\end{figure} - -読み込み, 書き込み, どちらともJungleが3倍以上早くレスポンスを返していることが確認できる. -また, CassandraもJungleもノードの数が増えてもレスポンスを返す時間が遅くならないことも分かる. +%単一サーバで動いている時の Jungle はただ子ノードとして後ろに追加するだけだが, 分散 +%環境下においては timestamp に従い子ノードを追加する位置を決めるようにする. -\section{実験結果2} -学科の並列環境クラスタを用いて分散環境下での実験を行う -学科の提供するVMは48台だが, ブレードサーバ上で動くKVMから12台を利用し, 合計60台を使用する. -JungleとCassandraをそれぞれサーバノード10台, 20台, 30台で動かし, クライアントも10台, 20台, 30台 -と増やして負荷をかける. -KVM側はクライアント側だけに利用する. -weighttpに付けたオプションを以下の通りである. -\begin{lstlisting}[frame=lrbt,label=src:distributed_weighttp_op,caption=weighttpのオプション(実験2),numbers=left] -weighttp -n 50000 -c 200 -t 2 -k "http://url" -\end{lstlisting} -クライアント1台からはそれぞれ5万のHTTPリクエストが送られる. -実験1に比べ同時接続数とネイティブスレッド数が少ないのはVMの環境に合わせてあるからである. - -測定は読み込みと書き込みの両方を行う. -測定の結果をグラフにしたのを図\ref{fig:distributed_read_bench}, \ref{fig:distributed_write_bench}に示す. - -\begin{figure}[htpb] - \begin{center} - \includegraphics[scale=1.0]{figures/distributed_read_bench.pdf} - \caption{分散環境下における読み込みベンチマーク結果} - \label{fig:distributed_read_bench} - \end{center} -\end{figure} - -\begin{figure}[htpb] - \begin{center} - \includegraphics[scale=1.0]{figures/distributed_write_bench.pdf} - \caption{分散環境下における書き込みベンチマーク結果} - \label{fig:distributed_write_bench} - \end{center} -\end{figure} - - - - -