view chapter4.tex @ 8:b75c564064a8 default tip

fix undefined reference , multiply defined references
author Shoshi TAMAKI
date Thu, 21 Feb 2013 22:53:20 +0900
parents 44a95cddab8a
children
line wrap: on
line source

\chapter{木構造データベースJungleを用いたCMSの検証}


前章では, 分散コンテンツマネージメントシステムで用いるための木構造データベースJungleの利用方法, 詳細な実装について述べた.
本章では, 検証を行うために簡単な掲示板ウェブアプリケーションを作成し, バックエンドとしてCassandraと木構造データベースJungleを利用した実装を比較する.
また, 学科が提供するVMWareを用いた仮想環境と別に, 我々の研究室ではブレードサーバーを4台保有しており, そのブレードサーバーを用いてKVMを利用した仮想環境を構築する.\cite{shoshi:2011b}
そして, KVMとVMWareでの検証を行いどのような違いがあるから比較していく.

\section{実験方法}
実験方法は, 複数のクラスタを利用してサーバーに対して並列にアクセスを5000回行い, それぞれのクラスタの実行平均時間をとる.
クラスタ台数を増やすことにより並列度を上昇させ, 並列度と実行時間の平均をグラフ化する.
測定するのは書き込みと読み込みであり, 掲示板のメッセージの取得と掲示板のメッセージの編集を行う.(図\ref{fig:board_benchmark})
本検証では, コア数の多いサーバーと少ないサーバー, クラスタのハイパーバイザがVMWareとKVMの場合をそれぞれの組み合わせを検証する.

\begin{figure}[!htbp]
\begin{center}
\includegraphics[width=70mm]{./images/bulletinboard_benchmark.pdf}
\end{center}
\caption{簡易掲示板システムを用いたJungleの検証の概要}
\label{fig:board_benchmark}
\end{figure}

\subsubsection{Torque ResourceManager}
クラスタを用いた検証は, クラスタの管理・タスクの送信が非常に大変である. そのため, 本検証ではクラスタのリソース管理にTorque ResourceManagerを利用する.
Torqueにはタスクを入れるためのQueueが存在する.
Queueにタスクに入れると, クラスタを管理するマスターサーバーが実際にタスクを実行するクラスタを選択して割り当てる.
しかし, タスクは割り当てられたクラスタのリストを受け取るだけで, サーバーでのタスクの実行は自身で行う必要がある. (図\ref{fig:torque})

\begin{figure}[!htbp]
\begin{center}
\includegraphics[width=80mm]{./images/torque.pdf}
\end{center}
\caption{Torque ResourceManagerの概要}
\label{fig:torque}
\end{figure}

\subsubsection{簡易掲示板システム}
本検証では, Cassandraと木構造データベースJungleを用いた簡易掲示板システムを作成する.
このシステムは組み込みウェブサーバーであるJettyをフロントエンドにし, ウェブアプリケーションを作成. そのウェブアプリケーションのバックエンドとしてCassandraと我々が開発したJungleを利用する. 表\ref{tab:bulletinboard_components}にJettyとCassandraのバージョンを示す.

\begin{table}[!htbp]
\caption{簡易掲示板システムで利用したJettyとCassandraのバージョン}
\label{tab:bulletinboard_components}
\begin{center}
\begin{tabular}{|c||c|} \hline
名前 & バージョン \\ \hline \hline
Jetty & 6.1.25 \\ \hline
Cassandra & 1.2.1 \\ \hline
\end{tabular}
\end{center}
\end{table}

\newpage

\subsection{実験環境}
\subsubsection{サーバー}
サーバーは負荷をかける対象である. 本検証では, マルチコア環境が生かされているか確認するために, コア数の多いサーバーとコア数の少ないサーバーで検証を行う.
それぞれのサーバーの仕様を表\ref{tab:server_spec_1}と表\ref{tab:server_spec_2}に示す.

