Aerospike deep dive LDTs

60
copyright Fringe81 Co.,Ltd. Aerospike Tech Deep Dive v3新機能 Large Data Typesを中心に

Transcript of Aerospike deep dive LDTs

Page 1: Aerospike deep dive LDTs

- -copyright Fringe81 Co.,Ltd.

Aerospike Tech Deep Divev3新機能 Large Data Typesを中心に

Page 2: Aerospike deep dive LDTs

- -copyright Fringe81 Co.,Ltd.

・@mtoyoshi

・Fringe81・Java, Scala・アドテク畑 DSP→DMP→ADNW

・Aerospike歴1年

自己紹介

Page 3: Aerospike deep dive LDTs

- -copyright Fringe81 Co.,Ltd.

Aerospikeは...

速い運用コストが低い

スケーラビリティ高いetc...

Page 4: Aerospike deep dive LDTs

- -copyright Fringe81 Co.,Ltd.

インフラ的な話が多い?

今日はプログラミング話

Page 5: Aerospike deep dive LDTs

- -copyright Fringe81 Co.,Ltd.

2015/04 Aerospike行ってきた

Page 6: Aerospike deep dive LDTs

- -copyright Fringe81 Co.,Ltd.

ステーキの写真

Page 7: Aerospike deep dive LDTs

- -copyright Fringe81 Co.,Ltd.

クライアントライブラリ

新機能の実装優先度

Page 8: Aerospike deep dive LDTs

- -copyright Fringe81 Co.,Ltd.

1st Priority

Page 9: Aerospike deep dive LDTs

- -copyright Fringe81 Co.,Ltd.

2nd Priority

Page 10: Aerospike deep dive LDTs

- -copyright Fringe81 Co.,Ltd.

Aerospike↓

アドテク?↓

Scala??

Page 11: Aerospike deep dive LDTs

- -copyright Fringe81 Co.,Ltd.

Aerospike Community Labshttp://www.aerospike.com/community/labs/

Page 12: Aerospike deep dive LDTs

- -copyright Fringe81 Co.,Ltd.

大体の使い方を知るにはサンプルプログラムを読む/実行する

のが手っ取り早い

あとドキュメントが充実してきている

Page 13: Aerospike deep dive LDTs

- -copyright Fringe81 Co.,Ltd.

https://www.aerospike.com/docs/operations/install/vagrant/mac/

Page 14: Aerospike deep dive LDTs

- -copyright Fringe81 Co.,Ltd.

http://localhost:8081

Page 15: Aerospike deep dive LDTs

- -copyright Fringe81 Co.,Ltd.

% vagrant ssh

$ cd ClientInstall$ ./as_java_install.sh$ cd ~/aerospike-client-java-3.1.2/examples$ ./run_examples all

Page 16: Aerospike deep dive LDTs

- -copyright Fringe81 Co.,Ltd.

Page 17: Aerospike deep dive LDTs

- -copyright Fringe81 Co.,Ltd.

ここまで

30分で出来た

※Vagrant自体のインストールは除く

Page 18: Aerospike deep dive LDTs

- -copyright Fringe81 Co.,Ltd.

GitHubで公開されているclientライブラリにもexamplesが同梱

但しクライアントライブラリ(プログラミング言語)によってexamplesの充実度が異なる

※例えばLDTsはrubyやphpには2015/06時点で無かったり一部だったり

※充実度ではJavaが一番良さそう

Page 19: Aerospike deep dive LDTs

- -copyright Fringe81 Co.,Ltd.

基本の「保存」&「検索」

Page 20: Aerospike deep dive LDTs

- -copyright Fringe81 Co.,Ltd.

client.put( new WritePolicy(), new Key(“namespace”, “setname”, “key1”), new Bin(“num”, 1), new Bin(“bool”, true));

Bin部は可変長引数

Page 21: Aerospike deep dive LDTs

- -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

Page 22: Aerospike deep dive LDTs

- -copyright Fringe81 Co.,Ltd.

Serializableを実装している任意のクラスも保存可能

Record#getListRecord#getMapはないRecord#getObjectを使用してダウンキャスト

boolean

int

long

float

double

String

List

Map

Object

byte[]

Page 23: Aerospike deep dive LDTs

- -copyright Fringe81 Co.,Ltd.

msgpackの仕様に基づきシリアライズされて保存

Page 24: Aerospike deep dive LDTs

- -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

Page 25: Aerospike deep dive LDTs

- -copyright Fringe81 Co.,Ltd.

でもver.3からできる

Page 26: Aerospike deep dive LDTs

- -copyright Fringe81 Co.,Ltd.

ver.3からAerospike DBとして

List / Set / Map / Stackをサポート

それがLarge Data Types(LDTs)

Page 27: Aerospike deep dive LDTs

- -copyright Fringe81 Co.,Ltd.

LargeList llist = client.getLargeList( writePolicy, key, binName);

llist.add(Value.get(“z”))

getLargeList時点では通信は発生しない。“z”だけの追加が可能。

Page 28: Aerospike deep dive LDTs

- -copyright Fringe81 Co.,Ltd.

