Aerospike

AerospikeのCLIでデータをいじってみた時のメモ

More than 3 years have passed since last update.


概要

データの構成や使い勝手の理解を深める為、以前構築したAerospikeの環境(Aerospike環境構築メモ on GCP)を使ってCLIベースでいじってみたのでそのメモ。


Aerospikeのデータ構成

Configuring Aerospike - Part 2 2015-10-07 18-40-31.png

区分
定義

Cluster
Aerospikeのクラスター

Node
クラスターの構成要素

Namespace
独立したストレージ領域。複数定義可能だがNamespaceを跨いだ参照はできない。RBDでいうところのdatabaseschemeに近い。

Set
Recordをグルーピングした領域。RDBのTableに近い。

Record
データを出し入れする単位。ValueはJSON形式。RDBのRawに近い。

Bin
データの最小単位。Recordを構成するパーツ。Jsonの要素に当たる。


namespace


  • 公式ドキュメント

  • namespaceはConfigファイル(/etc/aerospike/aerospike.conf)を編集して再起動すれば追加や変更ができる

  • 設定可能な項目はConfiguration Referenceを参照

  • 設定の反映にはNodeの再起動が必要

  • 全てのNodeに設定を反映しないとクラスター間の整合が取れなくなる

  • 全Nodeに一括反映みたいのはなさそう

  • よって、そんなに頻繁に作ったり消したりするものではなさそう


データを操作する(AQL版)

Aerospike Query Language(AQL)というSQLライクにデータを操作できるコマンドラインツールが用意されているのでそれを使ってデータを操作してみる。


AQLのプロンプトを開く

$ aql

デフォルトのAerospikeサーバ内にいるならこれでOK。

外部からアクセスする場合はマニュアルに則って-h-pなどのオプションを指定する。


データの挿入

INSERT INTO <ns>[.<set>] (PK, <bins>) VALUES (<key>, <values>)


  • SQLの構文とほぼ同じだけど、スキーマレスなので(PK, <bins>)部分の省略ができないのと、(たぶん)1コマンドで1レコードしか入らない。

例:

aql> insert into test.person (PK, name, age, gender, phone_number) values (1, 'Taro', 20, 'M', 09011112222)

OK, 1 record affected.


データの参照

SELECT * FROM <ns>[.<set>]

例:

aql> select * from test.person

+----------+-----+--------+--------------+
| name | age | gender | phone_number |
+----------+-----+--------+--------------+
| "Hanako" | 22 | "F" | 9011113333 |
| "Taro" | 20 | "M" | 9011112223 |
+----------+-----+--------+--------------+
2 rows in set (0.022 secs)

namespaceまたはsetのデータを参照する。

aql> select name, age from test.person

+----------+-----+
| name | age |
+----------+-----+
| "Hanako" | 22 |
| "Taro" | 20 |
+----------+-----+
2 rows in set (0.022 secs)

取得項目をBinで絞ることも可能

aql> select * from test.person where PK = 1

+--------+-----+--------+--------------+
| name | age | gender | phone_number |
+--------+-----+--------+--------------+
| "Taro" | 20 | "M" | 9011112223 |
+--------+-----+--------+--------------+
1 row in set (0.001 secs)

WHERE句はデフォルトではPK(Record-Key)の等価比較でのみ可能

Bin単位で絞るにはインデックスを貼らないといけない(後述)

[note]

AQLでは現状Record-Keyを参照できないらしい

更新や削除にはKeyが必要なことを考えるとAQLでデータ操作するには限界がある


データの更新


  • UPDAET構文はない。

  • 同じKey名でINSERTすれば上書かれるので更新になる。

  • ただし、更新範囲はRecord単位ではなくBin単位で実行される為、更新しなかったBinはそのまま残る。

例:

aql> select * from test.person where pk = 1

+--------+-----+--------+--------------+
| name | age | gender | phone_number |
+--------+-----+--------+--------------+
| "Taro" | 20 | "M" | 9011112222 |
+--------+-----+--------+--------------+
1 row in set (0.001 secs)

aql> insert into test.person (PK, age) values (1, 21)OK, 1 record affected.

aql> select * from test.person where pk = 1
+--------+-----+--------+--------------+
| name | age | gender | phone_number |
+--------+-----+--------+--------------+
| "Taro" | 21 | "M" | 9011112222 |
+--------+-----+--------+--------------+
1 row in set (0.000 secs)


データの削除

DELETE FROM <ns>[.<set>] WHERE PK=<key>