\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
JavaVM & Java(TM) SE Runtime Environment (build 1.6.0\_39-b04) \\ \hline
\end{tabular}
\end{center}
\end{table}

\begin{table}[!htbp]
\caption{コア数の少ないサーバーの仕様}
\label{tab:server_spec_2}
\begin{center}
\begin{tabular}{|c||c|} \hline
名前 & 概要 \\ \hline \hline
CPU & Intel(R) Xeon(R) CPU X5650@2.67GHz \\ \hline
仮想コア数 & 4 \\ \hline
Memory & 8GB \\ \hline
OS & Fedora 14 \\ \hline
HyperVisor & VMWare ESXi \\ \hline
JavaVM & Java(TM) SE Runtime Environment (build 1.6.0\_39-b04) \\ \hline
\end{tabular}
\end{center}
\end{table}

\newpage

\subsubsection{サーバーのnf\_conntrack}
サーバー対して並列に沢山のアクセスをすることで負荷を掛ける場合は, syslogに以下のメッセージが現れる可能性があり注意が必要である.

\begin{lstlisting}[frame=lrbt,label=src:syslog_nfconntrack,caption=syslogに大量のnf\_conntrack,numbers=left]
Feb 11 00:06:49 bldsv10 kernel: [103551.783200] nf_conntrack: table full, dropping packet.
Feb 11 00:06:49 bldsv10 kernel: [103551.783209] nf_conntrack: table full, dropping packet.
Feb 11 00:06:49 bldsv10 kernel: [103551.783260] nf_conntrack: table full, dropping packet.
Feb 11 00:06:49 bldsv10 kernel: [103551.783312] nf_conntrack: table full, dropping packet.
\end{lstlisting}

これは, iptablesのmoduleであり, ネットワークの接続を管理するテーブルが溢れてしまったことを示している.
この状態になると, 接続がタイムアウトするなどのエラーが発生する. それでは, 正常な測定ができないためnf\_conntrackの最大値を増やす必要がある.
以下のコマンドで増やすことが出来る.

\begin{lstlisting}[frame=lrbt,label=src:nf_conntrack_max,caption=nf\_conntrackのテーブルサイズを大きくする,numbers=left]
sysctl -w net.netfilter.nf_conntrack_max=65528
sysctl -w net.ipv4.netfilter.ip_conntrack_max=65535
\end{lstlisting}

\subsubsection{クラスタ}
クラスタはサーバーに並列に負荷をかけるために利用される. クラスタは仕様を表\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
\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
\end{tabular}
\end{center}
\end{table}

\newpage

\section{実験}
実験ではまず初めに, Torqueを利用してクラスタにタスクを実行させるためのスクリプトと実際にクラスタが実行するスクリプトが必要である.\\
本検証では, クラスタがサーバーにアクセスする際に使用するスクリプトの言語としてRubyを使用した. そのソースコードをソース\ref{src:benchmark_script}に示す.

\begin{lstlisting}[language=ruby,frame=lrbt,label=src:benchmark_script,caption=サーバーにアクセスするためのスクリプト,numbers=left]
#!/usr/bin/ruby

require 'net/http'
require 'benchmark'

tms = Benchmark.measure {
 schedule = ARGV[0].to_i
 time = Time.now.to_i 
 sleepTime = schedule - time
 sleep(sleepTime) 

 count = ARGV[1].to_i
 count.times {|i|
  Net::HTTP.get(address,url,port)
 }
}
puts tms.real
\end{lstlisting}

このスクリプトは, 時間計測のためにRubyのBenchmarkとサーバーへのアクセスのためにNet::HTTPを利用する. また, 指定された時間までsleepして指定回数サーバーへアクセスをする.\\
その合計時間を最後に出力するスクリプトである. 指定された時間にアクセスを開始することで, 複数のクラスタが同時にサーバーにアクセスすることを実現することが出来る.
\\ \\
次に, Torqueを利用してクラスタのリソースを確保し, 割り当てられたクラスタにタスクを送信するスクリプトを作成する.\\
このスクリプトは, 引数としてクラスタにベンチマークの開始時刻(unixtime)とリクエストの送信回数を指定する.
スクリプトのソースコードをソース\ref{src:torque_script}に示す. 

