view paper/sigos.tex @ 24:64a017ca89a4

done
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 23 Apr 2018 23:01:03 +0900
parents b81702f6108a
children 8bad8d17b4c1
line wrap: on
line source

\documentclass[techrep]{ipsjpapers}
\usepackage[dvipdfmx]{graphicx}
\usepackage{url}
\usepackage{listings,jlisting}
\usepackage{enumitem}


\lstset{
    language=C, 
    tabsize=2, 
    frame=single, 
    basicstyle={\ttfamily\footnotesize},% 
    identifierstyle={\footnotesize},% 
    commentstyle={\footnotesize\itshape},% 
    keywordstyle={\footnotesize\bfseries},% 
    ndkeywordstyle={\footnotesize},% 
    stringstyle={\footnotesize\ttfamily}, 
    breaklines=true, 
    captionpos=b, 
    columns=[l]{fullflexible},% 
    xrightmargin=0zw,% 
    xleftmargin=1zw,% 
    aboveskip=1zw, 
    numberstyle={\scriptsize},% 
    stepnumber=1, 
    numbersep=0.5zw,% 
    lineskip=-0.5ex, 
}
\renewcommand{\lstlistingname}{Code}

\input{dummy.tex} %% Font 

% ユーザが定義したマクロなど.
\makeatletter

\begin{document}

% 和文表題
\title{分散フレームワークChristieと分散木構造データベースJungle}
% 英文表題
\etitle{}

% 所属ラベルの定義
\affilabel{1}{琉球大学工学部情報工学科\\Information Engineering, University of the Ryukyus.}

% 和文著者名
\author{
    河野 真治\affiref{1}
}

% 英文著者名
\eauthor{
    Shinji KONO\affiref{1}
}

% 連絡先(投稿時に必要.製版用では無視される.)
\contact{河野真治\\
        〒903-0213 沖縄県西原町千原1番地\\
	琉球大学工学部情報工学科\\
        TEL: (098)895-2221\qquad FAX: (098)895-8727\\
        email: kono@ie.u-ryukyu.ac.jp}



% 和文概要
\begin{abstract}
現代のインターネットやアプリケーションで使われるデータは、複雑な構造を持っており、RDBの第一正規系には納まらないようになってきている。
また、RDBでは、編集中にロックがかけられ、複雑な構造に対する変更に向いていない。
これらの問題は、不定形のデータ構造とRDBの表構造のミスマッチである。
これをDBのインピーダンスミスマッチと言うことがある。
そこで当研究室では、非破壊的木構造データベースJungleを開発している。
Jungleでは、不定形のデータ構造を、直接木構造として格納することができる。
木構造の変更は、過去の版を保存する非破壊で行われ、木のルートをAtomicに入れ替える操作がトランザクションになる。
これにより、複雑な構造をDBとして素直に取り扱うことができる。
木構造の変更は、木の形に依存している。
サービスやアプリケーションに適した木の形があり、それに対応した木の変更方法を採用する必要がある。
本研究ではJungleの木と Index の編集機能の改善を行う。
直線的なリスト構造に適したPush/Popと差分リストを提案し、実装と評価を行なった。
巨大な木が必要な場合は、木を特定のKeyを用いてbalanceさせることにより、変更をO(log n)にすることができる。
Jungleは分散構造を取ることもできる。
複数の木を複数の分散したJungleノード間で通信することにより、Jungleをスケールさせる。
Jungleの木の変更Logを当研究室で開発した分散フレームワークAlice\cite{kono16a}を用いて通信する。
それぞれの木は、ルートノードに集約され、集約の過程で、競合する変更のMergeを行う。
分散Jungleの性能を測定する手法について述べる。
\end{abstract}

% 表題などの出力
\maketitle

% 本文はここから始まる

% Introduce
\section{分散アプリケーションとフレームワーク}
現代のサービスはInternetと切り離せない形で提供されている。それらは比較的ad-hocに開発発展してきたHTTP上に構築されている。
一方で、分散データベースや分散プログラムをサポートするフレームワークの研究も古くから行われてきている。例えば、
MySQLやPostgressなどのオープンソースデータベースでもリプリケーションなどの分散技術を採用するようになってきている。
HTTPもセキュリティを重視したHTTPSや、HTTP上のファイル変更プロトコルであるWebDAVなどが導入されてきている。
残念ながら、いまだに定番の分散フレームワークは存在せず、分散データベースも広く使われるようにはなっていない。
古くに提案された分散フレームワークCORBAや、KVSとして導入されたCassandraあるいはHDFSなども企業内ネットワークで
使われるに留まっている。

