Mercurial > hg > Papers > 2014 > nobuyasu-master
diff paper/chapter4.tex @ 62:2cb5ac9282b0
writed description of ods.put
author | Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Sat, 01 Feb 2014 11:44:34 +0900 |
parents | c5c761588168 |
children | d770a2b534b3 |
line wrap: on
line diff
--- a/paper/chapter4.tex Sat Feb 01 10:23:28 2014 +0900 +++ b/paper/chapter4.tex Sat Feb 01 11:44:34 2014 +0900 @@ -13,7 +13,6 @@ データ分散に必要なクラスを用意することで他サーバノードとの通信を行う. 最後に, データ更新時の衝突において具体的なMergeの例として掲示板プログラムにおけるMergeについて述べる. - \section{Alice のトポロジーマネージャーの利用} \subsection{トポロジーマネージャーの起動} @@ -28,6 +27,7 @@ ポート番号は Alice により記述された並列分散プログラムの起動時に渡す必要がある. dot ファイルには, トポロジーをどのように形成するかが書かれている. 以下に, サーバノード数5で, 2分木ツリー構造を形成する dot ファイルの例を示す(\ref{src:alice_dot}). +\newpage \begin{lstlisting}[frame=lrbt,label=src:alice_dot,caption=ネットワークトポロジー設定用 dot ファイル,numbers=left] % cat tree5.dot digraph test { @@ -122,13 +122,13 @@ if(c > 10) { exit(0); } CodeSegment cs = new TestCodeSegment(); cs.setKey("count"); - ods.update("local", "count", c); + ods.put("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); + cs.ods.put("local", "count", 0); } } \end{lstlisting} @@ -143,14 +143,14 @@ setKey APIの第一引数に渡している"local"はどのマシンのDataSegmentにアクセスするのかを指定している. この場合は自分自身を表す"local"になる. -データの登録は\verb|ods.update|により行える. -上記のコード19行目ではupdateにより"count"をキーとして数値の0を登録している. -updateがされるとcsの計算が始まり別スレッドにより8行目からの処理が行われる. +データの登録は\verb|ods.put|により行える. +上記のコード19行目ではputにより"count"をキーとして数値の0を登録している. +putがされるとcsの計算が始まり別スレッドにより8行目からの処理が行われる. -updateによりキー"count"に登録された数値0はReceiverであるdsを使って取ることができる. +putによりキー"count"に登録された数値0はReceiverであるdsを使って取ることができる. 7行目から13行目では\verb|ds.asInteger()|により, "count"に登録したデータの中身を受け取りインクリメントし出力する. -そして最後には\verb|ods.update|を行っている. -新たなTestCodeSegmentも生成しており, これはインクリメントされた"count"がupdateされることで実行される. +そして最後には\verb|ods.put|を行っている. +新たなTestCodeSegmentも生成しており, これはインクリメントされた"count"がputされることで実行される. この一連の処理を"count"の数値が10以上になるまで行う. DataSegmentへデータの追加とCodeSegmentの実行について表した図\ref{fig:testcodesegment}になる. @@ -162,7 +162,7 @@ \end{center} \end{figure} - +\newpage % Alice の他サーバノードへの"log"のputの問題 \subsection{他サーバノードのDataSegmentへアクセス} @@ -200,8 +200,8 @@ \subsection{独自クラスのインスタンスの送受信} 最後に, 独自クラスのインスタンスのDataSegmentでの扱い方について述べる. AliceではMessagePackを用いてシリアライズを行い他サーバノードへと送信している. -MessagePackはクラス単位でシリアライズを行うことができる. -そのため, Aliceではプリミティブな型に限らずクラスのインスタンスをDataSegmentとして +MessagePackはインスタンス単位でシリアライズを行うことができる. +そのため, Aliceでもプリミティブな型に限らずクラスのインスタンスをDataSegmentとして 扱うことができる. MessagePackによりシリアライズとなるクラスはいくつか制限がある. @@ -217,7 +217,7 @@ int age; } \end{lstlisting} -上記のStudenクラスはプリミティブ型しか保持していない. +上記のStudentクラスはプリミティブ型しか保持していない. そのためシリアライズが可能である また, 次のようなクラスもシリアライズ可能な型となる. \begin{lstlisting}[frame=lrbt,label=src:msgpack2,caption=MessagePackによりシリアライズ可能なクラス2,numbers=left] @@ -233,7 +233,7 @@ 保持しても問題はない. これらの制約にそった形で作成しDataSegmentにネットワークを介してクラスのインスタンス -をupdateすることができる. +をputすることができる. DataSegmentから受け取ったデータはそのままではシリアライズされたものため, 一度手元で 元のクラスにコンバートすることで扱う. 例として, AliceにおけるStudenクラス(Listing\ref{src:msgpack1})のコンバートを次に示す. @@ -269,22 +269,79 @@ そこで, TreeOperationLogの情報だけでなく, 木の名前とUUID, それとtimestampの情報も付与 してシリアライズが可能なNetworkTreeOperationLogの実装を行った. -\subsection{NetworkTreeOperationLogの実装} -NetworkTreeOperationLogの実装の一部を以下に示す. - - - - - % TreeOperationLog に木の名前の情報がない % そのため木の名前を追加して持たせた % 木がなければそのばでつくるようにした +\subsection{NetworkTreeOperationLogの実装} +NetworkTreeOperationLogの実装の一部を以下(\ref{fig:netlog})に示す. +\begin{lstlisting}[frame=lrbt,label=src:netlog,caption=NetworkTreeOperationが持つフィールド,numbers=left] +@Message +public class NetworkTreeOperationLog implements TreeOperationLog +{ + public LinkedList<NetworkTreeOperation> list; + String treeName; + long timestamp; +\end{lstlisting} +Listにより保持しているNetworkTreeOperationはTreeOperationをシリアライズ可能な形にしたものである. +TreeOperationLogをimplementsし, 木の名前とtimestampをを保持する. +他サーバノードへ伝える必要のある情報が増えた場合, このようにNetworkTreeOperationLogに情報を付与することで +対応することができる. + +\subsection{ログの送信} +ログを送信するタイミングはいつ行うか. +それは, 木の編集が成功した時である. +木の編集が成功した結果得られるTreeOperationLogをNetworkTreeOperationLogに変換し, \verb|ods.put|を使って +CodeSegment側から利用できるようにする. + +しかし, この時気をつけなければならないことがある. +それは, \verb|ods.put|の処理をレスポンスを返すスレッドの中で行うと, レスポンスが悪くなる可能性が +あることだ. +そのため, \verb|ods.put|を行うのは別のThreadにしたほうがよい. +以下のコードはcommitに成功した後に, NetworkTreeOperationへと変換したログを別スレッド渡し +て処理させるコードである. +\begin{lstlisting}[frame=lrbt,label=src:logconvert_and_execute,caption=NetworkTreeOperationをputするために別スレッドを立ち上げる,numbers=left] +NetworkTreeOperationLog netLog = new NetworkTreeOperationLog(_uuid, _treeName,newLog); +CodeSegment cs = new LogPutCodeSegment(netLog); +cs.execute(); +\end{lstlisting} + +LogPutCodeSegmentの実装は次のようになっている. +\begin{lstlisting}[frame=lrbt,label=src:,caption=putを行うためだけのCodeSegmentの用意,numbers=left] +// LogPutCodeSegment Class +NetworkTreeOperationLog log; +public LogPutCodeSegment(NetworkTreeOperationLog _log) { + log = _log; +} + +@Override +public void run() { + ods.put("log", log); +} +\end{lstlisting} +上で述べた問題は, 通常のアプリケーションとして使用する分には発生しない. +だが, ベンチマークテストなど, 大量の負荷をかけた際に発生する. +ベンチマークテストでは大量のログが生成される. +そのため, \verb|ods.put|によりDataSegmentの"log"にアクセスが集中してしまい, レスポンスが +悪くなっていた. +\verb|ods.put|を行うタイミングには気をつけなければず, 上記のコードにしても改良の余地はある. + + + +\begin{lstlisting}[frame=lrbt,label=src:,caption=,numbers=left] + +\end{lstlisting} + + +\begin{lstlisting}[frame=lrbt,label=src:,caption=,numbers=left] + +\end{lstlisting} + + + \subsection{local専用の編集の用意} -\subsection{} - \section{掲示板プログラムにおけるマージの実装}