削除にはPK(Record-key)が必要

例:

aql> delete from test.person where PK = 1

OK, 1 record affected.


インデックスを貼る

CREATE INDEX <index> ON <ns>[.<set>] (<bin>) <type>


  • インデックス名はnamespaceでユニークでないければならない

  • typeはNUMERIC or STRING

例:

aql> create index idx_person_age_numeric on test.person (age) numeric

OK, 1 index added.

インデックスを貼るとインデックスが貼られたBinでwhere句を使える。

例:

aql> select * from test.person where age = 18

+--------+-----+--------+--------------+
| name | age | gender | phone_number |
+--------+-----+--------+--------------+
| "Jiro" | 18 | "M" | 9022223333 |
+--------+-----+--------+--------------+
1 row in set (0.002 secs)

aql> select * from test.person where age between 18 and 20

+--------+-----+--------+--------------+
| name | age | gender | phone_number |
+--------+-----+--------+--------------+
| "Jiro" | 18 | "M" | 9022223333 |
| "Taro" | 20 | "M" | 9011112222 |
+--------+-----+--------+--------------+
2 rows in set (0.002 secs)


データを操作する(ascli版)

単純にKey指定でデータの出し入れや参照をするだけならAerospike CLI

を使っても可能。


データ操作系


put

recordの挿入

ascli put <ns> <set> <record-key> <record-value>


  • record-valueはJSON形式。

  • 成否は終了コードが0かどうか

  • namespace/set/record-keyが全て同一のデータがある場合は上書かれる

例:

$ ascli put test settest keytest '{"name":"hoge", "age":30, "array":[1,2,3], "map":{"mapkey":"mapvalue"}}'

$ echo $?
0


get

record-valueの取得

ascli get <ns> <set> <record-key>

例:

$ ascli get test settest keytest

{"map": { "mapkey": "mapvalue" }, "array": [ 1, 2, 3 ], "name": "hoge", "age": 30}


exists

record-keyの存在確認

ascli exists <ns> <set> <record-key>


  • 存在の有無は終了コードが0かどうか

例:

$ ascli exists test settest keytest

Key keytest exists.
$ echo $?
0

$ ascli exists test settest keytest2
Key keytest2 does not exist.
$ echo $?
2


remove

recordの削除

ascli remove <ns> <set> <record-key>


  • 成否は終了コードが0かどうか

例:

$ ascli remove test settest keytest

$ echo $?
0

$ ascli remove test settest keytest
ERROR 2 AEROSPIKE_ERR_RECORD_NOT_FOUND
$ echo $?
2


Scripting


eval

一連のascliのコマンドを実行できるシンプルなスクリプティング環境を呼び出す。

ascli eval


  • 標準入力からのコマンドを読み込むので適当なFileに書いたコマンドをパイピングして実行もできる

  • eval独自のコマンドもある

  • コマンドはスタックに保持される

  • スタックは1コマンド1000文字までで、1000コマンドまで保持する。

[Note]

evalはシングルスレッドで動作し、全ての呼び出しをブロックすることに注意する

evalの独自コマンドは以下。

コマンド
説明

:print
最後のコマンドからの統計情報を表示する

:reset
蓄積された統計情報をリセットする

:repeat n
スタック上の全てのコマンドをn回繰り返す

:clear
スタックを空にする

:quit
evalから抜ける

例:

$ ascli eval

put test evaltest test1 '{"name":"hoge"}'
:print
>>
time: 0.94500 ms
success: 1
failure: 0
:reset
:print
>>
time: 0.00000 ms
success: 0
failure: 0
:clear
get test evaltest test1
{"name": "hoge"}
:reset
:repeat 10
{"name": "hoge"}
{"name": "hoge"}
{"name": "hoge"}
{"name": "hoge"}
{"name": "hoge"}
{"name": "hoge"}
{"name": "hoge"}
{"name": "hoge"}
{"name": "hoge"}
{"name": "hoge"}
:print
>>
time: 4.98200 ms
success: 10
failure: 0
:quit

ファイルから実行する場合は以下のような感じでOK。

$ cat {evalfile} | ascli eval


所感

単純なデータ操作ならいいけど、ちょっと複雑なことやろうとすると手詰まりそうな感じ。AerospikeはUDFが定義できるみたいなので複雑な処理はそっちでやれってところかな、と思いました。

とりあえず今回の目的はデータ構成の理解なので一旦こんなもんで。

次はClientを使ってごにょごにょやる予定。