現代のOSには階層型ファイルシステムが必須なものとして備わっており、ファイルシステムの分散版が使われるようになると期待された
時期もあった。Andrew File System などが設計されたが、広く使われるにはいたらなかった。
本論文では、当研究室で開発してきた分散フレームワークAliceと、それを用いて実装された分散木構造データベースJungleを
見直すことにより、幅広く使われる分散サービスを構築するためのフレームワークのあるべき姿について考察する。


\section{分散フレームワークAlice}
ネットワーク上のサービスには、利用者数の爆発的な増加を受け入れるスケールアウト(サーバの数を増やすことによりサービスの質を維持する手法)
が必須である。
安定したネットワークサービスを提供するためには、分散プログラムに信頼性とスケーラビリティが要求される。
ここでいう信頼性とは、定められた環境下で安定して仕様に従った動作を行うことを指す。

分散プログラムには以下の3つの要素がある\cite{kono05f}。
\begin{itemize}
\item {ノード内の計算}
\item {ノード間通信}
\item {地理的に分散したノード}
\end{itemize}

本研究室で開発された分散フレームワーク
Aliceは、タスクをCode Segment、データをData Segmentという単位で記述し、Code SegmentはインプットとなるData Segmentが全て揃うと並列に実行される。
Data Segmentは対になるkeyが存在し、Data Segment Managerというノードごとに存在する独自のデータベースによって管理されている。
通信する各ノードに対応するラベル付きのプロキシであるRemote Data Segment Managerを立て、ラベルとkeyを指定してデータをtake/putする。
Linda のTuple spaceをノード毎に用意したような構造になっている。Linda と異なり、Tuple space が全世界で一つということはない。

AliceではTopologyManagerという機構が分散ノードを管理しており、静的・動的なトポロジーを自動構成する。静的トポロジーではプログラマがトポロジーを図として記述できるため
、より分かりやすく詳細な設定ができる。
TopologyManager内にはKeepAliveという機能があり、常にノードが生きているかHeartbeatを送信して監視しており、どこかのノードに障害が起こればトポロジーを再構成す
るといった対応ができる。

\section{木構造分散データベースJungle}

Web上の情報は複雑な木構造を持っていて、それを相互に参照する形式を持っている。Web上の相互参照はURIによるものだが、URIの存在は保証されているわけではなく、
リンク切れなどが存在する。広く使われるようになったRDBは、基本的にはネスト構造を持たない表の集まりであり、Web上の情報には直接は対応しない。
そこで、本研究室では木構造を直接扱うデータベースJungle を提案している。Jungle では、
木構造を扱えることによって、従来のRDBとは異なり、XMLやJsonで記述された構造を、データベースを設計することなく読み込むことが可能である。
Jungle では非破壊的木構造を採用している。データの元の木を直接書き換えずに保存し、新しく構築した木のデータ構造を編集する方法である。
木構造は、そのルートをAtomic に書き換えることにより、その変更の整合性を維持する。ルート複数存在しURIに相当するラベルを持っている。
木に対する変更をlogとして記録し、それをAliceによって通信し、分散データベースを構成している。

Jungle では、木のノードの位置を NodePath クラスを使って表す。 NodePath クラスはルートノードからスタートし、対象のノードまでの経路を数字を用いて指し示す。また、ルートノードは例外として-1と表記される。 NodePath クラスを用いて \textless -1,0,2,3 \textgreater を表している際の例を(図\ref{fig:nodepath})に示す。
\begin{figure}[htpb]
    \begin{center}
        \includegraphics[width=50mm]{pic/nodepath.pdf}
    \end{center}
        \caption{NodePath}
        \label{fig:nodepath}
\end{figure}

木のノードを他の木から参照することが必要な場合には、ノードにIndexを張ることができる。
Jungleは、非破壊的木構造というデータ構造上、過去の版の木構造を全て保持している。よって、すべての版に独立したIndexが必要となるため、前の版のIndexを破壊すること無く、Indexを更新する必要がある。
そのために非破壊なRed Black Tree をJava上に開発した。

