kvsをメインストレージと考えた場合のアプリケーション設計(続編)

前回ブログで書きました、kvs使った業務アプリ構築ですが
徐々に出来上がってきました。


設計は前回の内容どおりなんですが、実際にデータ入れて
取り出すところが、1ソートパターンですができました。


実際に動かして見ると、、、
ちゃんと動いてるじゃないですか!!
アプリ部分を作ってくれているメンバーに感謝。




体感ですが、画面上から表示リクエストを実行してから
表示が完了するまで約0.5〜1秒程度です。


まずはkvs上に数百件程度のデータを入れて試したの
ですが、ここで1000万件程表示対象以外のデータを
登録しながら試しましたが、登録中も、登録完了後も
全くレスポンスには影響がでませんでした。



予定通りです!!


一つの実証が取れました。
この構成で使用しているマシンはMasterNodeが2台、
DataNodeがマスタ2台、スレーブ2台でCpuが1GHz
メモリが768MBという、何年前のだよというマシン
なので、余計に自信が持てました。
(ちゃんとしたマシン用意しなきゃ。。。)


後は、ごく簡単な更新処理をkvsに行うので
そこで分散ロックを使うことになるので
また新たな実証が取れ次第書こうとおもいます。

KVSをメインストレージと考えた場合のアプリケーション設計

昨日の日記で少し書いたのですが、現在仕事でokuyamaをメインストレージとして
アプリケーションを作成中、そこで感じたことをメモ。


okuyama作ってますが業務ではkvsはキャッシュとしてしか使ったことなかったので。。。




メインストレージといっても、あくまでもRDBMSとセットで利用します。


ほとんどはRDBMSに格納されているんですが、一部のデータを
okuyamaに格納します。
そのデータは日に数万から、数十万増加する試算です。
それをシステムからリアルタイムに何種類かのソートパターンで表示します。
何ともチャレンジングな。。。
挑戦しがいがあります。


で、早々にRDBMSの設計は終わらして、kvsに格納するデータの設計です。
okuyamaはタグという概念があるので少しkey-valueの概念とは異なりますが、
多分他の場合も応用はきくかな。




アプリが都度表示する対象件数は数百件の母数に対して、特定のソート条件で
ソートした中から20ページ程度でページングして表示です。
多分最初の数ページしか見ない感じです。なので、ソートはかなり重要!
で、出来たデータ設計は下




インデックスとなるrow
key, tag, value
ソートキーで並べた場合のインデックスNo_母数全体を束ねるユニーク値_ソート項目名, 母数全体を束ねるユニーク値_ソート項目名_ページNo, KVS全row中でのキー値


実際の表示対象となるrow
key, value
KVS全row中でのキー値, value




あらかじめデータを登録する処理でソートしてひたすらインデクスのrowを登録します。
最後に表示rowを登録。


後は取得側は表示したい母数を一意にする値をRDBMSから取得して
ソートの要望と表示ページNoに合わせて、ソート項目名、ページNoを連結した
値をtagとしてokuyamaからgetすると、そのtagに紐付くKey値群が取れてくる仕組み。


データイメージは
インデックスとなるrow
母数を束ねる"1"というグループのDATEで並べた、1ページ目を取得したい場合は

こんな感じかな。
これなら表示アプリのソート幅も小さいし、1ぺージあたりの件数を増やしたい場合も
用意に対応できそうなので(1ページあたろ40件とかなら2ページTag分一度にとるとか)、
これで進めることになりました。



さてうまくいくだろうか。。。

okuyama0.6.0をリリース「分散ロック機能」を追加しました

