view paper/final_main/chapter3.tex @ 15:b1e659ca3552

fix
author suruga
date Sun, 18 Feb 2018 20:35:20 +0900
parents 91879dd23dd0
children 47e118dc6538
line wrap: on
line source

\chapter{評価実験}
本研究は、Jungleの分散環境上での性能を正しく評価するための実験を行う。
本章では実験の概要について述べる。
まず、本研究の目的について述べ、
次に、分散フレームワーク Aliceによる、本研究の分散機構を構成する方法について述べる。
次に、木構造上に立ち上げたJungleへ投入するタスクを制御するジョブスケジューラー、TORQUEについて述べる。
最後に、本実験の測定用プログラムについて述べる。
\section{実験目的}
Jungleは現在、Javaで実装されたものと、Huskellで実装されたものがある。
Java版は、処理速度が早く、よりスケーラビリティの高いデータベースの実装を目的に開発された。
対してHuskell版は、モダンな型システムと、型推論と型安全という特徴を生かし、信頼性の高データベースの実装を目的に開発された。
そして、これまでの研究で、Java版とHaskell版のJungleの分散性能を測定する実験が行われている。
分散性能測定実験では、それぞれJetty,Wrapというwebサーバーをフロントエンドに用いたWeb掲示板サービスを使用している。
Java版とHuskell版のWeb掲示板サービスをブレードサーバー上で実行される。
計測方法は、掲示板に対して読み込みと書き込みを行い、ネットワークを介してweighhttpで負荷をかける。
weighthttpの設定は、1スレッドあたり100並列のリクエストを、10スレッド分投入し、合計100万のリクエストを処理させる。
Java と Haskell の測定結果が表\ref{tab:compare}のようになった。

\begin{table}[!htbp]
\begin{center}
\begin{tabular}{|c||r|r|} \hline
  測定 & Haskell & Java \\ \hline \hline
  読み込み & 16.31 s & 53.13 s \\ \hline
  書き込み & 20.17 s & 76.4 s \\ \hline
\end{tabular}
\end{center}

\caption{HaskellとJavaの比較}
\label{tab:compare}
\end{table}

Huskell 版は、 Java 版と比較して、読み込みで3,25倍、書き込みで 3.78倍 の性能差がでている結果となってしまった。
処理速度においてはHuskellよりも高いことを予想されていたのにもかかわらず、Java版がHuskell版よりも遅くなってしまった原因は、
測定時のWeb掲示板サービスのフロントエンドに、どちらもWebサーバーを用いているということが考えられる。しかも、その際は言語の問題から、異なる種類のWebサーバーを使用している。
これでは、この性能結果が、異なる言語で実装されたJungleの性能差によるものなのか、Webサーバーの性能差によるものなのかがわからない。
そこで、本研究ではJava版のJungleにおいて、Webサーバーを取り除いた、純粋なJungleの分散性能を測定するプログラムを実装した。
\section{実験概要}
Jungleの分散性能を測定するにあたり、複数台のJungleを通信させ、JungleからJungleに対する書き込みにかかる時間を計測する。複数台のJungleを分散させる為に、学内共用の仮想マシンを32台使用した。分散したJungle同士の通信部分には、当研究室で開発している分散フレームワークAliceの機能であるTopologyManagerを使用する。TopologyManagerの起動には、仮想マシン32台のうちの1台を使用する。
学科の仮想マシン31台上でそれぞれ1台ずつJungleを立ち上げ、ツリー型のトポロジーを構成する。そのうち16台のJungleに対して100回ずつデータを書き込む。子ノードのJungleは、次々と親ノードのJungleへデータを書き込む。最終的にルートノードのJungleへデータが到達し、書き込まれた時間を計測し、平均を取る。31台中16台のJungleから書き込まれたデータがルートノードのJungleへ書き込まれる、一回あたりの時間を計測する実験である。(図\ref{fig:gaiyou} )

  \begin{figure}[htbp]
    \begin{center}
        \includegraphics[width=100mm]{./pic/gaiyou.pdf}
    \end{center}
        \caption{複数のjungleに書き込まれたデータがrootのjungleへ到達する時間を計測する}
         \label{fig:gaiyou}
\end{figure}

\section{実験環境}
学科のKVM上の仮想マシンによる仮想クラスタ環境を用いて実験を行った。
分散環境上での実験を行うにあたり、他の利用者とリソースが競合しないよう、TORQUEジョブスケジューラーを利用している。
KVMと仮想マシンの性能はそれぞれ表\ref{tab:kvm}、表\ref{tab:vm}である。
\begin{table}[htbp]
\begin{center}
\begin{tabular}{|c||r|r|} \hline
  マシン台数 & Haskell  \\ \hline 
  CPU & 16.31 s  \\ \hline
  物理コア数 & 20.17 s  \\ \hline
  論理コア数 &   \\ \hline
  CPUキャッシュ & \\ \hline
  Memory & \\ \hline
\end{tabular}
\end{center}

\caption{KVMの詳細}
\label{tab:kvm}
\end{table}