Jungleは、読み込みは高速に行える反面、書き込みの手間は木の形・大きさに依存している。
通常の変更ではルートから編集を行う位置までのノードの複製を行う。そのため、木の編集の手間は、木構造の形によって異なる。特に線形の木は、全てのノードの複製を行うため、変更の手間がO(n)になってしまう。
それに対処するために、木の変更アルゴリズムを三種提供している。

線形の木をO(1)で変更するPushPop は、ルートノードの上に新しいルートノードを付け加える API である、木の複製を行う必要が無いため、木の変更の手間がO(1)でノードの追加を行える。

しかし、PushPopはルートノードを追加していくため、ノードの並びが逆順になってしまう。Logなどの正順を要求する場合に対処するために、
Differential Jungle Tree の実装を行なった。 Differential Jungle Tree は。木のバージョンごとに、自身の木の最後尾を表す末尾ノードを保持する。木の編集は、別途構築したSub Tree に対して破壊的に更新を行い、Commit 時に末尾のノードに Sub Tree を Append することで行う。この場合は木が破壊的に変更されているように見えるが、前の版の末端部分を超えてアクセスすることがなければ複数の版を同時に使用することができる。

完全にランダムな変更が巨大な木に対して必要な場合には、Jungleの木そのものをRed Black Tree として構築する手法を使うことができる。この場合は木の構造を固定することはできないが、
O(log n)での木の変更が可能になる。これは表構造そのものになる。これにより、Jungle をRDBして使うことも可能になった。Reb Black Jungle Tree 用には専用のNode Pathが提供される。


\section{Jungleの分散構成}

Jungle で木構造を分散させるために、Alice による通信を使用する。木への変更をコマンドログとして記録し、それをAliceを用いて他のノードに転送する。
他のノードはログに従って自分の持っている木を変更する。複数のノードで変更を共有する手法は様々なものが開発されてきているが、現在は以下のような
簡単なものを実装している。

まず、ノードを木構造に接続する。変更ログを自ノードに接続されているノードに向かって送信する。受けとったノードは自分の木を変更したのち、
送られてきたノード以外の自分のノードに接続されているノードに変更ログを転送する(Split Horizon)。この方法では全部のノードに単純に
変更が伝搬する。変更が衝突した場合は、Merge処理を行う。Merge 処理は失敗しないと仮定する。Merge処理による変更は他ノードに転送しない。
失敗しないMergeは一般的な整合性を保証することはできないが、SNSへの投稿などの場合では十分に機能する。今回は分散実装の確認のために
簡単な方法を実装した。多数決などの複雑な分散機構を載せることも将来的には可能である。
通信部分はAliceを用いて実装されているので、Jungleの分散構成は Alice のToplogy Manager によって動的あるいは静的に構成される。

\begin{figure}[htbp]
    \centering
    \includegraphics[width=50mm]{pic/tree.pdf}
    \caption{ツリー型のトポロジー}
    \label{fig:tree}
\end{figure}

(図\ref{fig:tree})の矢印の流れを以下に示す。
\begin{enumerate}
 \item servernode 1, servernode 2からきたデータがservernode 0 で衝突。
 \item 衝突したデータのMergeが行われる。
 \item Mergeされたデータがservernode 1,servernode 2へ伝搬
 \item servernode1からMergeされたデータがservernode 3、servernode 4へ伝搬。全体でデータの整合性が取れる。
\end{enumerate}


\section{JungleとAliceの問題点}

Jungleの分散実装を行う時に、Aliceで分散プログラムを記述させる時の問題点がいくつか明らかになった。

まず、Jungle とAlice の機能の重複がある。Alice を採用したのは簡単にJungleの分散構成を実現するためだが、Jungle もAliceも、一種の
データベースであり、キーにより木構造あるいはオブジェクトを格納している。差は扱うデータが木構造かどうかと、トランザクションの取扱いの違いである。

Alice はDataSegmentをキーにより通信するが、このキーはプログラムの任意の位置からアクセスすることができる。つまり大域変数的に扱うことが可能である。
DataSegment へのアクセスはキーを取得したCodeSegmentのみであり、変更はキューに格納され、読み出しはキューに沿って行われる。従って、通常の大域変数
と違い、並列実行時に不整合が起きることはない。しかし、キーが大域的に見えているので、DataSegmentへのアクセスをモジュール内などに制限することは難しい。

現状のJungleの木のノードには属性と値の組があり、DBのレコードとして機能するが、値として使えるのはByteBufferであり型を持っていない。
Jungle のトランザクションはEitherという方法で実装されており、細かいエラーチェックを行う必要があり煩雑である。