okuyama Ver0.6.0をリリースしました。
今回の追加機能は、分散ロックです。
詳しい機能はokuyamaリリース物のReadMe.txtを抜粋。

                                                                                                                                                                                                                            • -

 ■分散ロック機能を追加
  +任意のデータをロックする機能を追加。
  +分散ロック機能はマスターノード用設定ファイルである、MasterNode.propertiesの9行目の"TransactionMode=true"で
    ロック機能が使用可能となる。
    また、72行目の"TransactionManagerInfo=127.0.0.1:6655"でTransactionManagerノードを指定する必要がある
    そして、TransactionManagerノードが起動している必要があるため、同梱のexecTransactionNode.batで起動する。
    分散ロック機能を使用する場合は、全てのマスターノードが"TransactionMode=true"で起動している必要がある。
    同梱の設定ファイルは全て分散ロック機能で起動する設定となる。
    ※execMasterNode2.batは分散ロック機能あり、memcacheプロトコルモードで起動する。
    また、従来の分散ロック機能なしで起動する場合は、"TransactionMode=false"としてexecMasterNode.batを実行する。


  +仕組みとしては、Clientからロック取得依頼を行った場合、TransactionManagerノードに指定したKey値で
    ロック情報を作り上げる。この際、すでに別Clientから同一のKey値でロックが取得されている場合は、
    指定した時間の間、ロックが解除されるのを待ち、取得を試みる。
    ロックされた値に対して、set,remove系のアクセスを行った場合は、TransactionManagerノードに対して該当の
    Key値が、リクエストを発行したClient以外からロックされているかを問い合わせて、別クライアントがロック
    している場合は、ロックが解除されるのを待ち続ける。
    同クライアントがロックしているもしくは、ロックがない場合は、そのまま処理を続行する。
    ロックのリリースも同じ動きである。
    なお、分散ロック機能を有効にした場合は、無効時と比べ1回通信が多く発生するため、処理速度は落ちる。
    また、TransactionManagerノードがSPOFとなるが、機能していない場合は無視して稼動するが、
    処理速度は極端に劣化する。
    今後、SPOFとならないように改善予定である。




  +以下は説明となる
    *ロックを実施したデータの挙動は以下となる。
   ・ロック可能なKey値(データ)は現在登録済みであっても、登録されていなくても可能である。
   ・1クライアントから同時に複数のデータをロック可能である
   ・ロックしたデータはロックを実施したクライアントからのみロック解除可能である。
   ・ロック中のデータはロックを実施したクライアントからのみ登録可能である。
   ・ロック中のデータはロックを実施したクライアントからのみ変更可能である。
   ・ロック中のデータはロックを実施したクライアントからのみ削除可能である。
   ・ロック中のデータは全クライアントから参照可能である。


    *ロック機能使用開始メソッドは以下である。
   ・クライアントのメソッド名:startTransaction
   ・引数なし
   ・戻り値:boolean  true:スタート成功  false:スタート失敗
    ※ロック機能有りでTransactionManagerノードを起動していない場合は、スタートに失敗する。
  
     
    *ロックメソッドへの引数と戻り値は以下である。
   ・クライアントのメソッド名:lockData
   ・引数1:ロック対象Key値
    引数2:ロック継続時間
       (ロック解除を行わない場合でも、ここでの設定時間が経過すると自動的に解除される。
         単位は秒。
         0を設定するとロックを実施したクライアントが解除するまで永久にロックされる。
         ※0指定は推奨しない)
    引数3:ロック取得待ち時間
       (既に別クライアントがロック中のデータへロックを実施した場合に、設定時間の間ロック取得をリトライする。
         単位は秒。
         0を設定すると1回ロックを試みる)


   ・戻り値:String配列
         String配列[0]:Lock成否  "true"=Lock成功  or  "false"=Lock失敗
  
    *ロック開放への引数と戻り値は以下である。
   ・クライアントのメソッド名:releaseLockData
   ・引数1:ロック対象Key値  
   ・戻り値:String配列
         String配列[0]:開放成否  "true"=開放成功  or  "false"=開放失敗


    *ロック機構使用終了メソッドは以下である。
   ・クライアントのメソッド名:endTransaction
   ・引数なし
   ・戻り値なし


  +Java版、PHP版のクライアントからは、ロック、リリース両方が可能
    Memchacheクライアントはロック、リリース機能は利用できないが、Lock中のデータにsetを実行した場合は"待ち状態"に入る。

                                                                                                                                                                                                                            • -





構成は以下のようになりました。





最初はロック情報もデータノードに持たせようとしたけど、ややこしくなりすぎるのと、
データと、それ以外の情報は別管理のほうが後々良いということで、別ノード立てました。
ロック機能を使用しても性能はそんなに悪くないので、まあまあ良いかと。


これで分散トランザクションの準備は50%くらいかな。。。
ぼちぼちやっていきます。




okuyamaを会社の業務で使い始めたので、そっちからのフィードバックも今後は有益な情報になりそう!!

kvsユーザーグループを立ち上げました

KVSユーザーグループをGoogleグループで
作成しました。


名前はkvs-jaです。


kvsのインターフェースや永続化特性、分散、
スケールアルゴリズムなどの議論や、拡張利用の
可能性などを会話を出来ればと思っています。


色々な方と意見を交わせればと思いますので、
宜しければご参加ください。

memcache速っ!!

今更なんですが、memcache速っ!!て感じました。
Windows版で試したんですが、同じ環境でクライアント動かして
10万件ほどsetしたんですが、6500QPS位出た。


同じクライアント使ってokuyamaで試すと、


完全メモリモード3600QPS位で、ファイル保存モードで、


2900QPS位。




かなわねーーーー!!



ネックは分かっててmemcacheは1アクション1通信、okuyamaは


2通信 (client->master->datanode)


これnetworkごしならもっと差がつきますね。

今はそれぞれの通信部分が全てのデータを受け取ってから

処理を始めてるんですが、受け取る部分と、

処理部分を並列化したら変わるかな。

あとで絵描いてみよう。

memcacheプロトコルに対応 「okuyama-ver0.5.2リリース」

okuyama-ver0.5.2をリリースしました。


今回の目玉はmemcacheのプロトコル対応です。
まだ文字の行ベースのみで、set、getだけ対応です。
後、flag、有効期限は対応してなくて、32bit値は登録可能です。


okuyamaクライアントとプロトコルの組み合わせに比べると
処理速度は落ちますが、今後残りの処理にも対応していきます。
取り合えずはdelete, add, replaceに対応します。




残りの改修は、データファイルのvacuum(デフラグ)処理を追加しました。
長時間の耐久テストで同じKeyとValueの組み合わせで登録を繰り返していたら
DiskFullで落ちたので。。。
当たり前ですね。okuyamaのファイル保存方式が追記型ですから。。。


今は単純に直近30秒間アクセスがなくて、不要領域が10万データを超えると
動き出すんですが、アクセスの状況を学習させても面白いかも。
本質から外れてるな〜〜〜


後は、負荷テストの結果をExcelで纏めました。


今の全体構成は以下。







つ、つぎこそは分散トランザクションを。。。

okuyama用PHPクライアントを作成

"okuyama Ver0.5.1"にてPHP用のクライアントを作成しました。
Byteデータの登録と取得以外は実装しました。
http://sourceforge.jp/projects/okuyama/releases/


また分散トランザクションから遠ざかっている。。。




okuyamaがさくらインターネット研究所様のblogのコメント欄で
少し取り上げられました。
http://research.sakura.ad.jp/2010/03/17/kvs-intro/
ありがとうございますm(_ _)m


KVS勉強会とかやりたいな〜。