目次
# キー単位 オプション実装されているが、商用設定には未展開。
Erlangの主な利点は、




物理的なノード障害の場合、ブリックは自動的に役割をシフトし、それぞれのチェインはクライアントにサービスを提供し続ける。

データを再配置するきっかけ:


キー・バリュー・ストアであることから、HibariのコアデータモデルとクライアントAPIモデルは、設計においてシンプル。:
blobベースのキー・バリュー・ペア
オペレーション
Hibariは、複数のクライアント API実装をサポート:
Java, C/C++, Python, Ruby, Erlangを含む様々な言語におけるHibariクライアント・アプリケーション開発が可能
atom はリテラルで、名前を持つ定数。atomは、小文字で開始する場合や、アルファベット、数値、アンダースコア (_), や @以外の文字を含む場合には、シングル・クォート (') で囲まれるべき。
hello phone_number 'Monday' 'phone number' 'hello' 'phone_number'
bit string は、非型式メモリーの領域を格納するために使われる。8で割り切れるビットからなるbit string は、 binary と呼ばれる。
<<10,20>> <<"ABC">>
tuple は、中括弧で囲まれる固定数をもつ複合データ型式。:
{Term1,...,TermN}list は、鍵括弧で囲まれる変数をもつ複合データ型式。:
[Term1,...,TermN]
true とfalse がBoolean values を表示するために使われる。
_… 数点追加_
ファイル "math.erl" は次のプログラムを含む。:
-module(math). -export([fac/1]). fac(N) when N > 0 -> N * fac(N-1); fac(0) -> 1.
このプログラムは、Erlang shellを使いながらコンパイルされ動作する。
$ erl
Erlang R14B01 (erts-5.8.2) [source] [64-bit] [smp:2:2] [rq:2] [async-threads:0] [hipe] [kernel-poll:false]
Eshell V5.8.2 (abort with ^G)
1> c(math).
{ok,math}
2> math:fac(25).
15511210043330985984000000強制終了させる …
3> math:fac(-1). ** exception error: no function clause matching math:fac(-1)
append([], L) -> L; append([H | T], L) -> [H | append(T, L)].
qsort([]) -> [];
qsort([H | T]) ->
qsort([ X || X <- T, X < H ]) ++
[H] ++
qsort([ X || X <- T, X >= H ]).> Adder = fun(N) -> fun(X) -> X + N end end. #Fun<erl_eval.6.13229925> > G = Adder(10). #Fun<erl_eval.6.13229925> > G(5). 15
{'ok', timestamp(), val()}.
{ok, {[{key(), timestamp(), val()}], boolean()}}.
'txn'|OpList]
"シングル" オペレーションは、 do/4 機能を利用しながら実装されています(hoodの下で). |
Tab
型式:
Tab = table()
table() = atom()
Key
型式:
Key = key()
key() = iodata()
iodata() = iolist() | binary()
iolist() = [char() | binary() | iolist()]
|
Value
型式:
Value = val()
val() = iodata()
iodata() = iolist() | binary()
iolist() = [char() | binary() | iolist()]
ExpTime
型式:
ExpTime = exp_time()
exp_time() = time_t()
time_t() = integer()
Flags
型式:
Flags = flags_list()
flags_list() = [do_op_flag() | property()]
do_op_flag() = {'testset', timestamp()}
timestamp() = integer()
property() = atom() | {term(), term()}
オペレーショナル・フラグ利用
{'testset', timestamp()}
timestamp() と正確に等しくない場合には、オペレーションは失敗する。マイクロ・トランザクション内で利用される場合には、keyのtimestampが、timestamp() と正確に等しくない場合には、トランザクションを停止
Timeout
型式:
Timeout = timeout()
timeout() = integer()
エラー・リターン
'key_not_exist'
{'key_exists',timestamp()}
timestamp() = integer()
{'ts_error', timestamp()}
{'testset', timestamp()} フラグは使われており、timestampのミスマッチがあったため、オペレーションは失敗した。 リターンにおけるtimestamp() は、 既存の keyのtimestampの現在のバリュー。
timestamp() = integer()
'invalid_flag_present'
Flags 引数に無効な do_op_flag() が見つかったため、オペレーションは失敗した。
'brick_not_available'
{{'nodedown',node()},{'gen_server','call',term()}}
node() = atom()
オペレーショナル・フラグ利用
'get_all_attribs'
witness flagとの組み合わせで利用され得る。
'witness'
サクセス・リターン
{'ok', timestamp(), val()}
{'ok', timestamp()}
'witness' を使うが、'get_all_attribs' を使わない場合のサクセス・リターン
{'ok', timestamp(), proplist()}
'witness' と 'get_all_attribs' の両方を使う場合のサクセス・リターン
{'ok', timestamp(), val(), exp_time(), proplist()}
'get_all_attribs' だが 'witness' でない場合のサクセス・リターン
For proplists, |
オペレーショナル・フラグ利用
'get_all_attribs'
witness flagと組み合わせて使われ得る。
'witness'
{'binary_prefix', binary()}
binary() に等しいkeyの場合だけリターンする。
{'max_bytes', integer()}
integer() バイトを超えない程度までの多さのkeyだけにリターンする。
仮に、この flag がクライアント・リクエストにおいて明示されない場合、バリューのデフォルトは2GBまで。
{'max_num', integer()}
サクセス・リターン
{ok, {[{key(), timestamp(), val()}], boolean()}}
{ok, {[{key(), timestamp()}], boolean()}}
get_many が'witness' を利用するが、'get_all_attribs' を利用しない場合のサクセス・リターン
`{ok, {[{key(), timestamp(), proplist()}], boolean()}}
get_many が'witness' と 'get_all_attribs' の両方を利用する場合のサクセス・リターン
{ok, {[{key(), timestamp(), val(), exp_time(), proplist()}],
boolean()}}
get_many が 'get_all_attribs' だが 'witness' でない場合のサクセス・リターン
|
For proplists, |
エラー・リターン
{txn_fail, [{integer(), do1_res_fail()}]}
do request と、ひとつ、若しくはそれ以上の初期オペレーションで利用されたために、オペレーションは失敗した。integer() は、リクエストの OpList 内の位置により失敗した初期オペレーションを示す。例としては、 a 2 は、失敗したリクエストの OpList 2番目のリストであることを示す。この位置識別子は、 OpList のスタートにおいて txn() 指示子を数えてはいないことに注意。
ディレクトリを作成
$ mkdir running-directory
Hibari tarball package を解凍- "hibari-X.Y.Z-DIST-ARCH-WORDSIZE.tgz"
$ tar -C running-directory -xvf hibari-X.Y.Z-DIST-ARCH-WORDSIZE.tgz
Hibariをスタート:
$ running-directory/hibari/bin/hibari start
システムをブートストラップ:
$ running-directory/hibari/bin/hibari-admin bootstrap ok
Hibari を停止 (必要があれば後で):
$ running-directory/hibari/bin/hibari stop
"Hibari Web Administration" ページを開くことができるかを確認:
$ firefox http://127.0.0.1:23080 &
Hibari ノードにpingを成功できるかを確認:
$ running-directory/hibari/bin/hibari ping pong
シングル・ノードのHibariシステムは、ローカルホスト・アドレス 127.0.0.1. に対してハードコードされている。結果として、Hibari ノードは、ノード自身からだけ連絡可能。 |
Erlangのリモート/シェルを利用してHibariに接続
$ running-directory/hibari/erts-5.8.2/bin/erl -name hogehoge@127.0.0.1 -setcookie hibari -kernel net_ticktime 20 -remsh hibari@127.0.0.1 Erlang R14B01 (erts-5.8.2) [source] [64-bit] [smp:2:2] [rq:2] [async-threads:0] [hipe] [kernel-poll:false] Eshell V5.8.2 (abort with ^G) (hibari@127.0.0.1)1>
ノードネームと一連の接続されたErlang ノードを確認
(hibari@127.0.0.1)1> node(). 'hibari@127.0.0.1' (hibari@127.0.0.1)2> nodes(). ['hogehoge@127.0.0.1'] (hibari@127.0.0.1)3>
Hibariの名前、クッキー、カーネルnet_ticktime は設定可能であり、running-directory/hibari/etc/vm.args fileのなかに置かれている。 |
"rlwrap -a running-directory/hibari/erts-5.8.2/bin/erl" ツールは、Erlang shell履歴をトラッキングし続けるために有用 (例 yum install rlwrap). |
2 つのハッシュ・プレフィックスとチェイン毎に3 つのブリックを持つ新規テーブルを作成
$ running-directory/hibari/bin/hibari-admin create-table tab2 \
-bigdata -disklogging -syncwrites \
-varprefix -varprefixsep 47 -varprefixnum 2 \
-bricksperchain 3 \
hibari@127.0.0.1 hibari@127.0.0.1 hibari@127.0.0.1例として、キーが表す最初の部分を user’s idとする。2のハッシュ・プレフィックスは、同じチェインに格納される個々のユーザーのkeysを作成する。…しかし他のユーザーのキーと同じチェインとは限らない。
: /user1/adir/ /user1/adir/file1 /user1/adir/file3 /user1/file1 /user1/file4 /user1/xdir/ /user1/xdir/fileY : /user2/file1 : /user3/file4 :
テーブルは、Hibariの管理サーバー・ウェブページを利用して作成することもできます。 |
このエクササイズの目的は、Hibariについて学び、実装し、HibariのネイティブErlangクライアントを利用しながら、ご自身のHibariのミニ・アプリケーションをテストすることです。
15 秒程度待ち、HibariのSchema.local file とdata filesをバックアップ:
$ tar -cvzf backup.tgz running-directory/hibari/Schema.local running-directory/hibari/data/brick
HibariのSchema.local and data filesを削除:
$ rm -r running-directory/hibari/Schema.local running-directory/hibari/data/brick/*
HibariのSchema.local and data filesを修復:
$ tar -xvzf backup.tgz
Erlang Shellを使い、 Hibariのアプリケーション開発者ガイドにリストされている例を再現する
この例を実行している間、またその後にHibariの管理サーバー・ウェブページでどんな変化を見ることができますか?
Hibariの新しいAPIを実装するが、クライアント側で行う(サーバー側では無く)
⇒ 'ok' |
'key_not_exist' | {'ts_error', timestamp()} | {'key_exists',timestamp()}
'testset' flagを除く)。
'key_not_exist' がリターン
{'testset', timestamp()} を含み、OldKeyにtimestampのミスマッチがあり、 `{ts_error,
timestamp()}`をリターン。
proplists:delete/2 と proplists:get_value/3 は、Flags フィルタリングのために使われます。
{'testset', timestamp()} flag は、あなたの友達です。
Mnesia は、Erlang/OTPによる分散型データベース管理システム。Mnesiaは、 dirty_update_counter/3 オペレーションをサポートする。Hibariと同様のAPIを実装し、それをクライアント側(サーバー側では無く)で行う。
⇒ {'ok', NewVal} | 'invalid_arg_present' | {non_integer,timestamp()} | exit by Timeout.
'invalid_arg_present' をリターン。
{'ok', NewVal} がリターンされる。
{'testset', timestamp()} flagは、あなたの友達です。
if is_integer(X) -> ...; true -> ... end. を利用してください。
erlang:integer_to_binary/1 と
erlang:binary_to_integer/1 は、たいへんに有用 (そして、必要)。
erlang:now/0 and timer:now_diff/2 は、絶対Now timeを設定し、新しい絶対Now timeとそれぞれ比較するために使われる。Timeoutは、ミリ秒です。Nowはマイクロ秒です。
Hibariのキー・バリュー・データモデルを使って、ファイルシステムのようなクライアントAPIを実装してください。
'ok' | {'dir_exists', timestamp()}.
{'ok', Names} | 'dir_not_exist'.
'ok' | 'dir_not_exist' | 'dir_not_empty'.
'ok' | 'dir_not_exist' | {'file_exists', timestamp()}.
'ok' | 'file_not_exist'.
'ok' | 'file_not_exist'.
{'ok', Data} | 'file_not_exist'.
HibariのGitHub レポジトリとウェブページの更新を常に確認してください。
|
Hibari Open Source project | |
|
Hibari Twitter |
@hibaridb Hashtag: #hibaridb |
|
Gemini Twitter |
@geminimobile |
|
Big Data blog | |
|
Slideshare |