view paper/chapter2.tex @ 26:388cd4555b3d

Added neo4j_replica, mongodb_sharding and cassandra_ring
author Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
date Sun, 26 Jan 2014 00:16:38 +0900
parents 67880a2ca650
children 1abd3c17cff9
line wrap: on
line source

\chapter{木構造データベースJungleの分散設計}



\section{木構造データベースJungle}
Jungle はスケーラビリティのある CMS の開発を目指して当研究室で開発されている非破壊的木構造データベースである.
一般的なコンテンツマネジメントシステムではブログツールや Wiki・SNS が多く, これらの
ウェブサイトの構造は大体が木構造であるため, データ構造として木構造を採用している.

まず破壊的木構造と, 非破壊的木構造の説明をし, Jungle におけるデータ編集の実装について述べる.
\subsection{破壊的木構造}
破壊的木構造の編集は, 木構造で保持しているデータを直接書き換えることで行う.
図\ref{fig:destractive}は破壊的木構造の編集を表している.

\begin{figure}[htpb]
  \begin{center}
    \includegraphics[scale=0.7]{figures/destructive_tree.pdf}
    \caption{破壊的木構造の編集}
    \label{fig:destractive}
  \end{center}
\end{figure}

破壊的木構造は, 編集を行う際に木のロックを掛ける必要がある.
この時, データを受け取ろうと木を走査するスレッドは書き換えの終了を待つ必要があり, 閲覧者が
いる場合は木の走査が終わるまで書き換えをまたなければならない.
これではロックによりスケーラビリティが損なわれてしまう.

\subsection{非破壊的木構造}
非破壊的木構造は破壊的木構造とは違い, 一度作成した木を破壊することはない.
非破壊的木構造においてデータの編集は, ルートから編集を行うノードまでコピーを
行い新しく木構造を作成することで行われる.
図\ref{fig:nondestractive}は非破壊的木構造のデータ編集を示している.

\begin{figure}[htpb]
  \begin{center}
    \includegraphics[scale=0.7]{figures/non_destructive_tree.pdf}
    \caption{非破壊的木構造の編集}
    \label{fig:nondestractive}
  \end{center}
\end{figure}

非破壊的木構造におけるデータ編集の手順を以下に示す.

\begin{enumerate}
\item ルートから編集を行うノードまでのパスを調べる(図\ref{fig:nondestractive_edit1}).
\item 編集を行うノードのコピーをとる. コピーをとったノードへデータの編集を行う(図\ref{fig:nondestractive_edit2}).
\item 調べたパスに従いルートからコピーしたノードまでの間のノードのコピーをとり繋げる(図\ref{fig:nondestractive_edit3}).
\item コピーしたルートノードは編集を行っていないノードへの参照を貼り新しい木構造を作る(図\ref{fig:nondestractive_edit4}).
\end{enumerate}

\begin{figure}[htpb]
  \begin{center}
    \includegraphics[scale=0.7]{figures/non_destructive_edit1.pdf}
    \caption{非破壊的木構造の編集1}
    \label{fig:nondestractive_edit1}
  \end{center}
\end{figure}

\begin{figure}[htpb]
  \begin{center}
    \includegraphics[scale=0.7]{figures/non_destructive_edit2.pdf}
    \caption{非破壊的木構造の編集2}
    \label{fig:nondestractive_edit2}
  \end{center}
\end{figure}

\begin{figure}[htpb]
  \begin{center}
    \includegraphics[scale=0.7]{figures/non_destructive_edit3.pdf}
    \caption{非破壊的木構造の編集3}
    \label{fig:nondestractive_edit3}
  \end{center}
\end{figure}

\begin{figure}[htpb]
  \begin{center}
    \includegraphics[scale=0.7]{figures/non_destructive_edit4.pdf}
    \caption{非破壊的木構造の編集4}
    \label{fig:nondestractive_edit4}
  \end{center}
\end{figure}

\newpage

非破壊的木構造により, データの読み込みと編集を同時に行うことが可能になる.

