====== オンメモリ型分散Key-Valueストア 「okuyama」=====================
Javaで実装された、オンメモリ型分散Key-Valueストア「okuyama」を
ダウンロード頂きありがとうございます。

========================================================================================================
[New - 機能追加]
[[リリース Ver 0.2.0 - (2010/02/08)]]
 ■自動レプリケーション及び、自動リカバリー機能を追加
   データノードクラッシュ時もシステムの機能停止を防止。

 [追加機能詳細]
  1. 1つのデータを複数のデータノードに登録するよう機能を追加(自動レプリケーション)
     分散登録を行うことで、自動的にデータの複製が行われ、より安全性の高い分散KVSへと進化しました。

  2. 自動リカバリー機能
     1.の機能を使用している場合、メインデータノードがクラッシュした場合も、メインデータノード復帰後、
     スレーブノード(レプリケーションノード)から自動的にデータを復元します。
     ※スレーブノードがクラッシュした場合も、復帰後自動的にメインデータノードから復元されます。

  3. 上記2つの機能を使用している場合はノード停止時もシステムの停止なしに使用可能
     データノードクラッシュ時もスレーブノード(レプリケーションノード)への自動移行が行われるため、
     使用システムの停止がありません。

  ※上記の使用方法は、src\MasterNode.propertiesを参照してください。
  ※execMasterNode.batはマスターノードを起動します。
  ※execDataNode.batはメインデータノードを起動します。
  ※execSlaveDataNode.batはスレーブデータノードを起動します。
========================================================================================================
========================================================================================================
[New - 不具合修正]
[[リリース Ver 0.2.1 - (2010/02/11)]]
 ■自動リカバー時の挙動を修正。
   停止ノード起動時のタイミングによって正しくデータがリカバリーされない不具合を修正。

 ■src\MasterNode.propertiesにコメントを追加。
========================================================================================================
========================================================================================================
[New - MasterNode処理部分を最適化&性能評価のテキストを添付]
[[リリース Ver 0.2.2 - (2010/02/24)]]
 ■MasterNodeのロジックを最適化。
   最適化残箇所はまだ残っている。

 ■最適化前と後で、簡単に性能を測定。測定結果をテキストとして添付
========================================================================================================

スペック
 実装言語:Java(jdk1.6にて開発)
 ソースエンコーディング:UTF-8
 動作検証OS:WinsowsXp SP3、CentOS 5.3(final)
 必要ライブラリ:log4j-1.2.14.jar、javamail-1.4.1.jar(JavaMail Ver1.4.1)
 Version:0.1.0(2010/01/07)


簡単な機能説明とサンプルの実行方法を以下に記します。
[機能説明]
1.Key-Valueストア
  Key-Valueストアを実現します。
  Keyは文字列、Valueは文字列と、byteデータの両方を登録可能です。

2.Tag機能
  Keyの他にTagを登録できます。
  Tagは文字列となります。
  ストアではKeyはユニークな値として扱われますが、Tagは複数のデータに紐付ける
  ことが出来ます。
  複数データにあらかじめ任意のTagを付けることで、Tag指定により
  一度に関連データを取得可能となります。
  ※現在はTag指定で関連するデータのKey配列が取得できます。

3.オンメモリであり、永続化されたデータ
  データの登録をクライアントが命令し、完了するとそのデータはデータノードの
  メモリ上(※1)に蓄えられると同時にファイルシステムに保存(※2)されます。
  なので、データノードを停止してもデータが消えることはありません。

  ※1.登録データは各データノード上で1つの同期化されたjava.util.HashMapに格納されます。
      データの登録、取り出しは全てここから行われます。
  ※2.ファイルシステムに保存されるデータは、定期的に保存されるjava.util.HashMapを
      シリアライズ化したデータと、データ登録時のログ情報となります。
      シリアライズデータの登録はデータ登録、取得処理とは非同期にて実行されます。