add / updatescan / find / range / filterremove / destroysize

LargeListはkeyのASCでソートされるO(logN)の探索となる

LargeListのメソッド

Page 29: Aerospike deep dive LDTs

- -copyright Fringe81 Co.,Ltd.

llist.add(Value.get(“a,99”));llist.add(Value.get(“b,1”));

これだと文字列順でa,bとソート

Page 30: Aerospike deep dive LDTs

- -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つは省略

Page 31: Aerospike deep dive LDTs

- -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メソッドのソースコード

Page 32: Aerospike deep dive LDTs

- -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

Page 33: Aerospike deep dive LDTs

- -copyright Fringe81 Co.,Ltd.

Luaスクリプトは自分で書くことも出来る

UDF(User-Defined Functions)

と呼ぶ

Page 34: Aerospike deep dive LDTs

- -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)

Page 35: Aerospike deep dive LDTs

- -copyright Fringe81 Co.,Ltd.

・クライアント: いくら足すのかを指定

・サーバー: udfにて、指定された値を全要素に足す ※replaceできない(?)ので削除&追加で表現

シナリオ

Page 36: Aerospike deep dive LDTs

- -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を保存しておく

Page 37: Aerospike deep dive LDTs

- -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’

Page 38: Aerospike deep dive LDTs

- -copyright Fringe81 Co.,Ltd.

client.execute( writePolicy, key, “myfunc”, “addr”, Value.get(“binName”), Value.get(1));

クライアントでmyfunc.addrを引数2つで呼び出し

Page 39: Aerospike deep dive LDTs

- -copyright Fringe81 Co.,Ltd.

System.out.println(llist.scan());

[2,3,4]と表示される。もとのListに+1された事が確認できた。※List<?>が返る

Page 40: Aerospike deep dive LDTs

- -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:

Page 41: Aerospike deep dive LDTs

- -copyright Fringe81 Co.,Ltd.

他にも制限がある・XDR(※1)ではLDTは対象外 ・aql(※2)で内容を確認できない

※1 Cross Datacenter Replication※2 SQLライクな対話型ツール

Page 42: Aerospike deep dive LDTs

- -copyright Fringe81 Co.,Ltd.

制限とはちょっと違うが

・LDTのデータは1つのサーバーノードで保存されクラスタ内に分散するわけではない

・TTLはRecord単位で、LDTのデータ(要素)単位ではない

・LDT処理はlua使う分CPU消費する

・LDT x Luaはサンプル少なくちょっと苦労

Page 43: Aerospike deep dive LDTs

- -copyright Fringe81 Co.,Ltd.

aqlの話を少ししてみる

Page 44: Aerospike deep dive LDTs

- -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句欲しい、が難しいらしい

Page 45: Aerospike deep dive LDTs

- -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が表示されない。が...

Page 46: Aerospike deep dive LDTs

- -copyright Fringe81 Co.,Ltd.

WritePolicy wp = new WritePolicy(); wp.sendKey = true;

client.put(wp, ...

Page 47: Aerospike deep dive LDTs

- -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での表示以外にも...

Page 48: Aerospike deep dive LDTs

- -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の値が必要になることが多い。

Page 49: Aerospike deep dive LDTs

- -copyright Fringe81 Co.,Ltd.

OSS化

2014.6.24

Page 50: Aerospike deep dive LDTs

- -copyright Fringe81 Co.,Ltd.

Community Edition?Enterprise Edition?

Page 51: Aerospike deep dive LDTs

- -copyright Fringe81 Co.,Ltd.

あまり使われていない機能(主に新機能)や環境を使う場合は

Enterprise Editionを推奨

Page 52: Aerospike deep dive LDTs

- -copyright Fringe81 Co.,Ltd.

Aerospike自身のバグの可能性も

米国チームやインドチームに調査依頼出来る※日本語でOK

※英語チャットもOK

日本に来てくれることも

Page 53: Aerospike deep dive LDTs

- -copyright Fringe81 Co.,Ltd.

でもCommunity Edition利用も

広がって欲しい

Page 54: Aerospike deep dive LDTs

- -copyright Fringe81 Co.,Ltd.

Page 55: Aerospike deep dive LDTs

- -copyright Fringe81 Co.,Ltd.

Page 56: Aerospike deep dive LDTs

- -copyright Fringe81 Co.,Ltd.

Page 57: Aerospike deep dive LDTs

- -copyright Fringe81 Co.,Ltd.

自分で薄いScalaラッパー作ってしまった。

みんなはどうしているんだろう?

調査発表とかソースコードリーディング勉強会?

Page 58: Aerospike deep dive LDTs

- -copyright Fringe81 Co.,Ltd.

最後に...

Page 59: Aerospike deep dive LDTs

- -copyright Fringe81 Co.,Ltd.

We’re hiring!

Page 60: Aerospike deep dive LDTs

- -copyright Fringe81 Co.,Ltd.

参考資料

GitHub上のClientライブラリ以外のサンプルコード

https://github.com/aerospike/ldt-exampleshttps://github.com/aerospike/url-tracker