Mercurial > hg > Papers > 2014 > nobuyasu-master
comparison paper/chapter4.tex @ 115:eac8620cf9cd
Fixed spell miss
author | Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Wed, 05 Mar 2014 19:54:34 +0900 |
parents | d116e59fc8a2 |
children | d45899154815 |
comparison
equal
deleted
inserted
replaced
114:d116e59fc8a2 | 115:eac8620cf9cd |
---|---|
52 誰に接続を行えばよいかを訪ねる. | 52 誰に接続を行えばよいかを訪ねる. |
53 トポロジーマネージャーは訪ねてきたサーバノードに対してノード番号を割り振り, dot ファイル | 53 トポロジーマネージャーは訪ねてきたサーバノードに対してノード番号を割り振り, dot ファイル |
54 に記述している通りにサーバノード同士が接続を行うよう指示をだす. | 54 に記述している通りにサーバノード同士が接続を行うよう指示をだす. |
55 | 55 |
56 トポロジーマネージャーは接続要求先を聞いてくるサーバノードに対して名前を割り振り, 接続相手を伝える. | 56 トポロジーマネージャーは接続要求先を聞いてくるサーバノードに対して名前を割り振り, 接続相手を伝える. |
57 dot ファイル\ref{src:alice_dot}により形成されるトポロジーを図\ref{fig:tree_topology}に示す. | 57 ソースコード\ref{src:alice_dot}のdotファイルにより形成されるトポロジーを図\ref{fig:tree_topology}に示す. |
58 | 58 |
59 | 59 |
60 \begin{figure}[htpb] | 60 \begin{figure}[htpb] |
61 \begin{center} | 61 \begin{center} |
62 \includegraphics[scale=0.70]{figures/tree_topology_noarrow.pdf} | 62 \includegraphics[scale=0.70]{figures/tree_topology_noarrow.pdf} |
94 \end{lstlisting} | 94 \end{lstlisting} |
95 | 95 |
96 \section{Alice を用いての分散実装} | 96 \section{Alice を用いての分散実装} |
97 Aliceのポロジー形成と他のサーバのデータへのアクセスする機構を用いるためには, Aliceが | 97 Aliceのポロジー形成と他のサーバのデータへのアクセスする機構を用いるためには, Aliceが |
98 提供するプログラミングスタイルに沿わなければならない. | 98 提供するプログラミングスタイルに沿わなければならない. |
99 それはDataSegment(データ)とCodeSegment(タスク)によるプログラムである. | 99 それはDataSegmentとCodeSegmentによるプログラムである. |
100 ここではまず, DataSegmentとCodeSegmentによるプログラムの方法について説明し, 他サーバとの | 100 ここではまず, DataSegmentとCodeSegmentによるプログラムの方法について説明し, 他サーバとの |
101 通信部分の実装について述べる. | 101 通信部分の実装について述べる. |
102 | 102 |
103 \subsection{Alice によるプログラミング} | 103 \subsection{Alice によるプログラミング} |
104 AliceはDataSegment(データ)とCodeSegment(タスク)単位でプログラミングを行うことを述べた. | 104 AliceはDataSegment(データ)とCodeSegment(タスク)単位でプログラミングを行う. |
105 CodeSegmentには計算に必要なDataSegmentが登録される. | 105 CodeSegmentには計算に必要なDataSegmentが登録される. |
106 そしてDataSegmentが準備され次第CodeSegmentによる計算が実行される. | 106 そしてDataSegmentが準備され次第CodeSegmentによる計算が実行される. |
107 DataSegmentの取得は文字列のキーを使うことで行える. | 107 DataSegmentの取得は文字列のキーを使うことで行える. |
108 ソースコード\ref{src:cs_sample}にCodeSegmentの例を示す. | 108 ソースコード\ref{src:cs_sample}にCodeSegmentの例を示す. |
109 \newpage | 109 \newpage |
110 \begin{lstlisting}[frame=lrbt,label=src:cs_sample,caption=CodeSegmentの実行,numbers=left] | 110 \begin{lstlisting}[frame=lrbt,label=src:cs_sample,caption=CodeSegmentの実行,numbers=left] |
111 public class TestCodeSegment extends CodeSegment { | 111 public class TestCodeSegment extends CodeSegment { |
112 public Receiver arg1 = ids.create(CommandType.TAKE); | 112 public Receiver arg1 = ids.create(CommandType.TAKE); |
113 | 113 |
114 public TestCodeSegment() { } | 114 public TestCodeSegment() { } |
115 | 115 |
116 public void run() { | 116 public void run() { |
117 int count = ds.asInteger(); | 117 int count = arg1.asInteger(); |
118 count++; | 118 count++; |
119 System.out.println("count = "+count); | 119 System.out.println("count = "+count); |
120 if(c > 10) { exit(0); } | 120 if(c > 10) { exit(0); } |
121 CodeSegment cs = new TestCodeSegment(); | 121 CodeSegment cs = new TestCodeSegment(); |
122 cs.setKey("count"); | 122 cs.setKey("count"); |
128 cs.arg1.setKey("local", "count"); // setKey API | 128 cs.arg1.setKey("local", "count"); // setKey API |
129 cs.ods.put("local", "count", 0); | 129 cs.ods.put("local", "count", 0); |
130 } | 130 } |
131 } | 131 } |
132 \end{lstlisting} | 132 \end{lstlisting} |
133 コードの説明を行う. | 133 ソースコード\ref{src:cs_sample}の説明を行う. |
134 このプログラムは, 数字を1から10まで出力を行い終了するプログラムである. | 134 このプログラムは, 数字を1から10まで出力を行い終了するプログラムである. |
135 17行目から19行目の処理が最初に行われる. | 135 17行目から19行目の処理が最初に行われる. |
136 まずTestCodeSegmentというCodeSegmentのインスタンスcsを生成する. | 136 まずTestCodeSegmentというCodeSegmentのインスタンスcsを生成する. |
137 csはarg1というReceiverクラスのフィールドを保持しており, Receiverクラスは | 137 csはarg1というReceiverクラスのフィールドを保持しており, Receiverクラスは |
138 DataSegmentを受けとるためのクラスである. | 138 DataSegmentを受けとるためのクラスである. |
143 | 143 |
144 データの登録は\verb|ods.put|により行える. | 144 データの登録は\verb|ods.put|により行える. |
145 上記のコード19行目ではputにより"count"をキーとして数値の0を登録している. | 145 上記のコード19行目ではputにより"count"をキーとして数値の0を登録している. |
146 putがされるとcsの計算が始まり別スレッドにより8行目からの処理が行われる. | 146 putがされるとcsの計算が始まり別スレッドにより8行目からの処理が行われる. |
147 | 147 |
148 putによりキー"count"に登録された数値0はReceiverであるdsを使って取ることができる. | 148 putによりキー"count"に登録された数値0はReceiverであるarg1を使って取ることができる. |
149 7行目から13行目では\verb|ds.asInteger()|により, "count"に登録したデータの中身を受け取りインクリメントし出力する. | 149 7行目から13行目では\verb|arg1.asInteger()|により, "count"に登録したデータの中身を受け取りインクリメントし出力する. |
150 そして, 最後には\verb|ods.put|を行っている. | 150 そして, 最後には\verb|ods.put|を行っている. |
151 新たなTestCodeSegmentも生成しており, これはインクリメントされた"count"がputされることで実行される. | 151 新たなTestCodeSegmentも生成しており, これはインクリメントされた"count"がputされることで実行される. |
152 この一連の処理を"count"の数値が10以上になるまで行う. | 152 この一連の処理を"count"の数値が10以上になるまで行う. |
153 | 153 |
154 DataSegmentへデータの追加とCodeSegmentの実行について表した図\ref{fig:testcodesegment}になる. | 154 DataSegmentへデータの追加とCodeSegmentの実行について表した図\ref{fig:testcodesegment}になる. |
213 String name; | 213 String name; |
214 int age; | 214 int age; |
215 } | 215 } |
216 \end{lstlisting} | 216 \end{lstlisting} |
217 上記のStudentクラスはプリミティブ型しか保持していない. | 217 上記のStudentクラスはプリミティブ型しか保持していない. |
218 そのためシリアライズが可能である | 218 そのためシリアライズが可能である. |
219 また, 次のようなクラスもシリアライズ可能な型となる(ソースコード\ref{src:msgpack2}). | 219 また, 次のようなクラスもシリアライズ可能な型となる(ソースコード\ref{src:msgpack2}). |
220 \begin{lstlisting}[frame=lrbt,label=src:msgpack2,caption=MessagePackによりシリアライズ可能なクラス2,numbers=left] | 220 \begin{lstlisting}[frame=lrbt,label=src:msgpack2,caption=MessagePackによりシリアライズ可能なクラス2,numbers=left] |
221 import org.msgpack.annotation.Message | 221 import org.msgpack.annotation.Message |
222 | 222 |
223 @Message | 223 @Message |
225 List<Student> studentList; | 225 List<Student> studentList; |
226 } | 226 } |
227 \end{lstlisting} | 227 \end{lstlisting} |
228 この場合, フィールドはプリミティブな型でないStudentクラスのフィールドを保持している. | 228 この場合, フィールドはプリミティブな型でないStudentクラスのフィールドを保持している. |
229 しかし, Studentクラスはシリアライズ可能な形で作成しているため, クラスのフィールドとして | 229 しかし, Studentクラスはシリアライズ可能な形で作成しているため, クラスのフィールドとして |
230 保持しても問題はない. | 230 保持しても問題ない. |
231 | 231 |
232 これらの制約にそった形で作成しDataSegmentにネットワークを介してクラスのインスタンス | 232 これらの制約にそった形で作成しDataSegmentにネットワークを介してクラスのインスタンス |
233 をputすることができる. | 233 をputすることができる. |
234 DataSegmentから受け取ったデータはそのままではシリアライズされたものため, 一度手元で | 234 DataSegmentから受け取ったデータはそのままではシリアライズされたものなため, 一度手元で |
235 元のクラスにコンバートすることで扱う. | 235 元のクラスにコンバートすることで扱う. |
236 例として, AliceにおけるStudenクラスのコンバートを次に示す(ソースコード\ref{src:msgpack1}). | 236 例として, AliceにおけるStudenクラスのコンバートを次に示す(ソースコード\ref{src:msgpack1}). |
237 \begin{lstlisting}[frame=lrbt,label=src:msgpack3,caption=DataSegment,numbers=left] | 237 \begin{lstlisting}[frame=lrbt,label=src:msgpack3,caption=DataSegment,numbers=left] |
238 // public Receiver arg1 = ids.create(CommandType.PEEK); | 238 // public Receiver arg1 = ids.create(CommandType.PEEK); |
239 Student s = arg1.asClass(Student.class); | 239 Student s = arg1.asClass(Student.class); |
269 % TreeOperationLog に木の名前の情報がない | 269 % TreeOperationLog に木の名前の情報がない |
270 % そのため木の名前を追加して持たせた | 270 % そのため木の名前を追加して持たせた |
271 % 木がなければそのばでつくるようにした | 271 % 木がなければそのばでつくるようにした |
272 | 272 |
273 \subsection{NetworkTreeOperationLogの実装} | 273 \subsection{NetworkTreeOperationLogの実装} |
274 NetworkTreeOperationLogの実装の一部を以下(図\ref{src:netlog})に示す. | 274 NetworkTreeOperationLogの実装の一部を以下(ソースコード\ref{src:netlog})に示す. |
275 \begin{lstlisting}[frame=lrbt,label=src:netlog,caption=NetworkTreeOperationが持つフィールド,numbers=left] | 275 \begin{lstlisting}[frame=lrbt,label=src:netlog,caption=NetworkTreeOperationが持つフィールド,numbers=left] |
276 @Message | 276 @Message |
277 public class NetworkTreeOperationLog implements TreeOperationLog | 277 public class NetworkTreeOperationLog implements TreeOperationLog |
278 { | 278 { |
279 public LinkedList<NetworkTreeOperation> list; | 279 public LinkedList<NetworkTreeOperation> list; |
302 CodeSegment cs = new LogPutCodeSegment(netLog); | 302 CodeSegment cs = new LogPutCodeSegment(netLog); |
303 cs.execute(); | 303 cs.execute(); |
304 \end{lstlisting} | 304 \end{lstlisting} |
305 | 305 |
306 LogPutCodeSegmentの実装は次のようになっている(ソースコード\ref{src:logputcs}). | 306 LogPutCodeSegmentの実装は次のようになっている(ソースコード\ref{src:logputcs}). |
307 \begin{lstlisting}[frame=lrbt,label=src:logputcs,caption=putを行うためだけのCodeSegmentの用意,numbers=left] | 307 \begin{lstlisting}[frame=lrbt,label=src:logputcs,caption=putを行うためのCodeSegmentの用意,numbers=left] |
308 public class LogPutCodeSegment extends CodeSegment{ | 308 public class LogPutCodeSegment extends CodeSegment{ |
309 NetworkTreeOperationLog log; | 309 NetworkTreeOperationLog log; |
310 public LogPutCodeSegment(NetworkTreeOperationLog _log) { | 310 public LogPutCodeSegment(NetworkTreeOperationLog _log) { |
311 log = _log; | 311 log = _log; |
312 } | 312 } |
314 public void run() { | 314 public void run() { |
315 ods.put("log", log); | 315 ods.put("log", log); |
316 } | 316 } |
317 } | 317 } |
318 \end{lstlisting} | 318 \end{lstlisting} |
319 上で述べた問題は, ベンチマークテストなど, 大量の負荷をかけたさいに発生する. | 319 上で述べた問題は, ベンチマークテストなど, 大量の負荷をかけた際に発生する. |
320 負荷とはJungleのデータに変更が加わることである. | 320 負荷とはJungleのデータに変更が加わることである. |
321 多数のデータの変更により大量のログが生成される. | 321 多数のデータの変更により大量のログが生成される. |
322 そのため, \verb|ods.put|によりDataSegmentの"log"にアクセスが集中してしまい, レスポンスが | 322 そのため, \verb|ods.put|によりDataSegmentの"log"にアクセスが集中してしまい, レスポンスが |
323 悪くなっていた. | 323 悪くなっていた. |
324 \verb|ods.put|を行うタイミングには気をつけなければず, 上記のコードにしても改良の余地はある. | 324 \verb|ods.put|を行うタイミングには気をつけなければず, 上記のコードにしても改良の余地はある. |
347 for (String node : list) { | 347 for (String node : list) { |
348 ods.put(node, log.key, log.getVal()); // Send datasegment to other node | 348 ods.put(node, log.key, log.getVal()); // Send datasegment to other node |
349 } | 349 } |
350 : | 350 : |
351 \end{lstlisting} | 351 \end{lstlisting} |
352 12行目の\verb|ods.put(node, log.key, log.getVal())|が他サーバノードへデータを送る部分になる. | 352 12行目の\verb|ods.put(node, log.key, log.getVal())|が他サーバノードへデータを送る部分になる. |
353 変数logにはNetworTreeOperationLogが入っている. | 353 変数logにはNetworTreeOperationLogが入っている. |
354 変数listには"\_CLIST"により得られたデータが入っている. | 354 変数listには"\_CLIST"により得られたデータが入っている. |
355 それは文字列のListとなっている. | 355 それは文字列のListとなっている. |
356 listの中身を1つずつ受け取り, \verb|ods.put|する際に引数として渡してやることで, 他サーバノードの | 356 listの中身を1つずつ受け取り, \verb|ods.put|する際に引数として渡してやることで, 他サーバノードの |
357 DataSegmentにアクセスが行える. | 357 DataSegmentにアクセスが行える. |
360 の文字列のListとなっている. | 360 の文字列のListとなっている. |
361 もし子どもとなるサーバノードがないときは"parent"だけがListには入れられる. | 361 もし子どもとなるサーバノードがないときは"parent"だけがListには入れられる. |
362 | 362 |
363 \subsection{ログの受信とデータ反映} | 363 \subsection{ログの受信とデータ反映} |
364 次は受け取ったログからデータの編集を行う部分の実装を行う. | 364 次は受け取ったログからデータの編集を行う部分の実装を行う. |
365 Jungleはのデータを変更する手段として木構造データ毎にTreeEditorクラスが提供される. | 365 Jungleはデータを変更する手段として木構造データ毎にTreeEditorクラスを提供している. |
366 このTreeEditorを使用し, ログに入っているTreeOperationを1つ1つ取り出し同じ編集を行わせる. | 366 このTreeEditorを使用し, ログに入っているTreeOperationを1つ1つ取り出し同じ編集を行わせる. |
367 例えば次のようになる(ソースコード\ref{src:data_edit}). | 367 例えば次のようになる(ソースコード\ref{src:data_edit}). |
368 \begin{lstlisting}[frame=lrbt,label=src:data_edit,caption=ログを受け取ってのデータの反映,numbers=left] | 368 \begin{lstlisting}[frame=lrbt,label=src:data_edit,caption=ログを受け取ってのデータの反映,numbers=left] |
369 // Receiver log <- "log"キーから取得できるデータが入っている | 369 // Receiver log <- "log"キーから取得できるデータが入っている |
370 // Jungle jugnle | 370 // Jungle jugnle |
371 // Either<Error,JungleTreeEditor> either | |
371 NetworkTreeOperationLog netLog = log.asClass(NetworkTreeOperationLog.class); | 372 NetworkTreeOperationLog netLog = log.asClass(NetworkTreeOperationLog.class); |
372 String treeName = netLog.getTreeName(); | 373 String treeName = netLog.getTreeName(); |
373 JungleTree tree = jungle.getTreeByName(treeName); | 374 JungleTree tree = jungle.getTreeByName(treeName); |
374 TreeEditor editor = tree.getLocalTreeEditor(); // Editor の取得 | 375 TreeEditor editor = tree.getLocalTreeEditor(); // Editor の取得 |
375 for (TreeOperation op : netlog) { | 376 for (TreeOperation op : netlog) { |
380 // エラー処理.編集失敗 | 381 // エラー処理.編集失敗 |
381 } | 382 } |
382 editor = either.b(); | 383 editor = either.b(); |
383 } | 384 } |
384 \end{lstlisting} | 385 \end{lstlisting} |
385 7行目で取り出されたTreeOperationからさらにNodePathとNodeOperationを取り出しているのが8行目と9行目になる. | 386 8行目で取り出されたTreeOperationからさらにNodePathとNodeOperationを取り出しているのが9行目と10行目になる. |
386 最後にedit関数にTreeEditorとNodePath, それとNodeOpeartionを引き渡している. | 387 最後にedit関数にTreeEditorとNodePath, それとNodeOpeartionを引き渡している. |
387 edit関数は次のようになる(ソースコード\ref{src:data_edit2}). | 388 edit関数は次のようになる(ソースコード\ref{src:data_edit2}). |
388 \begin{lstlisting}[frame=lrbt,label=src:data_edit2,caption=edit関数の実装,numbers=left] | 389 \begin{lstlisting}[frame=lrbt,label=src:data_edit2,caption=edit関数の実装,numbers=left] |
389 Either<Error, JungleTreeEditor> edit(JungleTreeEditor editor, NodePath path, | 390 Either<Error, JungleTreeEditor> edit(JungleTreeEditor editor, NodePath path, |
390 NodeOperation nodeOp, int pos) { | 391 NodeOperation nodeOp, int pos) { |
452 またUUIDや木の名前も取得することができる. | 453 またUUIDや木の名前も取得することができる. |
453 そのため, NetworkTreeOperationLogへと変換が行える. | 454 そのため, NetworkTreeOperationLogへと変換が行える. |
454 | 455 |
455 ログの書き出しを行いたいときはこのPersistentChangeListWriterを設定することで行えるようになった. | 456 ログの書き出しを行いたいときはこのPersistentChangeListWriterを設定することで行えるようになった. |
456 これにより木の編集が行われるたびにNetworkTreeOperationLogが書き込まれていく. | 457 これにより木の編集が行われるたびにNetworkTreeOperationLogが書き込まれていく. |
457 読み込みたいときはMessagePackを使ってディスクから読み込み, データ分散実装と同じの方法で木の編集を行っていく | 458 読み込みたいときはMessagePackを使ってディスクから読み込み, データ分散実装と同じ方法で木の編集を行っていく |
458 ことができる(ソースコード\ref{src:data_edit}, \ref{src:data_edit2}). | 459 ことができる. |
459 | 460 |
460 | 461 |
461 \newpage | 462 \newpage |
462 \section{Mergeの実装} | 463 \section{Mergeの実装} |
463 Jungle に分散実装を行った後の問題としてデータ衝突がある. | 464 Jungle に分散実装を行った後の問題としてデータ衝突がある. |
504 \newpage | 505 \newpage |
505 | 506 |
506 \subsection{掲示板プログラムにおけるMerge} | 507 \subsection{掲示板プログラムにおけるMerge} |
507 | 508 |
508 図\ref{fig:merge_imp2}の server node0 の木の状態にするのが理想である. | 509 図\ref{fig:merge_imp2}の server node0 の木の状態にするのが理想である. |
509 掲示板のへの書き込みの表示は, 書き込みされた時間が早い順に表示されるようにしたい. | 510 掲示板への書き込みの表示は, 書き込みされた時間が早い順に表示されるようにしたい. |
510 これを timestamp を利用することで行う. | 511 これを timestamp を利用することで行う. |
511 他サーバノードから来たデータに関しては, timestamp を参照し, 次に自分の保持している | 512 他サーバノードから来たデータに関しては, timestamp を参照し, 次に自分の保持している |
512 木の子ノードの timestamp と比べていくことでデータの追加する場所を決める. | 513 木の子ノードの timestamp と比べていくことでデータの追加する場所を決める. |
513 これが今回実装を行った掲示板システムにおけるMergeになる. | 514 これが今回実装を行った掲示板システムにおけるMergeになる. |
514 | 515 |