Alice のDataSegmentの管理は Singleton で実装されており、同一プロセス上で複数のAliceのインスタンスを立ち上げることができない。これにより
分散アルゴリズムのテストを単一プロセスで行うことができないという問題がある。また、NAT越えの実装を行う時にも複数のプロセスが必要になって
しまう。

現状のAlice の記述方法が煩雑で、型の整合性をコンパイル時に指定できない。これに付いては次節でさらに詳しく述べる。


\section{CodeSegmentの記述方法}
CSをユーザーが記述する際にはCodeSegmentクラスを継承して記述する(ソースコード \ref{src:StartCodeSegment} , \ref{src:CodeSegment})。
継承することによりCode Segmentで使用するData Segment APIを利用する事ができる。

Alice には、Start CS (ソースコード \ref{src:StartCodeSegment} )というC の main に相当するような最初に
実行される CS がある。
Start CSはどのDSにも依存しない。つまりInput DSを持たない。
このCSをmainメソッド内でnewし、executeメソッドを呼ぶことで実行を開始させることができる。


\lstinputlisting[label=src:StartCodeSegment, caption=StartCodeSegment]{source/StartCodeSegment.java}
\lstinputlisting[label=src:CodeSegment, caption=CodeSegment]{source/TestCodeSegment.java}

\newpage

ソースコード \ref{src:StartCodeSegment} は、5行目で次に実行させたいCS(ソースコード \ref{src:CodeSegment} )を作成している。
8行目でOutput DS APIを通してLocal DSMに対してDSをputしている。
Output DS APIはCSの{\tt ods}というフィールドを用いてアクセスする。
{\tt ods}は{\tt put}と{\tt update}と{\tt flip}を実行することができる。
TestCodeSegmentはこの"cnt"というkeyに対して依存関係があり、8行目でputが行われるとTestCodeSegmentは実
行される。


CSのInput DSは、CSの作成時に指定する必要がある。指定はCommandType(PEEKかTAKE)、DSM名、そしてkey よっ
て行われる。
Input DS API はCSの{\tt ids}というフィールドを用いてアクセスする。
Output DSは、{\tt ods}が提供するput/update/flipメソッドをそのまま呼べばよかったが、Input DSの場合{\tt ids}にpeek/takeメソッドはなく、create/setKeyメソッド内でCommandTypeを指定して実行する。

ソースコード\ref{src:CodeSegment}は、0から9までインクリメントする例題である。
2行目では、Input DS APIがもつcreateメソッドでInput DSを格納する受け皿(Receiver)を作っている。
引数には{\tt PEEK}または{\tt TAKE}を指定する。
\begin{itemize}
\item {\ttfamily Receiver create(CommandType type)}
\end{itemize}

4行目から6行目はコンストラクタである。コンストラクタはオブジェクト指向のプログラミング言語で新たなオ
ブジェクトを生成する際に呼び出されて内容の初期化を行う関数である。

 TestCodeSegmentのコンストラクタが呼ばれた際には、
 \begin{enumerate}
 \item CSが持つフィールド変数 {\tt Receiver input}に{\tt ids.create(CommandType.TAKE)}が行われ、{\tt input}が初期化される。
 \item 5行目にあるTestCodeSegmentのコンストラクタのTAKEが実行される。
 \end{enumerate}

5行目は、2行目のcreateで作られたReceiverが提供するsetKeyメソッドを用いてLocal DSMからDSを取得している。
\begin{itemize}
\item \verb+void setKey(String managerKey, String key)+
\end{itemize}
setKeyメソッドはpeek/takeの実行を行う。どのDSMのどのkeyに対してpeekまたはtakeコマンドを実行させるかを指定できる。コマンドの結果がレスポンスとして届き次第CSは実行される。

\newpage

実行されるrunメソッドの内容は
\begin{enumerate}
\item 10行目で取得されたDSをInteger型に変換してcountに代入する。
\item 12行目でcountをインクリメントする。
\item 16行目で次に実行されるCSを作る。run内の処理を終えたらCSは破棄されるため、処理を繰り返したい場合はこのように新しいくCSを作る必要がある。この時点で次のCSはInput DSの待ち状態に入る。
\item 17行目でcountをLocal DSMにputする。Input DSが揃い待ち状態が解決されたため、次のCSが実行される。
\item 13行目が終了条件であり、countの値が10になれば終了する。
 \end{enumerate}