\begin{table}[htbp]
\begin{center}
\begin{tabular}{|c||r|r|} \hline
  マシン台数 & Haskell  \\ \hline 
  CPU & 16.31 s  \\ \hline
  物理コア数 & 20.17 s  \\ \hline
  仮想コア数 &   \\ \hline
  CPUキャッシュ & \\ \hline
  Memory & \\ \hline
\end{tabular}
\end{center}

\caption{仮想クラスタの詳細}
\label{tab:vm}
\end{table}

\section{TORQUE Resource Manager}
分散環境上でのJungleの性能を測定するにあたり、VM31台にJungleを起動させた後、16台のJungleに対し、データを書き込むプログラムを動作させる。プログラムを起動する順番やタイミングは、TORQUE Resource Managerというジョブスケジューラーによって管理する。

TORQUE Resource Manager は、ジョブを管理・投下・実行する3つのデーモンで構成されており、
ジョブの管理・投下を担うデーモンが稼働しているヘッダーノードから、ジョブの実行を担うデーモンが稼働している計算ノードへジョブが投下される(図\ref{fig:torque} )。
  \begin{figure}
    \begin{center}
        \includegraphics[width=100mm]{./pic/torque.pdf}
    \end{center}
        \caption{TORQUEの構成}
         \label{fig:torque}
\end{figure}

ユーザーはジョブを記述したシェルスクリプトを用意し、スケジューラーに投入する。その際に、利用したいマシン数やCPUコア数を指定する。TORQUEは、ジョブに必要なマシンが揃い次第、受け取ったジョブを実行する。

今回作成した、ジョブに投入するためのシェルスクリプトを以下(ソースコード\ref{src:LogupdateTest.pl})に示す。

\begin{lstlisting}[frame=lrbt,label=src:LogupdateTest.pl,caption=本実験で投入するジョブスクリプト,numbers=left]
#!/bin/sh
#PBS -q jungle
#PBS -N LogUpdateTest
#PBS -l nodes=16,walltime=00:08:00

cd /mnt/data/jungle_workspace/Log  
/usr/bin/perl /mnt/data/jungle_workspace/scripts/LogupdateTest.pl
\end{lstlisting}
6行目で指定されたディレクトリに移動し、7行目ではそのディレクトリで、指定した別の階層にあるperlスクリプトを実行している。

\newpage