\newpage

\begin{lstlisting}[language=sh,frame=lrbt,label=src:torque_script,caption=割り当てられたクラスタにタスクを送るスクリプト,numbers=left]
#!/bin/sh
#
#PBS -q tqueue
#PBS -N read_jungle
#PBS -l walltime=00:05:00

script=/home/mass/share/student/k118585/stress_read_jungle.rb

function run() {
 while read serv
 do
  ssh $serv "/usr/bin/ruby $script $schedule $times" &
 done   
 wait
}

uniq $PBS_NODEFILE /tmp/nodes
run < /tmp/nodes
\end{lstlisting}

Torqueはリソースを割り当てる際に必要なノード数とそのコア数を指定することが出来る.
しかし, Torqueはそれぞれのクラスタの1コア単位にリソースを割り当てるため, 正確に1つのホストを割り当てるためにはクラスタのコア数である4を指定しなければならない.
Torqueに10ノードを利用してタスクを実行させるコマンドをソース\ref{src:qsub_command}に示す.

\begin{lstlisting}[language=sh,frame=lrbt,label=src:qsub_command,caption=Torqueにタスクを実行させるコマンド,numbers=left]
qsub -v schedule=`expr $(date +%s) + 5`,times=5000 -l nodes=10:ppn=4 script.sh 
\end{lstlisting}

そして, 本検証ではクラスタ1ノードから45ノードまでを計測するため, タスクの実行を監視し完了したのち次のタスクを投入するスクリプトを作成した.
ソース\ref{src:auto_qsub_script}に示す.

\begin{lstlisting}[language=sh,frame=lrbt,label=src:auto_qsub_script,caption=タスクの実行を監視して自動的に次のタスクを投入するスクリプト,numbers=left]
#!/bin/sh

start=1
finish=45

for i in `seq $start $finish`
do
 echo "current count = $i"
 qsub -v times=5000,schedule=`expr $(date +%s) + 5` -l nodes=$i:ppn=4 script.sh
 while [ "x`qstat`" != "x" ]
 do
  echo "waiting for job to complete"
  sleep 5
 done 
 echo "job complete"
 sleep 15
done
\end{lstlisting}

このスクリプトではTorqueのタスク状況を表示するqstatの出力を監視する. qstatはタスクが全て完了すると何も出力をしないため, 条件文でqstatの出力が無い場合, 次のタスクを投入する仕組みになっている.

\newpage

\section{実験結果}
\subsection{VMWareを用いた検証}
\subsubsection{コア数が多いサーバーの場合}
コア数が多いサーバーの場合の実験結果を読み込みの実験結果を図\ref{fig:benchmark_read_bldsv10}, 書き込みの実験結果を図\ref{fig:benchmark_write_bldsv10}に示す.

\begin{figure}[!htbp]
 \begin{center}
  \includegraphics[width=90mm]{./images/read_bldsv10.pdf}
 \end{center}
 \caption{コア数が多いサーバーの読み込み実験結果}
 \label{fig:benchmark_read_bldsv10}
\end{figure}

\begin{figure}[!htbp]
 \begin{center}
  \includegraphics[width=90mm]{./images/write_bldsv10.pdf}
 \end{center}
 \caption{コア数が多いサーバーの書き込み実験結果}
 \label{fig:benchmark_write_bldsv10}
\end{figure}

\newpage

\subsubsection{コア数が少ないサーバーの場合}
コア数が少ない場合の実験結果を読み込みの実験結果を図\ref{fig:benchmark_read_4cores}, 書き込みの実験結果を図\ref{fig:benchmark_write_4cores}に示す.