\begin{figure}[htpb]
  \begin{center}
    \includegraphics[scale=0.7]{figures/non_destructive_merit.pdf}
    \caption{非破壊的木構造による利点}
    \label{fig:nondestractive_merit}
  \end{center}
\end{figure}



\section{Jungleにおけるデータ編集}
Jungle ではデータをそれぞれの Node が attribute として保持する.
attribute は String 型の Key と ByteBuffer の value のペアにより表される.
Jungle でデータ編集を行う場合, この Node に対して削除や attribute の追加等を行うことを指す.
どの Node へデータの編集を行うかはパスで示す.
このパスは NodePath と呼ばれる(図\ref{fig:nodepath}).

\begin{figure}[htpb]
  \begin{center}
    \includegraphics[scale=0.7]{figures/nodepath.pdf}
    \caption{Node の attribute と NodePath}
    \label{fig:nodepath}
  \end{center}
\end{figure}

Node の編集は Node の追加・削除, それと attribute の追加・削除を行うことを指す.
Node の編集のためには次の4つの API が用意されている.
\begin{itemize}
\item \verb|addNewChild(NodePath _path, int _pos)|
NodePath で指定された Node に子供となる Node を追加する API である.
pos で指定された番号に子供として追加を行う.
\item \verb|deleteChildAt(NodePath _path, int _pos)|
NodePath と pos により指定される Node を削除する API である.
\item \verb|putAttribute(NodePath _path, String _key, ByteBuffer _value)|
Node に attribute を追加する API である. 
NodePath は attribute を追加する Node を指す.
\item \verb|deleteAttribute(NodePath _path, String _key)|
\verb|_key| が示す attribute の削除を行う API である.
NodePath は Node を示す.
\end{itemize}

この Node 編集の為の API は NodeOperation と呼ばれる.
\subsection{TreeOperationLog}
API を使用すると, Jungle 内部では NodeOperation として順次ログに積まれていき, 最終的に
commit されることで編集が行われる.
この時ログに積まれる複数の NodeOperation を TreeOperationLog という.
Jungle ではこの TreeOperationLog 単位でデータの編集が行われる.
以下に TreeOperationLog の具体的な例を示す(\ref{src:treelog}).
\begin{lstlisting}[frame=lrbt,label=src:treelog,caption=トポロジーマネージャーの利用,numbers=left]
[APPEND_CHILD:<-1>:pos:0]
[PUT_ATTRIBUTE:<-1,1>:key:author,value:oshiro]
[PUT_ATTRIBUTE:<-1,1>:key:mes,value:hello]
[PUT_ATTRIBUTE:<-1,1>:key:key,value:hoge]
[PUT_ATTRIBUTE:<-1,1>:key:timestamp,value:0]
\end{lstlisting}
このログは今回の研究で使用したベンチマーク用掲示板プログラムにおける書き込みにより行われるログである(図\ref{fig:treeoperationlog}).

大文字の英字は実行した NodeOperation を表す.
<> により囲まれている数字は NodePath を示す.
NodePath の表記以降は Node の position や attribute の情報を表している.
\begin{figure}[htpb]
  \begin{center}
    \includegraphics[scale=0.7]{figures/treeoperationlog1.pdf}
    \caption{TreeOperationLog の具体例}
    \label{fig:treeoperationlog}
  \end{center}
\end{figure}



\section{データ衝突時におけるマージによる解決}
Jungle への分散実装を行うことである問題が発生する.
それは更新されたデータ同士が衝突を起こした時の処理である.
Jungle はリクエストがきた場合, 現在もっているデータを返す.
しかしそのデータは最新のものであるかは保証されない.
よって, 別のサーバノードで動いている Jungle からの更新データと衝突する可能性がある.

この問題に対して Jungle はアプリケーションレベルでのマージを実装して貰うことで解決をはかる.


\section{データの永続性}




\section{CAP 定理と Jungle}

\begin{figure}[htpb]
  \begin{center}
    \includegraphics[scale=0.7]{figures/cap_theorem.pdf}
    \caption{CAP 定理における各データベースの立ち位置}
    \label{fig:cap_theorem}
  \end{center}
\end{figure}