Mercurial > hg > Papers > 2014 > nobuyasu-master
annotate paper/chapter4.tex @ 105:3678db9f1085
Modified poster
author | Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 18 Feb 2014 01:09:38 +0900 |
parents | 6f73e05d5024 |
children | d116e59fc8a2 |
rev | line source |
---|---|
50 | 1 \chapter{木構造データベースJungleの分散実装} |
102
6f73e05d5024
Fixed chapter4.tex
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
71
diff
changeset
|
2 前章では Jungle のアーキテクチャと分散設計について説明した. |
50 | 3 トポロジーの形成と他サーバノードのデータのアクセス方法には Alice を使用する. |
4 また, Jungle ではデータ編集のログとして TreeOperationLog がある. | |
5 この TreeOperationLog を Alice により他サーバノードへ送ることでデータの分散を行う. | |
6 | |
61
c5c761588168
Modified chapter3
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
50
diff
changeset
|
7 本章では Jungle に行った分散実装について述べる. |
c5c761588168
Modified chapter3
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
50
diff
changeset
|
8 まず, Aliceによるトポロジー形成の仕方を述べ, Aliceを利用したプログラミングの方法に |
c5c761588168
Modified chapter3
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
50
diff
changeset
|
9 ついて説明を行う. |
c5c761588168
Modified chapter3
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
50
diff
changeset
|
10 Aliceの提供する分散プログラミングにおけるデータアクセス機構について述べ, それらを使用する |
c5c761588168
Modified chapter3
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
50
diff
changeset
|
11 上での注意点を述べる. |
c5c761588168
Modified chapter3
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
50
diff
changeset
|
12 次に, それらをふまえてJungleの分散実装を行っていく. |
c5c761588168
Modified chapter3
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
50
diff
changeset
|
13 データ分散に必要なクラスを用意することで他サーバノードとの通信を行う. |
c5c761588168
Modified chapter3
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
50
diff
changeset
|
14 最後に, データ更新時の衝突において具体的なMergeの例として掲示板プログラムにおけるMergeについて述べる. |
c5c761588168
Modified chapter3
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
50
diff
changeset
|
15 |
50 | 16 \section{Alice のトポロジーマネージャーの利用} |
17 | |
18 \subsection{トポロジーマネージャーの起動} | |
19 Alice を用いてサーバノードでトポロジーの形成を行う方法を述べる. | |
102
6f73e05d5024
Fixed chapter4.tex
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
71
diff
changeset
|
20 Alice のトポロジーマネージャーの起動はソースコード\ref{src:alice_ntm_run}の様に行う. |
50 | 21 \begin{lstlisting}[frame=lrbt,label=src:alice_ntm_run,caption=Alice によるネットワークトポロジーマネージャーの起動,numbers=left] |
22 % java -cp Alice.jar alice.topology.manager.TopologyManager -p 10000 -conf ./topology/tree5.dot | |
23 \end{lstlisting} | |
24 -p オプションはトポロジーマネージャーが開くポートの番号, -conf オプションには dot ファイルのパスを渡す. | |
25 | |
26 ポート番号は Alice により記述された並列分散プログラムの起動時に渡す必要がある. | |
27 dot ファイルには, トポロジーをどのように形成するかが書かれている. | |
102
6f73e05d5024
Fixed chapter4.tex
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
71
diff
changeset
|
28 以下に, サーバノード数5で, 2分木ツリー構造を形成する dot ファイルの例を示す(ソースコード\ref{src:alice_dot}). |
62
2cb5ac9282b0
writed description of ods.put
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
61
diff
changeset
|
29 \newpage |
50 | 30 \begin{lstlisting}[frame=lrbt,label=src:alice_dot,caption=ネットワークトポロジー設定用 dot ファイル,numbers=left] |
31 % cat tree5.dot | |
32 digraph test { | |
33 node0 -> node1 [label="child1"] | |
34 node0 -> node2 [label="child2"] | |
35 node1 -> node0 [label="parent"] | |
36 node1 -> node3 [label="child1"] | |
37 node1 -> node4 [label="child2"] | |
38 node2 -> node0 [label="parent"] | |
39 node3 -> node1 [label="parent"] | |
40 node4 -> node1 [label="parent"] | |
41 } | |
42 \end{lstlisting} | |
43 | |
44 node0 や node1 はサーバノードの名前を示す. | |
45 サーバノードの間にはラベルがあり, Alice 上ではこのラベル | |
46 に指定される文字列(キー)を使うことで他のサーバノードのデータへアクセスすることができる. | |
69 | 47 node0 \verb|->| node1 はサーバノード同士の繋がりを示している. |
50 | 48 次に続く label="child1" は, node0 が node1 のデータに"child1"という文字列を使うことでアクセス |
49 できることを示す. | |
50 | |
51 dot ファイルを読み込んだ Alice のトポロジーマネージャーに対して, サーバノードは | |
52 誰に接続を行えばよいかを訪ねる. | |
53 トポロジーマネージャーは訪ねてきたサーバノードに対してノード番号を割り振り, dot ファイル | |
54 に記述している通りにサーバノード同士が接続を行うよう指示をだす. | |
55 | |
56 トポロジーマネージャーは接続要求先を聞いてくるサーバノードに対して名前を割り振り, 接続相手を伝える. | |
57 dot ファイル\ref{src:alice_dot}により形成されるトポロジーを図\ref{fig:tree_topology}に示す. | |
58 | |
59 | |
60 \begin{figure}[htpb] | |
61 \begin{center} | |
63
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
62 \includegraphics[scale=0.70]{figures/tree_topology_noarrow.pdf} |
50 | 63 \caption{Alice によるネットワークトポロジー形成} |
64 \label{fig:tree_topology} | |
65 \end{center} | |
66 \end{figure} | |
67 | |
63
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
68 %矢印に書かれている文字列は, 相手のデータにアクセスするキーを示す. |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
69 %"child1", "child2", "parent" というキーを使うことで別のサーバノードにあるデータを取得することができる. |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
70 %これでトポロジーマネージャーが起動される. |
24
5316b4791570
Added master_paper.pdf
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
4
diff
changeset
|
71 |
50 | 72 \subsection{アプリケーション側の記述} |
73 次は Jungle 側のプログラムが最初に Alice のトポロジーノードと通信を行うようにする. | |
102
6f73e05d5024
Fixed chapter4.tex
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
71
diff
changeset
|
74 そのためには Alice の TopologyNode クラスに必要な情報を渡してインスタンスを生成する(ソースコード\ref{src:app_start}). |
50 | 75 \begin{lstlisting}[frame=lrbt,label=src:app_start,caption=アプリケーションの起動,numbers=left] |
76 public static void main( String[] args ) throws Exception | |
77 { | |
78 RemoteConfig conf = new RemoteConfig(args); | |
79 new TopologyNode(conf, new StartJungleCodeSegment(args, conf.bbsPort)); | |
80 } | |
81 \end{lstlisting} | |
82 TopologyNode クラスは第2引数として CodeSegment を受け取る. | |
83 TopologyNode のインスタンスはまず初めにトポロジーマネージャーへ接続を行う. | |
84 次にトポロジーマネージャーから受け取った情報を元に別のサーバノードとトポロジーの形成を行う. | |
85 その後, 第2引数で渡された StartJungleCodeSegment の実行を行う. | |
86 StartJungleCodeSegment には通常のアプリケーションの処理が書かれる. | |
87 | |
88 アプリケーションの起動時にはコンフィグの情報として, トポロジーマネージャーが動いているサーバのドメインとポート番号を | |
89 渡す必要がある. | |
90 例えば, mass00.cs.ie.u-ryukyu.ac.jp というサーバ上でポート番号10000を指定してトポロジーマネージャーを | |
102
6f73e05d5024
Fixed chapter4.tex
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
71
diff
changeset
|
91 起動した場合は次のようになる(ソースコード\ref{src:run_program}). |
50 | 92 \begin{lstlisting}[frame=lrbt,label=src:run_program,caption=トポロジーマネージャーの利用,numbers=left] |
93 % java Program -host mass00.cs.ie.u-ryukyu.ac.jp -port 10000 | |
94 \end{lstlisting} | |
95 | |
96 \section{Alice を用いての分散実装} | |
97 Aliceのポロジー形成と他のサーバのデータへのアクセスする機構を用いるためには, Aliceが | |
98 提供するプログラミングスタイルに沿わなければならない. | |
99 それはDataSegment(データ)とCodeSegment(タスク)によるプログラムである. | |
102
6f73e05d5024
Fixed chapter4.tex
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
71
diff
changeset
|
100 ここではまず, DataSegmentとCodeSegmentによるプログラムの方法について説明し, 他サーバとの |
50 | 101 通信部分の実装について述べる. |
24
5316b4791570
Added master_paper.pdf
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
4
diff
changeset
|
102 |
50 | 103 \subsection{Alice によるプログラミング} |
104 AliceはDataSegment(データ)とCodeSegment(タスク)単位でプログラミングを行うことを述べた. | |
105 CodeSegmentには計算に必要なDataSegmentが登録される. | |
106 そしてDataSegmentが準備され次第CodeSegmentによる計算が実行される. | |
107 DataSegmentの取得は文字列のキーを使うことで行える. | |
102
6f73e05d5024
Fixed chapter4.tex
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
71
diff
changeset
|
108 ソースコード\ref{src:cs_sample}にCodeSegmentの例を示す. |
69 | 109 \newpage |
110 \begin{lstlisting}[frame=lrbt,label=src:cs_sample,caption=CodeSegmentの実行,numbers=left] | |
50 | 111 public class TestCodeSegment extends CodeSegment { |
112 public Receiver arg1 = ids.create(CommandType.TAKE); | |
113 | |
114 public TestCodeSegment() { } | |
115 | |
116 public void run() { | |
117 int count = ds.asInteger(); | |
118 count++; | |
119 System.out.println("count = "+count); | |
120 if(c > 10) { exit(0); } | |
121 CodeSegment cs = new TestCodeSegment(); | |
122 cs.setKey("count"); | |
62
2cb5ac9282b0
writed description of ods.put
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
61
diff
changeset
|
123 ods.put("local", "count", c); |
50 | 124 } |
125 | |
126 public static void main(String[] args) { | |
127 CodeSegment cs = new TestCodeSegment(); | |
128 cs.arg1.setKey("local", "count"); // setKey API | |
62
2cb5ac9282b0
writed description of ods.put
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
61
diff
changeset
|
129 cs.ods.put("local", "count", 0); |
50 | 130 } |
131 } | |
132 \end{lstlisting} | |
133 コードの説明を行う. | |
69 | 134 このプログラムは, 数字を1から10まで出力を行い終了するプログラムである. |
50 | 135 17行目から19行目の処理が最初に行われる. |
136 まずTestCodeSegmentというCodeSegmentのインスタンスcsを生成する. | |
137 csはarg1というReceiverクラスのフィールドを保持しており, Receiverクラスは | |
138 DataSegmentを受けとるためのクラスである. | |
139 arg1に対しsetKey APIを使うことで, 使用したいDataSegmentのキー"count"を登録することができる. | |
140 これによりキー"count"に対してデータが登録された場合, そのデータを受け取りcsの計算が自動で始まる. | |
141 setKey APIの第一引数に渡している"local"はどのマシンのDataSegmentにアクセスするのかを指定している. | |
142 この場合は自分自身を表す"local"になる. | |
143 | |
62
2cb5ac9282b0
writed description of ods.put
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
61
diff
changeset
|
144 データの登録は\verb|ods.put|により行える. |
2cb5ac9282b0
writed description of ods.put
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
61
diff
changeset
|
145 上記のコード19行目ではputにより"count"をキーとして数値の0を登録している. |
2cb5ac9282b0
writed description of ods.put
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
61
diff
changeset
|
146 putがされるとcsの計算が始まり別スレッドにより8行目からの処理が行われる. |
50 | 147 |
62
2cb5ac9282b0
writed description of ods.put
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
61
diff
changeset
|
148 putによりキー"count"に登録された数値0はReceiverであるdsを使って取ることができる. |
50 | 149 7行目から13行目では\verb|ds.asInteger()|により, "count"に登録したデータの中身を受け取りインクリメントし出力する. |
102
6f73e05d5024
Fixed chapter4.tex
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
71
diff
changeset
|
150 そして, 最後には\verb|ods.put|を行っている. |
62
2cb5ac9282b0
writed description of ods.put
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
61
diff
changeset
|
151 新たなTestCodeSegmentも生成しており, これはインクリメントされた"count"がputされることで実行される. |
50 | 152 この一連の処理を"count"の数値が10以上になるまで行う. |
153 | |
154 DataSegmentへデータの追加とCodeSegmentの実行について表した図\ref{fig:testcodesegment}になる. | |
39
63eca978482f
Writed description of experiment
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
30
diff
changeset
|
155 \begin{figure}[htpb] |
63eca978482f
Writed description of experiment
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
30
diff
changeset
|
156 \begin{center} |
50 | 157 \includegraphics[scale=0.70]{figures/testcodesegment.pdf} |
158 \caption{DataSegmentとCodeSegmentによるプログラムの例} | |
159 \label{fig:testcodesegment} | |
160 \end{center} | |
161 \end{figure} | |
162 | |
62
2cb5ac9282b0
writed description of ods.put
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
61
diff
changeset
|
163 \newpage |
50 | 164 % Alice の他サーバノードへの"log"のputの問題 |
165 | |
166 \subsection{他サーバノードのDataSegmentへアクセス} | |
167 Aliceにおける基本的なプログラミングは述べた. | |
168 次はネットワークを介して他サーバノードのDataSegmentにアクセスするプログラムについて述べる. | |
169 | |
170 まず, Aliceにより2分木3ノードのトポロジーが形成された場合を想定する. | |
63
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
171 その時に実際に作られるトポロジーは図\ref{fig:remote_cs}となる. |
50 | 172 \begin{figure}[htpb] |
173 \begin{center} | |
174 \includegraphics[scale=0.70]{figures/remote_codesegment.pdf} | |
175 \caption{トポロジーの形成} | |
176 \label{fig:remote_cs} | |
177 \end{center} | |
178 \end{figure} | |
179 | |
180 ネットワークを介したDataSegmentへのアクセスはそのサーバノードを示す | |
181 文字列のキーを追加することで行える. | |
182 他サーバノードを示す文字列のキーとは図\ref{fig:remote_cs}に矢印の隣に書かれている文字列 | |
183 "parent", "child1", "child2" のことを指す. | |
184 例えば, server node0 が server node1のDataSegmentに入っている"count"というデータを | |
102
6f73e05d5024
Fixed chapter4.tex
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
71
diff
changeset
|
185 を使用したい場合は, 次のようにsetKeyを行えばよい(ソースコード\ref{src:remote_cs1}). |
50 | 186 \begin{lstlisting}[frame=lrbt,label=src:remote_cs1,caption=CodeSegmentで他サーバノードのDataSegmentを使用する,numbers=left] |
187 CodeSegment cs = new RemoteCodeSegment(); | |
188 cs.arg1.setKey("child1", "count"); | |
189 \end{lstlisting} | |
102
6f73e05d5024
Fixed chapter4.tex
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
71
diff
changeset
|
190 また, 他サーバノードのDataSegmentにデータを送りたい場合は, putを行うときにサーバノードへのキーを |
50 | 191 追加すればよい. |
102
6f73e05d5024
Fixed chapter4.tex
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
71
diff
changeset
|
192 例として, server node1やserver node2がserver node0のDataSegmentに"message"というキーでデータを追加したい場合は, 次のようになる(ソースコード\ref{src:remote_cs2}). |
50 | 193 \begin{lstlisting}[frame=lrbt,label=src:remote_cs2,caption=他サーバーノードのDatasSegmentにデータを追加する,numbers=left] |
194 ods.put("parent", "message", "Hello parent"); | |
195 \end{lstlisting} | |
196 | |
197 \subsection{独自クラスのインスタンスの送受信} | |
198 最後に, 独自クラスのインスタンスのDataSegmentでの扱い方について述べる. | |
199 AliceではMessagePackを用いてシリアライズを行い他サーバノードへと送信している. | |
62
2cb5ac9282b0
writed description of ods.put
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
61
diff
changeset
|
200 MessagePackはインスタンス単位でシリアライズを行うことができる. |
2cb5ac9282b0
writed description of ods.put
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
61
diff
changeset
|
201 そのため, Aliceでもプリミティブな型に限らずクラスのインスタンスをDataSegmentとして |
50 | 202 扱うことができる. |
203 | |
204 MessagePackによりシリアライズとなるクラスはいくつか制限がある. | |
205 それはそのクラスに@Messageアノテーションを付けることと, そのクラスが保持するフィールドが | |
206 MessagePackによりシリアライズ可能であることである. | |
102
6f73e05d5024
Fixed chapter4.tex
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
71
diff
changeset
|
207 例えば次のようなクラスである(ソースコード\ref{src:msgpack1}). |
50 | 208 \begin{lstlisting}[frame=lrbt,label=src:msgpack1,caption=MessagePackによりシリアライズ可能なクラス1,numbers=left] |
209 import org.msgpack.annotation.Message | |
210 | |
211 @Message | |
212 public class Student { | |
213 String name; | |
214 int age; | |
215 } | |
216 \end{lstlisting} | |
102
6f73e05d5024
Fixed chapter4.tex
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
71
diff
changeset
|
217 上記のStudentクラスはプリミティブ型しか保持していない. |
50 | 218 そのためシリアライズが可能である |
102
6f73e05d5024
Fixed chapter4.tex
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
71
diff
changeset
|
219 また, 次のようなクラスもシリアライズ可能な型となる(ソースコード\ref{src:msgpack2}). |
50 | 220 \begin{lstlisting}[frame=lrbt,label=src:msgpack2,caption=MessagePackによりシリアライズ可能なクラス2,numbers=left] |
221 import org.msgpack.annotation.Message | |
222 | |
223 @Message | |
224 public class Class { | |
225 List<Student> studentList; | |
226 } | |
227 \end{lstlisting} | |
102
6f73e05d5024
Fixed chapter4.tex
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
71
diff
changeset
|
228 この場合, フィールドはプリミティブな型でないStudentクラスのフィールドを保持している. |
50 | 229 しかし, Studentクラスはシリアライズ可能な形で作成しているため, クラスのフィールドとして |
230 保持しても問題はない. | |
231 | |
232 これらの制約にそった形で作成しDataSegmentにネットワークを介してクラスのインスタンス | |
62
2cb5ac9282b0
writed description of ods.put
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
61
diff
changeset
|
233 をputすることができる. |
50 | 234 DataSegmentから受け取ったデータはそのままではシリアライズされたものため, 一度手元で |
235 元のクラスにコンバートすることで扱う. | |
102
6f73e05d5024
Fixed chapter4.tex
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
71
diff
changeset
|
236 例として, AliceにおけるStudenクラスのコンバートを次に示す(ソースコード\ref{src:msgpack1}). |
50 | 237 \begin{lstlisting}[frame=lrbt,label=src:msgpack3,caption=DataSegment,numbers=left] |
238 // public Receiver arg1 = ids.create(CommandType.PEEK); | |
239 Student s = arg1.asClass(Student.class); | |
240 \end{lstlisting} | |
102
6f73e05d5024
Fixed chapter4.tex
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
71
diff
changeset
|
241 MessagePackでシリアライズ可能な形としているためDataSegmentはネットワークを介して |
50 | 242 送受信が可能である. |
243 | |
244 | |
245 \section{ログのシリアライズ} | |
246 Jungleの具体的な分散実装について述べる. | |
247 実装にあたり, 解決しなければならない問題はまず, ログをDataSegmentで扱える形にすることである. | |
248 そのためには, @Messageアノテーションを付けたログのクラスの作成を行わなければならない. | |
249 | |
250 | |
251 \subsection{TreeOperationLogのシリアライズ} | |
71 | 252 ログの実体であるTreeOperationLogをシリアライズ可能な形にするにあたって気をつけなければならないのが, フィールドを |
50 | 253 シリアライズ可能にする部分である. |
254 TreeOperationLogはTreeOperationをいくつも保持し, TreeOperationはNodePathとNodeOperationを保持するものであった. | |
69 | 255 そのため, これら全てをシリアライズ可能な形にしなければならない. |
50 | 256 |
257 基本的にこれらの実装は, フィールドを全てプリミティブなものだけにすればよい. | |
258 MessagePackはListを扱うこともできるため, TreeOperationLogで継承されていたIterableの挙動もListを使うことで | |
259 実装を行うことができた. | |
260 | |
71 | 261 \section{ログに対する情報の追加} |
50 | 262 TreeOperationLogをシリアライズ可能な形にした後, 問題が発生した. |
69 | 263 それは, TreeOperationLog自体は木の名前を保持していないというものである. |
50 | 264 そのため, TreeOperationLogだけを受け取っても, そのログがどの木に対して行われるのか |
265 わからなかった. | |
266 そこで, TreeOperationLogの情報だけでなく, 木の名前とUUID, それとtimestampの情報も付与 | |
267 してシリアライズが可能なNetworkTreeOperationLogの実装を行った. | |
268 | |
269 % TreeOperationLog に木の名前の情報がない | |
270 % そのため木の名前を追加して持たせた | |
271 % 木がなければそのばでつくるようにした | |
272 | |
62
2cb5ac9282b0
writed description of ods.put
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
61
diff
changeset
|
273 \subsection{NetworkTreeOperationLogの実装} |
102
6f73e05d5024
Fixed chapter4.tex
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
71
diff
changeset
|
274 NetworkTreeOperationLogの実装の一部を以下(図\ref{src:netlog})に示す. |
62
2cb5ac9282b0
writed description of ods.put
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
61
diff
changeset
|
275 \begin{lstlisting}[frame=lrbt,label=src:netlog,caption=NetworkTreeOperationが持つフィールド,numbers=left] |
2cb5ac9282b0
writed description of ods.put
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
61
diff
changeset
|
276 @Message |
2cb5ac9282b0
writed description of ods.put
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
61
diff
changeset
|
277 public class NetworkTreeOperationLog implements TreeOperationLog |
2cb5ac9282b0
writed description of ods.put
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
61
diff
changeset
|
278 { |
2cb5ac9282b0
writed description of ods.put
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
61
diff
changeset
|
279 public LinkedList<NetworkTreeOperation> list; |
2cb5ac9282b0
writed description of ods.put
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
61
diff
changeset
|
280 String treeName; |
2cb5ac9282b0
writed description of ods.put
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
61
diff
changeset
|
281 long timestamp; |
2cb5ac9282b0
writed description of ods.put
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
61
diff
changeset
|
282 \end{lstlisting} |
2cb5ac9282b0
writed description of ods.put
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
61
diff
changeset
|
283 Listにより保持しているNetworkTreeOperationはTreeOperationをシリアライズ可能な形にしたものである. |
2cb5ac9282b0
writed description of ods.put
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
61
diff
changeset
|
284 TreeOperationLogをimplementsし, 木の名前とtimestampをを保持する. |
2cb5ac9282b0
writed description of ods.put
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
61
diff
changeset
|
285 他サーバノードへ伝える必要のある情報が増えた場合, このようにNetworkTreeOperationLogに情報を付与することで |
2cb5ac9282b0
writed description of ods.put
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
61
diff
changeset
|
286 対応することができる. |
2cb5ac9282b0
writed description of ods.put
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
61
diff
changeset
|
287 |
63
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
288 \subsection{ログの送信部分} |
62
2cb5ac9282b0
writed description of ods.put
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
61
diff
changeset
|
289 ログを送信するタイミングはいつ行うか. |
2cb5ac9282b0
writed description of ods.put
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
61
diff
changeset
|
290 それは, 木の編集が成功した時である. |
2cb5ac9282b0
writed description of ods.put
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
61
diff
changeset
|
291 木の編集が成功した結果得られるTreeOperationLogをNetworkTreeOperationLogに変換し, \verb|ods.put|を使って |
2cb5ac9282b0
writed description of ods.put
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
61
diff
changeset
|
292 CodeSegment側から利用できるようにする. |
2cb5ac9282b0
writed description of ods.put
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
61
diff
changeset
|
293 |
2cb5ac9282b0
writed description of ods.put
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
61
diff
changeset
|
294 しかし, この時気をつけなければならないことがある. |
2cb5ac9282b0
writed description of ods.put
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
61
diff
changeset
|
295 それは, \verb|ods.put|の処理をレスポンスを返すスレッドの中で行うと, レスポンスが悪くなる可能性が |
2cb5ac9282b0
writed description of ods.put
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
61
diff
changeset
|
296 あることだ. |
2cb5ac9282b0
writed description of ods.put
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
61
diff
changeset
|
297 そのため, \verb|ods.put|を行うのは別のThreadにしたほうがよい. |
69 | 298 以下のコードはcommitに成功した後に, NetworkTreeOperationへと変換したログを別スレッドに渡し |
102
6f73e05d5024
Fixed chapter4.tex
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
71
diff
changeset
|
299 て処理させるコードである(ソースコード\ref{src:logconvert_and_execute}). |
62
2cb5ac9282b0
writed description of ods.put
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
61
diff
changeset
|
300 \begin{lstlisting}[frame=lrbt,label=src:logconvert_and_execute,caption=NetworkTreeOperationをputするために別スレッドを立ち上げる,numbers=left] |
2cb5ac9282b0
writed description of ods.put
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
61
diff
changeset
|
301 NetworkTreeOperationLog netLog = new NetworkTreeOperationLog(_uuid, _treeName,newLog); |
2cb5ac9282b0
writed description of ods.put
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
61
diff
changeset
|
302 CodeSegment cs = new LogPutCodeSegment(netLog); |
2cb5ac9282b0
writed description of ods.put
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
61
diff
changeset
|
303 cs.execute(); |
2cb5ac9282b0
writed description of ods.put
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
61
diff
changeset
|
304 \end{lstlisting} |
2cb5ac9282b0
writed description of ods.put
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
61
diff
changeset
|
305 |
102
6f73e05d5024
Fixed chapter4.tex
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
71
diff
changeset
|
306 LogPutCodeSegmentの実装は次のようになっている(ソースコード\ref{src:logputcs}). |
6f73e05d5024
Fixed chapter4.tex
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
71
diff
changeset
|
307 \begin{lstlisting}[frame=lrbt,label=src:logputcs,caption=putを行うためだけのCodeSegmentの用意,numbers=left] |
69 | 308 public class LogPutCodeSegment extends CodeSegment{ |
309 NetworkTreeOperationLog log; | |
310 public LogPutCodeSegment(NetworkTreeOperationLog _log) { | |
311 log = _log; | |
312 } | |
313 @Override | |
314 public void run() { | |
315 ods.put("log", log); | |
316 } | |
62
2cb5ac9282b0
writed description of ods.put
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
61
diff
changeset
|
317 } |
2cb5ac9282b0
writed description of ods.put
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
61
diff
changeset
|
318 \end{lstlisting} |
102
6f73e05d5024
Fixed chapter4.tex
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
71
diff
changeset
|
319 上で述べた問題は, ベンチマークテストなど, 大量の負荷をかけたさいに発生する. |
69 | 320 負荷とはJungleのデータに変更が加わることである. |
321 多数のデータの変更により大量のログが生成される. | |
62
2cb5ac9282b0
writed description of ods.put
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
61
diff
changeset
|
322 そのため, \verb|ods.put|によりDataSegmentの"log"にアクセスが集中してしまい, レスポンスが |
2cb5ac9282b0
writed description of ods.put
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
61
diff
changeset
|
323 悪くなっていた. |
2cb5ac9282b0
writed description of ods.put
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
61
diff
changeset
|
324 \verb|ods.put|を行うタイミングには気をつけなければず, 上記のコードにしても改良の余地はある. |
2cb5ac9282b0
writed description of ods.put
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
61
diff
changeset
|
325 |
63
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
326 \subsection{他サーバノードへのログの送信} |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
327 上記の実装によりDataSegmentの"log"キーにアクセスすることでTreeOperationLogを取得できるようになった. |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
328 次はこのデータを他サーバノードへ送る部分の実装を行う. |
62
2cb5ac9282b0
writed description of ods.put
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
61
diff
changeset
|
329 |
63
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
330 他サーバノードに対してデータを送るときに必要なことは, そのサーバノードのDataSegmentにアクセスする |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
331 キーである. |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
332 Aliceでは接続を行っている相手のDataSegmentのキーのリストは"\_CLIST"キーを使うことで取得することができる. |
102
6f73e05d5024
Fixed chapter4.tex
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
71
diff
changeset
|
333 "\_CLIST"キーで得られるリストを使って他サーバノードへとデータをputするコードを次に示す(ソースコード\ref{src:log_put}). |
62
2cb5ac9282b0
writed description of ods.put
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
61
diff
changeset
|
334 |
69 | 335 \newpage |
63
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
336 \begin{lstlisting}[frame=lrbt,label=src:log_put,caption=他サーバノードへのログの送信部分,numbers=left] |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
337 public class LogUpdateCodeSegment extends CodeSegment { |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
338 Receiver log = ids.create(CommandType.TAKE); |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
339 Receiver clist = ids.create(CommandType.PEEK); |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
340 |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
341 public LogUpdateCodeSegment() { |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
342 log.setKey("log"); |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
343 clist.setKey("_CLIST");; |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
344 } |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
345 |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
346 List<String> list = clist.asClass(List.class); |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
347 for (String node : list) { |
69 | 348 ods.put(node, log.key, log.getVal()); // Send datasegment to other node |
63
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
349 } |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
350 : |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
351 \end{lstlisting} |
102
6f73e05d5024
Fixed chapter4.tex
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
71
diff
changeset
|
352 12行目の\verb|ods.put(node, log.key, log.getVal())|が他サーバノードへデータを送る部分になる. |
69 | 353 変数logにはNetworTreeOperationLogが入っている. |
63
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
354 変数listには"\_CLIST"により得られたデータが入っている. |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
355 それは文字列のListとなっている. |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
356 listの中身を1つずつ受け取り, \verb|ods.put|する際に引数として渡してやることで, 他サーバノードの |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
357 DataSegmentにアクセスが行える. |
62
2cb5ac9282b0
writed description of ods.put
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
61
diff
changeset
|
358 |
63
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
359 listの具体的な内容は, 図\ref{fig:tree_topology}で組まれたトポロジーでいうところの, "parent", "child1", "child2" |
69 | 360 の文字列のListとなっている. |
63
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
361 もし子どもとなるサーバノードがないときは"parent"だけがListには入れられる. |
62
2cb5ac9282b0
writed description of ods.put
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
61
diff
changeset
|
362 |
63
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
363 \subsection{ログの受信とデータ反映} |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
364 次は受け取ったログからデータの編集を行う部分の実装を行う. |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
365 Jungleはのデータを変更する手段として木構造データ毎にTreeEditorクラスが提供される. |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
366 このTreeEditorを使用し, ログに入っているTreeOperationを1つ1つ取り出し同じ編集を行わせる. |
102
6f73e05d5024
Fixed chapter4.tex
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
71
diff
changeset
|
367 例えば次のようになる(ソースコード\ref{src:data_edit}). |
63
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
368 \begin{lstlisting}[frame=lrbt,label=src:data_edit,caption=ログを受け取ってのデータの反映,numbers=left] |
69 | 369 // Receiver log <- "log"キーから取得できるデータが入っている |
63
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
370 // Jungle jugnle |
69 | 371 NetworkTreeOperationLog netLog = log.asClass(NetworkTreeOperationLog.class); |
63
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
372 String treeName = netLog.getTreeName(); |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
373 JungleTree tree = jungle.getTreeByName(treeName); |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
374 TreeEditor editor = tree.getLocalTreeEditor(); // Editor の取得 |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
375 for (TreeOperation op : netlog) { |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
376 NodePath path = op.getNodePath(); |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
377 NodeOperation nodeOp = op.getNodeOperation(); |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
378 either = edit(editor, path, nodeOp, nodeOp.getPosition()); // データの編集を行う. |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
379 if(either.isA()) { |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
380 // エラー処理.編集失敗 |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
381 } |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
382 editor = either.b(); |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
383 } |
62
2cb5ac9282b0
writed description of ods.put
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
61
diff
changeset
|
384 \end{lstlisting} |
102
6f73e05d5024
Fixed chapter4.tex
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
71
diff
changeset
|
385 7行目で取り出されたTreeOperationからさらにNodePathとNodeOperationを取り出しているのが8行目と9行目になる. |
63
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
386 最後にedit関数にTreeEditorとNodePath, それとNodeOpeartionを引き渡している. |
102
6f73e05d5024
Fixed chapter4.tex
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
71
diff
changeset
|
387 edit関数は次のようになる(ソースコード\ref{src:data_edit2}). |
69 | 388 \begin{lstlisting}[frame=lrbt,label=src:data_edit2,caption=edit関数の実装,numbers=left] |
63
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
389 Either<Error, JungleTreeEditor> edit(JungleTreeEditor editor, NodePath path, |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
390 NodeOperation nodeOp, int pos) { |
69 | 391 String key = ""; |
63
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
392 Command c = nodeOp.getCommand(); |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
393 switch (c) { |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
394 case PUT_ATTRIBUTE: |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
395 key = nodeOp.getKey(); |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
396 ByteBuffer value = nodeOp.getValue(); |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
397 return editor.putAttribute(path, key, value); |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
398 case DELETE_ATTRIBUTE: |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
399 key = nodeOp.getKey(); |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
400 return editor.deleteAttribute(path, key); |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
401 case APPEND_CHILD: |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
402 return editor.addNewChildAt(path, pos); |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
403 case DELETE_CHILD: |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
404 return editor.deleteChildAt(path, 0); |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
405 } |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
406 \end{lstlisting} |
102
6f73e05d5024
Fixed chapter4.tex
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
71
diff
changeset
|
407 NodeOperationのAPIの種類(Command)毎に使用するTreeEditorのAPIを変えている. |
63
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
408 もしNodeOperationのAPIの種類を増えるようなことが合っても, 上記のコードのように |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
409 対応するTreeEditorのAPIを書くことで対応できる. |
62
2cb5ac9282b0
writed description of ods.put
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
61
diff
changeset
|
410 |
63
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
411 %\subsection{ローカルのデータ編集専用のTreeEditorの用意} |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
412 %データ編集が行われ, |
62
2cb5ac9282b0
writed description of ods.put
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
61
diff
changeset
|
413 |
69 | 414 \newpage |
63
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
415 \section{永続性の実装} |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
416 次は, ログの書き出しによる永続性の実装について述べる. |
71 | 417 第3章でJungleはWriterという永続性実装のための機能が元々用意されていることを述べた. |
63
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
418 永続性で考えなければならないことは, どのようなデータをどんなデータ表現で書き込むかということである. |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
419 今回の実装ではログであるTreeOperationLogを書き出す. |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
420 また, TreeOperationLogの情報を保持しつつ, MessagePackでシリアライズできるクラスとして |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
421 NetworkTreeOperationLogの実装を行った. |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
422 |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
423 つまり, WriterでNetworkTreeOperationLogを書き出すようにすればよい. |
102
6f73e05d5024
Fixed chapter4.tex
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
71
diff
changeset
|
424 以下にログをディスクへ書き出すためのクラスPersistentChangeListWriterの実装を示す(ソースコード\ref{src:writer}). |
69 | 425 \begin{lstlisting}[frame=lrbt,label=src:writer,caption=NetworkTreeOperationをディスクへ書き出す,numbers=left] |
63
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
426 public class PersistentChangeListWriter implements ChangeListWriter { |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
427 |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
428 MessagePack msgpack; |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
429 OutputStream out; |
50 | 430 |
63
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
431 public PersistentChangeListWriter(OutputStream _out, MessagePack _msgpack) { |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
432 out = _out; |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
433 msgpack = _msgpack; |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
434 } |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
435 @Override |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
436 public Result write(ChangeList cs) |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
437 { |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
438 NetworkTreeOperationLog log |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
439 = new NetworkTreeOperationLog(cs.uuid(), cs.getTreeName(), cs); |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
440 try { |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
441 msgpack.write(out, log); |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
442 out.flush(); |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
443 return Result.SUCCESS; |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
444 } catch (IOException e) { |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
445 // エラー処理 |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
446 } |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
447 return Result.FAILED; |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
448 } |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
449 \end{lstlisting} |
102
6f73e05d5024
Fixed chapter4.tex
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
71
diff
changeset
|
450 write関数はJungleのデータ編集が完了すると呼び出される関数である. |
63
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
451 引数として渡されているChangeListはTreeOperationLogと同じく\verb|Iterable<TreeOperation>|を継承している. |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
452 またUUIDや木の名前も取得することができる. |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
453 そのため, NetworkTreeOperationLogへと変換が行える. |
50 | 454 |
63
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
455 ログの書き出しを行いたいときはこのPersistentChangeListWriterを設定することで行えるようになった. |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
456 これにより木の編集が行われるたびにNetworkTreeOperationLogが書き込まれていく. |
d770a2b534b3
Writed description of persistent
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
62
diff
changeset
|
457 読み込みたいときはMessagePackを使ってディスクから読み込み, データ分散実装と同じの方法で木の編集を行っていく |
102
6f73e05d5024
Fixed chapter4.tex
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
71
diff
changeset
|
458 ことができる(ソースコード\ref{src:data_edit}, \ref{src:data_edit2}). |
50 | 459 |
460 | |
69 | 461 \newpage |
462 \section{Mergeの実装} | |
50 | 463 Jungle に分散実装を行った後の問題としてデータ衝突がある. |
464 他のサーバノードから送られてくるデータが既に手元で変更を加えた木構造を対象とした | |
465 場合に発生する問題である. | |
69 | 466 Jungle ではこれをアプリケーション毎にMergeを実装することで解決させる. |
467 | |
468 \section{掲示板プログラムにおけるデータ衝突} | |
50 | 469 |
470 今回分散実装を行い, 例題として掲示板プログラムを用意した. | |
69 | 471 掲示板プログラムに実装を行ったMergeについて述べる. |
50 | 472 まず Jungle を用いた掲示板プログラムのデータ保持方法を図\ref{fig:merge2}に示す. |
473 \begin{figure}[htpb] | |
474 \begin{center} | |
475 \includegraphics[scale=0.70]{figures/merge2.pdf} | |
476 \caption{Jungle による掲示板プログラムのデータ保持方法} | |
477 \label{fig:merge2} | |
478 \end{center} | |
479 \end{figure} | |
480 | |
481 掲示板プログラムでは各掲示板毎に1つの木構造が作成される. | |
482 掲示板への1つの書き込みは子ノードを1つ追加することに相当する. | |
483 また, 各子ノードは attributes として書き込みの内容である message と書き込まれた時間を表す timestamp を保持している. | |
484 先に追加された順で子ノードには若い番号が割り振られる. | |
485 | |
486 他サーバノードからの書き込みをそのまま子ノードの後ろに追加してしまうと, データの整合性が崩れてしまう. | |
487 この時の状態を表しているのが図\ref{fig:merge_imp1}と\ref{fig:merge_imp2}になる. | |
488 \begin{figure}[htpb] | |
489 \begin{center} | |
490 \includegraphics[scale=0.70]{figures/merge_imp1.pdf} | |
491 \caption{他サーバノードの編集データ反映による整合性の崩れ1} | |
492 \label{fig:merge_imp1} | |
39
63eca978482f
Writed description of experiment
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
30
diff
changeset
|
493 \end{center} |
63eca978482f
Writed description of experiment
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
30
diff
changeset
|
494 \end{figure} |
63eca978482f
Writed description of experiment
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
30
diff
changeset
|
495 |
63eca978482f
Writed description of experiment
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
30
diff
changeset
|
496 \begin{figure}[htpb] |
63eca978482f
Writed description of experiment
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
30
diff
changeset
|
497 \begin{center} |
50 | 498 \includegraphics[scale=0.70]{figures/merge_imp2.pdf} |
499 \caption{他サーバノードの編集データ反映による整合性の崩れ2} | |
500 \label{fig:merge_imp2} | |
39
63eca978482f
Writed description of experiment
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
30
diff
changeset
|
501 \end{center} |
63eca978482f
Writed description of experiment
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
30
diff
changeset
|
502 \end{figure} |
63eca978482f
Writed description of experiment
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
30
diff
changeset
|
503 |
50 | 504 \newpage |
39
63eca978482f
Writed description of experiment
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
30
diff
changeset
|
505 |
69 | 506 \subsection{掲示板プログラムにおけるMerge} |
507 | |
50 | 508 図\ref{fig:merge_imp2}の server node0 の木の状態にするのが理想である. |
509 掲示板のへの書き込みの表示は, 書き込みされた時間が早い順に表示されるようにしたい. | |
510 これを timestamp を利用することで行う. | |
511 他サーバノードから来たデータに関しては, timestamp を参照し, 次に自分の保持している | |
512 木の子ノードの timestamp と比べていくことでデータの追加する場所を決める. | |
69 | 513 これが今回実装を行った掲示板システムにおけるMergeになる. |
39
63eca978482f
Writed description of experiment
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
30
diff
changeset
|
514 |
50 | 515 %単一サーバで動いている時の Jungle はただ子ノードとして後ろに追加するだけだが, 分散 |
516 %環境下においては timestamp に従い子ノードを追加する位置を決めるようにする. | |
41
a59ede6b5a5a
Writed chapter4
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
40
diff
changeset
|
517 |
a59ede6b5a5a
Writed chapter4
Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
40
diff
changeset
|
518 |