- -copyright Fringe81 Co.,Ltd.
Aerospike Tech Deep Divev3新機能 Large Data Typesを中心に
- -copyright Fringe81 Co.,Ltd.
・@mtoyoshi
・Fringe81・Java, Scala・アドテク畑 DSP→DMP→ADNW
・Aerospike歴1年
自己紹介
- -copyright Fringe81 Co.,Ltd.
Aerospikeは...
速い運用コストが低い
スケーラビリティ高いetc...
- -copyright Fringe81 Co.,Ltd.
インフラ的な話が多い?
今日はプログラミング話
- -copyright Fringe81 Co.,Ltd.
2015/04 Aerospike行ってきた
- -copyright Fringe81 Co.,Ltd.
ステーキの写真
- -copyright Fringe81 Co.,Ltd.
クライアントライブラリ
新機能の実装優先度
- -copyright Fringe81 Co.,Ltd.
1st Priority
- -copyright Fringe81 Co.,Ltd.
2nd Priority
- -copyright Fringe81 Co.,Ltd.
Aerospike↓
アドテク?↓
Scala??
- -copyright Fringe81 Co.,Ltd.
Aerospike Community Labshttp://www.aerospike.com/community/labs/
- -copyright Fringe81 Co.,Ltd.
大体の使い方を知るにはサンプルプログラムを読む/実行する
のが手っ取り早い
あとドキュメントが充実してきている
- -copyright Fringe81 Co.,Ltd.
https://www.aerospike.com/docs/operations/install/vagrant/mac/
- -copyright Fringe81 Co.,Ltd.
http://localhost:8081
- -copyright Fringe81 Co.,Ltd.
% vagrant ssh
$ cd ClientInstall$ ./as_java_install.sh$ cd ~/aerospike-client-java-3.1.2/examples$ ./run_examples all
- -copyright Fringe81 Co.,Ltd.
- -copyright Fringe81 Co.,Ltd.
ここまで
30分で出来た
※Vagrant自体のインストールは除く
- -copyright Fringe81 Co.,Ltd.
GitHubで公開されているclientライブラリにもexamplesが同梱
但しクライアントライブラリ(プログラミング言語)によってexamplesの充実度が異なる
※例えばLDTsはrubyやphpには2015/06時点で無かったり一部だったり
※充実度ではJavaが一番良さそう
- -copyright Fringe81 Co.,Ltd.
基本の「保存」&「検索」
- -copyright Fringe81 Co.,Ltd.
client.put( new WritePolicy(), new Key(“namespace”, “setname”, “key1”), new Bin(“num”, 1), new Bin(“bool”, true));
Bin部は可変長引数
- -copyright Fringe81 Co.,Ltd.
getBooleanとgetObjectで挙動が異なる
Record record = client.get( new Policy(), new Key(“namespace”, “setname”,“key1”), “num”);
int n = record.getInt(“num”); // 1boolean b = record.getBoolean(“bool”); // falseObject o = record.getValue(“bool”); // null
- -copyright Fringe81 Co.,Ltd.
Serializableを実装している任意のクラスも保存可能
Record#getListRecord#getMapはないRecord#getObjectを使用してダウンキャスト
boolean
int
long
float
double
String
List
Map
Object
byte[]
- -copyright Fringe81 Co.,Ltd.
msgpackの仕様に基づきシリアライズされて保存
- -copyright Fringe81 Co.,Ltd.
val list = List(“x”, “a”, “c”)
list :+ “f” // 追加list.dropWhile(_ == “a”) // 削除list.find(_ == “c”) // 検索list.sorted // ソート
Aerospike上にListが保存されていてもプログラミング言語のListのように
1要素だけ追加とか出来ない
取得→Listの操作→保存
Scala
- -copyright Fringe81 Co.,Ltd.
でもver.3からできる
- -copyright Fringe81 Co.,Ltd.
ver.3からAerospike DBとして
List / Set / Map / Stackをサポート
それがLarge Data Types(LDTs)
- -copyright Fringe81 Co.,Ltd.
LargeList llist = client.getLargeList( writePolicy, key, binName);
llist.add(Value.get(“z”))
getLargeList時点では通信は発生しない。“z”だけの追加が可能。
- -copyright Fringe81 Co.,Ltd.
add / updatescan / find / range / filterremove / destroysize
LargeListはkeyのASCでソートされるO(logN)の探索となる
LargeListのメソッド
- -copyright Fringe81 Co.,Ltd.
llist.add(Value.get(“a,99”));llist.add(Value.get(“b,1”));
これだと文字列順でa,bとソート
- -copyright Fringe81 Co.,Ltd.
上記だとkeyの数字順でb,aとソート※“key”が特殊な意味を持つ
Map<String,Value> m = new HashMap<>();
m.put(“key”,Value.get(99));m.put(“value”, Value.get(“a,99”));
list.add(Value.get(m));※もう1つは省略
- -copyright Fringe81 Co.,Ltd.
どうやって1要素だけの差分追加等を実現しているのか?
public void add(Value v) { client.execute(policy, key, PackageName, "add", binName, v);}
private static final String PackageName = "llist";
LargeList.javaのaddメソッドのソースコード
- -copyright Fringe81 Co.,Ltd.
サーバーに配置されたluaプログラムを実行するためのメソッド。LDT処理はサーバーのluaで実行される。
インストール時に/opt/aerospike/sys/udf/luaにluaスクリプトが配置される。
function llist.add (topRec, ldtBinName, newValue, createSpec, src) local meth = "llist.add()"; local rc = aerospike:set_context( topRec, UDF_CONTEXT_LDT ); if (rc ~= 0) then error(ldte.ERR_NS_LDT_NOT_ENABLED); end
if newValue == nil then ...略...end
/opt/aerospike/sys/udf/lua/ldt/lib_llist.lua
AerospikeClient#execute
- -copyright Fringe81 Co.,Ltd.
Luaスクリプトは自分で書くことも出来る
UDF(User-Defined Functions)
と呼ぶ
- -copyright Fringe81 Co.,Ltd.
val l = List(1,2,3)
val addr = (a:Int, b:Int) => a + bl.map(n => addr(1, n))
Scala
(ちょっと苦しいが)UDFで実現してみる
List(1,2,3) -> +1 -> List(2,3,4)
- -copyright Fringe81 Co.,Ltd.
・クライアント: いくら足すのかを指定
・サーバー: udfにて、指定された値を全要素に足す ※replaceできない(?)ので削除&追加で表現
シナリオ
- -copyright Fringe81 Co.,Ltd.
LargeList llist = client.getLargeList( writePolicy, key, binName);
llist.add( Value.get(1), Value.get(2), Value.get(3));
1,2,3というLListを保存しておく
- -copyright Fringe81 Co.,Ltd.
local llist_lib = require(‘ldt/lib_llist’);function addr(rec, binName, numVal) local l = list()
elems = llist_lib.scan(rec, binName, nil, nil, nil, nil) for e in list.iterator(elems) do list.append(l, e + numVal) end
llist_lib.destroy(rec, binName) llist_lib.add_all(rec, binName, l);
return numValend
aql> register module ‘myfunc.lua’
- -copyright Fringe81 Co.,Ltd.
client.execute( writePolicy, key, “myfunc”, “addr”, Value.get(“binName”), Value.get(1));
クライアントでmyfunc.addrを引数2つで呼び出し
- -copyright Fringe81 Co.,Ltd.
System.out.println(llist.scan());
[2,3,4]と表示される。もとのListに+1された事が確認できた。※List<?>が返る
- -copyright Fringe81 Co.,Ltd.
・ソート順は昇順のみ
・aerospike.confのwrite block size設定によって1要素の容量が制限される- 1Mbなら200kb- 128Kbなら30kb- なお要素数の制限は無い
・add_all()/update_all()での実行で挿入できるデータ容量は1GBまで(luaの限界)
・BinaryDataTypeおよびmin()/max()はunder construction
http://www.aerospike.com/docs/guide/llist.html
Limitation:
- -copyright Fringe81 Co.,Ltd.
他にも制限がある・XDR(※1)ではLDTは対象外 ・aql(※2)で内容を確認できない
※1 Cross Datacenter Replication※2 SQLライクな対話型ツール
- -copyright Fringe81 Co.,Ltd.
制限とはちょっと違うが
・LDTのデータは1つのサーバーノードで保存されクラスタ内に分散するわけではない
・TTLはRecord単位で、LDTのデータ(要素)単位ではない
・LDT処理はlua使う分CPU消費する
・LDT x Luaはサンプル少なくちょっと苦労
- -copyright Fringe81 Co.,Ltd.
aqlの話を少ししてみる
- -copyright Fringe81 Co.,Ltd.
aql> select * from test.hoge where pk='addkey'+------+| bool |+------+| 1 |+------+
aql> select * from test.hoge where pk='addkey2'+--------+| addbin |+--------+| 45 |+--------+
aql> select * from test.hoge+--------+------+| addbin | bool |+--------+------+| 45 | || | 1 |+--------+------+
limit句欲しい、が難しいらしい
- -copyright Fringe81 Co.,Ltd.
aql> select * from test.hoge where pk='addkey'+------+| bool |+------+| 1 |+------+
aql> select * from test.hoge where pk='addkey2'+--------+| addbin |+--------+| 45 |+--------+
aql> select * from test.hoge+--------+------+| addbin | bool |+--------+------+| 45 | || | 1 |+--------+------+
Keyが表示されない。が...
- -copyright Fringe81 Co.,Ltd.
WritePolicy wp = new WritePolicy(); wp.sendKey = true;
client.put(wp, ...
- -copyright Fringe81 Co.,Ltd.
aql> select * from test.hoge where pk='addkey'+------+| bool |+------+| 1 |+------+
aql> select * from test.hoge where pk='addkey2'+--------+| addbin |+--------+| 45 |+--------+
aql> select * from test.hoge+-----------+--------+------+| key | addbin | bool |+-----------+--------+------+| "addkey2" | 45 | || "addkey" | | 1 |+-----------+--------+------+
Keyが表示される なおaqlでの表示以外にも...
- -copyright Fringe81 Co.,Ltd.
client.scanAll( new ScanPolicy(), “namespace”, “setname”, new ScanCallback { public void scanCallback(Key k, Record r) { k.userKey(); // これでkeyの値が取得可能 } }); scanAllはSetのレコードを全走査する際に使用。
この時Keyの値が必要になることが多い。
- -copyright Fringe81 Co.,Ltd.
OSS化
2014.6.24
- -copyright Fringe81 Co.,Ltd.
Community Edition?Enterprise Edition?
- -copyright Fringe81 Co.,Ltd.
あまり使われていない機能(主に新機能)や環境を使う場合は
Enterprise Editionを推奨
- -copyright Fringe81 Co.,Ltd.
Aerospike自身のバグの可能性も
米国チームやインドチームに調査依頼出来る※日本語でOK
※英語チャットもOK
日本に来てくれることも
- -copyright Fringe81 Co.,Ltd.
でもCommunity Edition利用も
広がって欲しい
- -copyright Fringe81 Co.,Ltd.
- -copyright Fringe81 Co.,Ltd.
- -copyright Fringe81 Co.,Ltd.
- -copyright Fringe81 Co.,Ltd.
自分で薄いScalaラッパー作ってしまった。
みんなはどうしているんだろう?
調査発表とかソースコードリーディング勉強会?
- -copyright Fringe81 Co.,Ltd.
最後に...
- -copyright Fringe81 Co.,Ltd.
We’re hiring!
- -copyright Fringe81 Co.,Ltd.
参考資料
GitHub上のClientライブラリ以外のサンプルコード
https://github.com/aerospike/ldt-exampleshttps://github.com/aerospike/url-tracker
Top Related