となっている。

1.で用いられているasInteger()はasClassメソッドの一部であり、asClassはtake/peekで取得したDSをObject型から任意の型で取得するためのAPIである。

\begin{itemize}
    \item {\ttfamily <T> T asClass(Class<T> clazz)}
\end{itemize}

CS内でDSのデータを扱うには、正しい型を意識しながらこのasClassメソッドを使わなければならない。

このように、InputDSを記述するには、一度フィールドでReceiverをcreateして、その後Reveiverに対してsetKeyで待ち合わせるkeyを指定しなければならない。
このようにインプットの処理が分離されてしまっていては、記述が煩雑な上にコードを読んだ際にどのkeyに対して待ち合わせを行っているのか直感的に分からない。

さらに、setKeyは明確な記述場所が決まっていないため、そのDSを待ち合わせているCS以外からも呼び出せてしまう(ソースコード\ref{src:StartSetKey})。

    \lstinputlisting[label=src:StartSetKey, caption=setKey]{source/StartSetKey.java}
    \lstinputlisting[label=src:SetKey, caption=Seprated setKey]{source/SetKey.java}

このような書き方をされると、CSだけを見てどのkeyに対して待ち合わせを行っているのかわからないため、setKeyを呼び出しているコードを辿る必要がある。
これでは見通しが悪いため、どこでkeyを指定するのか明確にすべきである。

可読性の低いコードはプログラマの負担となるため、CSが何を待ち合わせているのかそのCSを見ただけで理解できるように記述の分離問題を改善しなくてはならない。

setKeyはCSのコンストラクタで指定することが多い。
このとき、指定するkeyは引数などから動的に受け取り、セットすることができる。
しかし、それでは実際にどんな処理が行われているのかわかりづらく、また、putする部分などの該当するkeyを扱う全てコードを変更しなければならない。
このように、AliceではCSを使いまわすことを考慮して動的なsetKeyを可能にしてしまったせいで、慎重に書かなければプログラムの信頼性が保てないようになってしまっている。
そのため、動的なsetKeyはできないように制限し、コードの見通しを良くする必要がある。
CSに対してインプットとなるkeyが静的に決まれば、待ち合わせているkeyに対してのputのし忘れなどの問題をコンパイル時のモデル検査などで発見することができると考えられる。

inputDSを受け取るReceiverはデータをObject型で持っており、そのデータをCS内で扱うには正しい型にキャストする必要がある。
しかし、inputDSで指定するのはkeyのみであり、そのデータの型までは分からない。
そのため、DSの型を知るにはputしている部分まで辿る必要がある。
辿ってもflipされている可能性もあるため、最初にそのDSをputしている部分を見つけるのは困難である。
従って、待ち合わせているkeyにどのような型のデータが対応しているのかをそのCSを見ただけで分かるようにするべきと考える。

key名とそのkeyで待ち合わせたDSを受け取るReceiver名は異なることがある。
もしプログラマが適当に命名してしまえば後々混乱を招くため、待ち合わせるkey名とinput DS の変数名一致を強制させたい。

\section{分散フレームワークChristieの設計}

以上の問題を踏まえ、新しい分散フレームワークChristieの設計とプロトタイプの実装を行った。
Christieに必要な要件は以下のように考えた。

\begin{itemize}
\item {\ttfamily create/setKeyのような煩雑なAPIをシンプルにし可読性を向上させる}
\item {\ttfamily 並列分散環境下での型の整合性を保証する構文と仕組みを提供する}
\item {\ttfamily 一つのプロセス内で複数のインスタンスを同時に立ち上げられる}
\item {\ttfamily 木構造などのデータ構造をネットワーク上でやりとりできる}
\item {\ttfamily 通信に用いるキーの階層的管理を提供する}
\item {\ttfamily これらの仕組みを実現するメタ計算機構を提供する}
\end{itemize}

Chirstie では、CodeSegment/DataSegment と呼ばずに、CodeGear/DataGear と呼ぶ。これは将来的にはGears OSにより実装するためである。

Alice のAPIの問題は、送信するオブジェクトの型を前もって指定できないことと、記述する場所に自由度があることが問題になっている。
そこで、DataGear を Java のAnnoationを用いて宣言することにした。これに関しては、実装を行ない、妥当なAPIを決定した。
これについは次節で説明する。

Alice のSingleton は広範囲で使われており、Refactoring では修正できない。そこで、Christie では基本的な部分を再実装することにした。