4.分散型
  「okuyama」はマスタノード、データノード、クライアントの3つで構成されます。
  それぞれの役目は以下です。
  マスタノード:設定されたアルゴリズム(※1)に従って、クライアントからのデータ操作依頼を適切な
               データノードに依頼します。
               データの保存、取得の際の使用データノード決定を行います。
               マスターノードは情報を保持しないので、複数台で稼動可能となります。
               データノードの追加を実現します。
               ※1.管理するデータノードの数に依存する簡単なアルゴリズムです。

  データノード:キーとデータの組み合わせでデータを保存します。
               データの登録、抽出インターフェースを持ちます。
               自身では他ノードへのデータの振り分けなどは行ないません。

  クライアント:マスタノードへの通信を行う実際のプログラムインターフェースです。
               インターフェースとしては、
               1.Key(文字列)とValue(文字列)の組み合わせでのデータ登録
               2.Key(文字列)とTag(文字列)とValue(文字列)の組み合わせでのデータ登録
               3.Key(文字列)でのValue(文字列)取得
               4.Tag(文字列)でのKey(文字配列)取得
               5.Key(文字列)とValue(byte配列)の組み合わせでのデータ登録
               6.Key(文字列)でのValue(byte配列)取得

  それぞれのノード間の通信はTCP/IPでの通信となります。
  また、クライアントとマスタノード間の通信は試験的にBase64にてエンコーディングした文字列を使用しています。



[サンプル稼動方法]
 ※Windows環境

   前提条件:1.構成
              1台のマシン上で稼動するように設定されています。
              それぞれのノード台数
              マスタノード:1台
              データノード:2台

            2.各ノードの使用ポートは以下となります。
              マスタノード:8888
              用途:クライアントからの要求待ち受け
              変更する場合:srcディレクトリ配下のMasterNode.propertiesの7行目を変更
                           7行目=MasterManagerJob.Init=8888<=この番号

              データノード:5553、5554
              用途:マスタノードからの要求待ち受け
              変更する場合:srcディレクトリ配下のDataNode.propertiesの7行目、13行目を変更
                           7行目=KeyManagerJob1.Init=5553<=この番号
                           13行目=KeyManagerJob2.Init=5554<=この番号


 1.コンパイル
   簡易的なコンパイル用バッチファイルを用意しています。
   本ファイルと同一ディレクトリにある、compile.batを実行してください。
   前提:javac.exeにPATHが通っている

 2.MasterNode起動
   簡易的なMasterNode起動用バッチファイルを用意しています。
   本ファイルと同一ディレクトリにある、execMasterNode.batを実行してください。
   停止方法はCtrl+Cもしくは本ファイルと同一ディレクトリにServerStopというファイルを作成する
   ※ServerStopファイルが存在するとサーバはMasterNodeは起動しません。
   前提:1.java.exeにPATHが通っている
        2.メモリ上限を128MBとしています

 3.DataNode起動
   簡易的なDataNode起動用バッチファイルを用意しています。
   本ファイルと同一ディレクトリにある、execDataNode.batを実行してください。
   2つのデータノードが同時に起動します。
   停止方法はCtrl+Cもしくは本ファイルと同一ディレクトリにServerStopというファイルを作成する
   ※ServerStopファイルが存在するとサーバはDataNodeは起動しません。
   前提:1.java.exeにPATHが通っている
        2.メモリ上限を256MBとしています
   
 4.接続サンプル
   簡易的な接続、登録、取得サンプルを用意しています。
   本ファイルと同一ディレクトリにある、TestSock.classを実行してください(jdk1.6にてコンパイル済み)。
   引数なしで実行すると使用方法が出力されます。
   例)
     # 以下の例は自動的にインクリメントするKey値でValue文字列を1000回登録している
     java -cp ./;./classes;./lib/javamail-1.4.1.jar TestSock 1 127.0.0.1 8888 1000

     # 以下の例は自動的にインクリメントするKey値でValue文字列を1000回取得している
     java -cp ./;./classes;./lib/javamail-1.4.1.jar TestSock 2 127.0.0.1 8888 1000

     # 以下の例は自動的にインクリメントするKey値と適当な4パターンのTag値でValue文字列を100回登録している
     java -cp ./;./classes;./lib/javamail-1.4.1.jar TestSock 3 127.0.0.1 8888 100

     # 以下の例はTag値「tag1」に紐付くKey値を1回取得している
     java -cp ./;./classes;./lib/javamail-1.4.1.jar TestSock 4 127.0.0.1 8888 1 tag1

     # 以下の例はKey値「wordfile」で「C:\temp\SampleWord.doc」ファイルを1回登録している
     java -cp ./;./classes;./lib/javamail-1.4.1.jar TestSock 5 127.0.0.1 8888 1 C:\temp\SampleWord.doc wordfile

     # 以下の例はKey値「wordfile」のバイトデータを取得し「C:\SampleWord.doc」ファイルとして1回作成している
     java -cp ./;./classes;./lib/javamail-1.4.1.jar TestSock 6 127.0.0.1 8888 1 C:\SampleWord.doc wordfile


[今後]
 今後はバグFixとデータの多重保存(Ver0.2.0で実現)を実現し、現在存在しない削除メソッドなどを作成します。