\section{分散フレームワーク Alice による分散環境の構築}
分散させたJungleの通信部分を担うのが、当研究室で開発している並列分散フレームワークAlice[1である。Aliceは、ネットワーク上の複数のサーバーノードにトポロジーを形成させ、通信する機能を提供する。今回扱うサーバーノードに学科の仮想マシン(VM)を用いる。
本研究では、分散環境上でのJungleの性能を確認する為、VM32台分のサーバーノードを用意し、それぞれで1台ずつJungle起動することで、分散させる。
Jungleを起動したサーバーノード間の通信部分を、当研究室で開発している並列分散フレームワークAlice[1]にて再現する。

Aliceには、ネットワークのトポロジーを構成するTopologyManager[2]という機能が備わっている。サーバーノードはTopologyManagerに、誰に接続を行えばよいかを尋ねる。TopologyManagerは尋ねてきたサーバーノードに順番に、接続先のサーバーノードのIPアドレス、ポート番号、接続名を送り、受け取ったサーバーノードはそれらに従って接続する。
この時、TopologyManager自身はVM0を用いて立ち上げる。
よって、TopologyManagerはJungleをのせたVM1からVM32、計VM31台分のサーバーノードを、木構造を形成するように采配する(図\ref{fig:topologymanager} )。

\begin{figure}[H]
    \centering
    \includegraphics[width=100mm]{pic/topologymanager3.pdf}
    \caption{AliceによるJungleの木構造トポロジーの形成}
    \label{fig:topologymanager}
\end{figure}

%DataSegment CodeSegment
Aliceはタスクを行うCodeSegmentと、CodeSegmentで使用するデータを扱うDataSegmentによってプログラムを行うスタイルを取る。
CodeSegmentはDataSegmentが必要なデータを受け取り次第、タスクを行う。DataSegmentがデータを受け取る為には、そのDataSegmentを示すキーが必要である。

TopologyManagerによって構成されたトポロジーのサーバーノードには、それぞれ自分自身を示す文字列であるキーが存在する。
このキーは自身のサーバーノードのDataSegmentがデータを受け取る際に指定する必要がある。

たとえば、servernode0,servernode1,servernode2により、(図\ref{fig:LogupdateTree})のように木構造が構成されたとする。
\begin{figure}[H]
    \centering
    \includegraphics[width=100mm]{pic/LogupdateTree.pdf}
    \caption{トポロジーの形成}
    \label{fig:LogupdateTree}
\end{figure}

この時、servernode0はservernode1、servernode2に対して親にあたる。逆に、servernode1,servernode2はservernode0に対して子にあたる。よって、(図\ref{fig:LogupdateTree})に矢印の隣にかかれている文字列"parent","child 1","child 2"のようにキーを指定している。
servernode0からservernode1へデータを送りたい場合、”child 1”というキーを追加すればいい。
このように、データアクセスしたいサーバーノードのキーを追加することで、そのサーバノードのDataSegmentへデータアクセスすることができる。
他のサーバーノードのDataSegmentへデータアクセスする際には、アクセス先のサーバーノードのキーを追加すればいい。

%TreeOperationLog
トポロジー構成後、Jungle間の通信でのデータ形式にはTreeOperationLogを利用する。TreeOperationLogは、Jungleによるノードの編集の履歴などの情報が入っている。TreeOperationLogは、AliceのDataSegmentでも扱えるようシリアライズ化されたデータである。よって、Aliceによって構成されたネットワークトポロジーのサーバノード間でのデータのアクセスが可能になっている。
TreeOperationLogをAliceによって他のJungleへ送る。送信先のJungleでは、送られてきたTreeOperationLogを参照して送信元のJungleと同じノード編集を行う。こうして、Jungle間でのデータの同期を可能にしている。
\newpage

\section{Jungleの分散性能測定用テストプログラムの実装}
本実験において、Jungleの性能を測定する為に以下のテストプログラムを作成した。
テストプログラムは、木構造における複数の子ノードに、データを複数書き込む機能を提供する。
複数の子ノードにデータをそれぞれ書き込み、最終的にrootノードへデータをmergeしていく(図\ref{fig:logupdatetest} )。データを複数書き込む機能は、Jungleを立ち上げる際に-writeオプションと-countオプションをつけることで搭載される。

測定範囲は、複数の子ノードから書き込まれたデータが全てrootノードへ到達し、書き込みが終了するまでの時間である。
%Aliceのコードを参照する限り、TopologyManagerが起動した時から、終了するまでの間で時間を取得している。

%この図だと末端の子ノードからのみ書き込まれているように見える。実際は1~16の様々な場所にあるノードから書き込む。
\begin{figure}[htbp]
    \centering
    \includegraphics[width=100mm]{pic/logupdatetest2.pdf}
    \caption{TestプログラムによるJungleの性能測定}
    \label{fig:logupdatetest}
\end{figure}

到達時間を測定するためには、AliceのTopologyManagerを立ち上げる際に、-show Time オプションをつける必要がある。これにより、出力される結果に末端ノードからrootノードへのデータの到達時間が表示されるようになる。

テストプログラムは、TopologyManagerとJungleの起動を行う。
TopologyManagerとJungleは、用意されたVM32台に起動される。
それぞれ、VMを何台用いて起動するかは、以下のように指定する。

%topologymanager
まず、本実験のネットワークトポロジーを形成するためtopokogymanagerの起動を行う。
TopologyManagerはVM0に起動する。
AliceのTopologyManagerの起動はソースコード\ref{src:Logupdate.pl}のように行う。
\begin{lstlisting}[frame=lrbt,label=src:Logupdate.pl,caption=Alice によるネットワークトポロジーマネージャーの起動,numbers=left]
% ssh $nodes[0] \"cd $logFile;java -cp ../../build/libs/logupdateTest-1.1.jar alice.topology.manager.TopologyManager -conf ../../scripts/tree.dot -p 10000 --showTime --noKeepAlive
\end{lstlisting}
-p オプションはTopologyManagerが開くポートの番号、-confオプションには dot ファイルのパスを渡している。
 ポート番号はAliceのより記述された並列分散プログラムの起動時に渡す必要がある。
 dot ファイルには、トポロジーをどのように構成するかが書かれている。dotファイルを読み込んだAliceのTopologyManagerに対して、サーバーノードは誰に接続を行えばよいかを尋ねる。TopologyManagerは尋ねてきたサーバーノードに対してノード番号を割り振り、dotファイルに記述している通りにサーバーノードが接続を行うように指示をだす。
このとき、子ノードからの書き込みがrootノードへ到達したときの時間の計測結果を表示する -showTime オプションも一緒につける。

%writeモードのjungle起動
-writeオプションをつけることで、jungleにデータを書き込む機能をつけることができる。
これを最大16台のJungleにつけて起動させる。
また、Jungleがデータを書き込む回数は、-countオプションをつけることで指定できる。今回は、1から100の回数分書き込みを行う。
-writeオプション、-countオプションを付けたwriteモードのjungleの起動はソースコード\ref{src:WriteCount}のように行う。
\begin{lstlisting}[frame=lrbt,label=src:WriteCount,caption=writeモードでのJungleの起動,numbers=left]
% ssh $nodes[$#nodes] \"cd $logFile;java -jar ../../build/libs/logupdateTest-1.1.jar -host $nodes[0] -p 10003 -port 10000  -write -count 10 --noKeepAlive
\end{lstlisting}

%jungleの起動
TopologyManagerに1台、writeモードで立ち上げるJungleに16台使た後、残りの15台はそのままJungleを起動させる。
起動はソースコード\ref{src:jungle}のように行う。
\begin{lstlisting}[frame=lrbt,label=src:jungle,caption=Jungleの起動,numbers=left]
% ssh $nodes[$i] \"cd $logFile;java -jar ../../build/libs/logupdateTest-1.1.jar -host $nodes[0] -p 10003 -port 10000  --noKeepAlive
\end{lstlisting}