Jungle との整合性では、Alice と Jungle の両方にオブジェクトのデータベースが存在することが良くない。Jungle では変更ログを
Aliceにより送信しているが、これはリスト構造を送信することに相当する。Jungle では木の変更を伝搬させるが、これは木構造そのものを
通信しているのと同等である。つまり、Alice の通信を木構造を持つオブジェクトにまで拡張することが可能だと考えられる。

Jungleの木構造と、AliceのTuple空間の違いは、変更時の同期方法にある。Jungle では木はラベルにより指定されて、その変更はトランザクション
として失敗と成功がある形で直列化される。Alice の同期機構は、Data Segment の待ち合わせによって行われる。単一のData Segment を
待ち合わせれば、それは単一のトランザクションと同等になる。複数のData Segmentを待ち合わせる形の同期は Jungle では実現できない。
Jungle の木をキーに対応する Data Segment とすることよって、Alice により Jungle のトランザクションを実現できる。

Jungleの木のラベルは大域的なIDである必要があるが、特に構造を持たせていない。Alice のラベルは、接続された2点間でのみ有効になっている。
従って、Jungle の木のラベルは分散システムの中で管理する必要がある。通常のURIのように木構造を持った構造として分散管理することが
望ましい。つまり、Jungle の木のラベルはJungle 自体で管理される木構造であるべきだと思われる。これはファイルシステムのパスに
相当する。Christie はGears OSでの分散ファイルシステムとして使えるのが望ましい。

\section{アノテーションの導入}

InputAPIにはAliceと同じくTakeとPeekを用意した。
ChristieではInput DG の指定にはアノテーションを使う。
アノテーションとは、クラスやメソッド、パッケージに対して付加情報を記述できるJavaのMeta Computationである。
先頭に@をつけることで記述でき、オリジナルのアノテーションを定義することもできる。

AliceではInputの受け皿であるReceiverを作り後からkeyをセットしていたが、
ChristieではInputとなる型の変数を直接宣言し、変数名としてkeyを記述する。
そして、その宣言の上にアノテーションでTakeまたはPeekを指定する(ソースコード\ref{src:takeex})。

\lstinputlisting[label=src:takeex, caption=Takeの例]{src/InputDG.java}


アノテーションで指定したInputDGは、CGを生成した際にCodeGear.class内で待ち合わせの処理が行われる。
これにはJavaのreflectionAPIを利用しており、アノテーションと同時に変数名も取得できるため、変数名によるkey指定が実現した。

Christieのこのインプットアノテーションはフィールドに対してしか記述できないため、keyの指定とTake/Peekの指定を必ず一箇所で書くことが明確に決まっている。
そのためAliceのように外のCSからのkeyへの干渉をされることがない。
このように、アノテーションを用いたことで、Aliceの記述の分離問題が解決された。
また、keyを変数名にしたことで、動的なkeyの指定や、keyと変数名の不一致による可読性の低下を防ぐことができた。

リモートノードに対してTake/Peekする際は、TakeFrom/PeekFromのアノテーションを用いる(ソースコード\ref{src:remotetake})。

\lstinputlisting[label=src:remotetake, caption=TakeFrom]{src/RemoteInputDG.java}

なお、圧縮のMeta ComputationはAliceと同様で、指定する際にDGM名の前にcompressedをつける(ソースコード\ref{src:compresslocal})。

\lstinputlisting[label=src:compresslocal, caption=Remoteから圧縮して受け取る例]{src/CompressLocal.java}


OutputAPIにはput/flipを用意した。
基本的なシンタックスはAliceと同様だが、Christieではput/flipのメソッドはCodeGear.classに用意されている。
そのためCodeGear.classを継承するCGで直接putメソッドを呼ぶことができる(ソースコード\ref{src:remoteput})。

\lstinputlisting[label=src:remoteput, caption=put]{src/RemotePut.java}

そのため、ChristieにはAliceのODSにあたる部分がない。
ODSを経由するより直接DGMに書き込むような記述のほうが直感的であると考えたためである。
圧縮を指定してのputも、Alice同様DGM名の前にcompressedをつける。


\subsection*{型の整合性の向上}
ChristieではReceiver型ではなく直接変数を宣言する。
そのため他の場所を辿らなくともCGを見るだけでインプットされるデータの型が分かるようになった。
また、変数を直接宣言するため、そもそもAliceのようにasClassメソッドで型の取り出す必要がない。
ソースコード\ref{src:getdata}はInputDGのデータを扱うである。