\begin{figure}[!htbp]
 \begin{center}
  \includegraphics[width=90mm]{./images/read_4cores.pdf}
 \end{center}
 \caption{コア数が少ないサーバーの読み込みの実験結果}
 \label{fig:benchmark_read_4cores}
\end{figure}

\begin{figure}[!htbp]
 \begin{center}
  \includegraphics[width=90mm]{./images/write_4cores.pdf}
 \end{center}
 \caption{コア数が少ないサーバーの書き込み実験結果}
 \label{fig:benchmark_write_4cores}
\end{figure}

全体的にJungleが僅かながら速く処理を終えている.
読み込み速度に関しては, 非破壊的木構造はコピーを自由に行うことができるためロックを必要としない. そのため, Casandraより速い結果が出ている.
書き込み速度はほぼCassandraと同じような推移の仕方をしていることが確認できる.
しかし, Jungleの測定結果においてところどころブレが見られる. これは, Jungleが木の編集の際に非破壊的に行うためオブジェクトが大量に生成され, JavaのGCが走ることのにより遅くなっているのではないかと推測する.\\
今回の実験では, コア数が多いサーバーと少ないサーバーで台数効果を確認することが出来なかった.
データベースの利用方法や測定の仕方にチューニングをして再度検証する必要があると思われる.

\newpage

\subsection{KVMクラスタを用いた検証}

\subsubsection{コア数が多いサーバーの場合}
コア数が多いサーバーの場合の実験結果を読み込みの実験結果を図\ref{fig:benchmark_read_kvm_bldsv10}, 書き込みの実験結果を図\ref{fig:benchmark_write_kvm_bldsv10}に示す.

\begin{figure}[!htbp]
 \begin{center}
  \includegraphics[width=90mm]{./images/kvm_read_bldsv10.pdf}
 \end{center}
 \caption{コア数が多いサーバーの読み込み実験結果}
 \label{fig:benchmark_read_kvm_bldsv10}
\end{figure}

\begin{figure}[!htbp]
 \begin{center}
  \includegraphics[width=90mm]{./images/kvm_write_bldsv10.pdf}
 \end{center}
 \caption{コア数が多いサーバーの書き込み実験結果}
 \label{fig:benchmark_write_kvm_bldsv10}
\end{figure}

\newpage

\subsubsection{コア数が少ないサーバーの場合}
コア数が少ない場合の実験結果を読み込みの実験結果を図\ref{fig:benchmark_read_kvm_4cores}, 書き込みの実験結果を図\ref{fig:benchmark_write_kvm_4cores}に示す.

\begin{figure}[!htbp]
 \begin{center}
  \includegraphics[width=90mm]{./images/read_kvm_4cores.pdf}
 \end{center}
 \caption{コア数が少ないサーバーの読み込みの実験結果}
 \label{fig:benchmark_read_kvm_4cores}
\end{figure}

\begin{figure}[!htbp]
 \begin{center}
  \includegraphics[width=90mm]{./images/write_kvm_4cores.pdf}
 \end{center}
 \caption{コア数が少ないサーバーの書き込み実験結果}
 \label{fig:benchmark_write_kvm_4cores}
\end{figure}

VMWareでの検証結果と同様に, Jungleが僅かながら早く処理を終えている.
しかし, 処理終了の平均時間をみてみるとVMWareよりKVMのほうが10秒以上の時間がかかっているのが分かる.
今回KVMクラスタを構築した際にブレードサーバー1台のみに48台の仮想マシンを構築した. 実際にはブレードサーバーは3台あるため, 3台に均等に仮想マシンを配置するのが良いと考えられる.
また, KVMにはvirtioなどの様々なio高速化に関するオプションがあり, それを試しながら更なるチューニングが必要である.
結果的に, VMWareと同様な結果が得られているので, チューニングによりKVMを実用的に運用できるのではないかと思われる.