\lstinputlisting[label=src:getdata, caption=InputDGを扱う例]{src/GetData.java}

InputDGとして宣言した変数の型は、reflectionAPIにより内部で保存され、リモートノードと通信する際も適切な変換が行われる。
このようにプログラマが指定しなくとも正しい型で取得できるため、プログラマの負担を減らし信頼性を保証することができる。

以下のコードはLocalDSMにputしたDGを取り出して表示するのを10回繰り返す例題である。

\lstinputlisting[label=src:StartCodeGear, caption=StartCodeGearの例]{src/StartTest.java}
\lstinputlisting[label=src:TestCodeGear, caption=CodeGearの例]{src/TestCodeGear.java}

Alice同様、ChristieでもInputDGを持たないStartCGから処理を開始する。
StartCGはStartCodeGear.classを継承することで記述できる。
AliceではStartCSもCodeSegment.classを継承して書かれていたため、どれがStartCSなのか判別しづらかったが、Christieではその心配はない。

StartCGを記述する際にはcreateCGMメソッドでCGMを生成してコンストラクタに渡す必要がある。
ソースコード\ref{src:StartCodeGear}の8行目でそれが行われている。
createCGMの引数にはリモートノードとソケット通信する際使うポート番号を指定する。
CGMを生成した際にLocalDGMやリモートと通信を行うためのDaemonも作られる。

CGに対してアノテーションから待ち合わせを実行する処理はsetupメソッドが行う。
そのためソースコード\ref{src:StartCodeGear}の13行目、ソースコード\ref{src:TestCodeGear}の10行目のように、newしたCGをCGMのsetupメソッドに渡す必要がある。
AliceではnewすればCGが待ちに入ったが、Christieでは一度CGをnewしないとアノテーションから待ち合わせを行う処理ができないため、newの後にsetupを行う。
そのため、CGの生成には必ずCGMが必要になる。
runでCGMを受け渡すのはこのためである。
なお、StartCGはインプットを持たないため、setupを行う必要がなく、newされた時点でrunが実行される。

\section{Unixファイルシステムとの比較}

Christie を分散ファイルシステムとして使うのと、Unixファイルシステム上の分散ファイルシステムとの違いについて考察する。

Christie に格納されるのはオブジェクトであり、型のないテキストファイルとは異なる。もちろん、文字列をそのまま格納することも
できるが、巨大な文字列にはなんらかの構造を与えてランダムアクセスなどができるようにする。その意味で、Unixファイルシステム
でもファイルには必ず構造が入っている。

Unixファイルにはディレクトリ構造があり、ディレクトリの構造にはトランザクションが導入されている。Christieの場合は、
Christie の同期機構としてトランザクションが定義される。

Unixファイル全体はiノードを使ったB-Tree構造を持つ。これらはディレクトリ構造による木構造のパスでアクセスされる。
Christie ではパスとディレクトリは木構造のデータベースとして定義される。

Unixファイルの持続性はディスク上のiノードの持続性によって実現される。Christieは持続性のあるノードに木構造を
複製することによって持続性を実現する。

Unixファイルはread/writeによりアクセスするが、Christieではメモリ上のオブジェクトであり、read/writeではなく
名前で指定された木に対する get/put で変更を行う。

持続性のあるノードに複製されたChristieのオブジェクトはメモリ上から削除しても良い。再度必要な場合は、パスを
用いて持続性のあるノードから複製する。

\section{まとめ}

分散木構造データベースJungleと、分散フレームワークAliceについて考察し、両者を統一する形で、分散フレームワークChristieを
提案した。

Christie ではアノテーションを用いて、Aliceの欠点であった記述の分離と型の整合性をコンパイル時に解決できない問題を解決した。

Jungle の構造をChristieに内蔵することにより、ChristieのData Gear は、分散環境で共有、あるいは、持続性を持つことができるようになる。
そのData Gear へのアクセスに、大域的な木構造を持つラベルを用意することで、ChristieのData Gearをファイルシステムのように
使えるようになる。

将来的には Gears OS でのファイルシステムとしてChristieを使えるように、持続性、DataGearにアクセスするパスとしての木構造、分散環境での
同期手法を研究していく予定である。



%参考文献 
\bibliographystyle{ipsjunsrt}
\bibliography{ref}

\end{document}