ご機嫌よう、ガラパゴスのおとめです。
先日のことですが、AppleがFoundationDBをオープンソースにしたというニュースが目に止まりました。そこでFoundationDB、て何かしらん、と調べてみたら、次のように魅力的なリストができました。
- ACIDなNoSQL
- SQLで操作可能
- SSDを使う場合で、1コアで20,000書き込み/秒のスループット
- 500コアまでリニアにスケール(1400万書き込み/秒までスケールするという記事もあり)
- 読み込みは1ms、書き込みは5ms
- キーはソートされている
そこで、まずは試してみることにしました。
インストールしてみる
とりあえず適当なUbuntu Server 16.04のVMに入れてみます(システム要件を満たしていないことは置いておきます)。まあ手順は公式に書いてある通りなのですが……
$ sudo dpkg -i foundationdb-server_5.1.5-1_amd64.deb dpkg: 依存関係の問題により foundationdb-server の設定ができません: foundationdb-server は以下に依存 (depends) します: python (>= 2.6) ...しかし: パッケージ python はまだインストールされていません。
ここでガラパゴスのおとめはちょっとハマってしまいました。Ubuntu 16.04ではPython3.5が入っていて、コマンドもpython3
だからなのかな? とか、python2も入れておいて、update-alternatives
しないとダメなのかしらん? とか……
結論としては、sudo apt-get install python
するだけでした。
インストールが済んだら確認してみます。
$ fdbcli Using cluster file `/etc/foundationdb/fdb.cluster'. The database is available. Welcome to the fdbcli. For help, type `help'. fdb>
次にbindingをインストールしてみましょう。この記事を書いている時点では、以下の言語が用意されています。
使ってみる
今回はRubyから使ってみます。公式のガイドでは何故かgemを直接ダウンロードするみたいに書かれていますが、gem install fdb
で入ります。ダウンロードしたgemを使う場合は、ffi
に依存していますので一緒に入れると良いでしょう。
では早速公式のAPIリファレンスとにらめっこしつつREPLから使ってみます(Ruby 2.5.1から使っているので時々ワーニングが出ています)。
$ irb irb(main):001:0> require 'fdb' => true irb(main):002:0> FDB.api_version 510 /home/his/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/fdb-5.1.5/lib/fdbimpl.rb:173: warning: constant ::Fixnum is deprecated /home/his/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/fdb-5.1.5/lib/fdbimpl.rb:173: warning: constant ::Fixnum is deprecated /home/his/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/fdb-5.1.5/lib/fdbimpl.rb:173: warning: constant ::Fixnum is deprecated => nil irb(main):003:0> db = FDB.open => #<FDB::Database:0x000056493f1fb808 @dpointer=#<FFI::Pointer address=0x00007f4ddc001050>, @options=#<FDB::DatabaseOptions:0x000056493f1fb790 @setfunc=#<Proc:0x000056493f1fb7b8@/home/his/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/fdb-5.1.5/lib/fdbimpl.rb:553 (lambda)>>>
……ここいらへんから既に公式のリファレンスが何を言っているのかわかりません。というかAPIの説明が何もないので、ソースコードの方を見てみると、どうやらFDB.open
の戻りを使ってget
/set
/clear
することでKVSのように使えるようです。
irb(main):004:0> db.set(1, 'foo') Traceback (most recent call last): 6: from /home/his/.rbenv/versions/2.5.1/bin/irb:11:in `<main>' 5: from (irb):8 4: from /home/his/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/fdb-5.1.5/lib/fdbimpl.rb:581:in `set' 3: from /home/his/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/fdb-5.1.5/lib/fdbimpl.rb:569:in `transact' 2: from /home/his/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/fdb-5.1.5/lib/fdbimpl.rb:582:in `block in set' 1: from /home/his/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/fdb-5.1.5/lib/fdbimpl.rb:877:in `set' NoMethodError (undefined method `bytesize' for 1:Integer)
何か怒られました。Integer#bytesizeが存在しないと言われています。bytesize? じゃ文字列を入れてみたらいいのかしらん?
irb(main):005:0> db.set('1', 'foo') => "foo" irb(main):006:0> db.get('1') => "foo"
何か入ったようです。試しにFDBコンソールから確認してみましょう。するとこのようにちゃんと登録されているようです。
$ fdbcli Using cluster file `/etc/foundationdb/fdb.cluster'. The database is available. Welcome to the fdbcli. For help, type `help'. fdb> get 1 `1' is `foo'
では何件か登録してみます。
irb(main):007:0> db.set('100', 'bar') => "bar" irb(main):008:0> db.set('30', 'baz') => "baz"
既存のキーを書き換えてみます。
irb(main):009:0> db.set('1', 'hmm') => "hmm"
ところでキーは必ずソートされていると書かれていました。確認してみましょう。キーを複数取得するには、get_range
を使うと良さそうです。
irb(main):010:0> db.get_range('1','100') => [#<FDB::KeyValue:0x000056493ee77970 @key="1", @value="hmm">] irb(main):011:0> db.get_range('1','999') => [#<FDB::KeyValue:0x000056493eb7e520 @key="1", @value="hmm">, #<FDB::KeyValue:0x000056493eb7e160 @key="100", @value="bar">, #<FDB::KeyValue:0x000056493eb7d788 @key="30", @value="baz">]
ふむ。(とりあえずデフォルトでは)ソート順はCなのかしらん? そして、get_range
の引数に与えるキーの範囲ですが、始点は含んで終点は含まないことが分かりました。ためしにFDBコンソールからも見てみましょう。
fdb> getrange 1 999 Range limited to 25 keys `1' is `hmm' `100' is `bar' `30' is `baz'
ソートされているようです。
さて、今回はFoundationDBのさわりとして、RubyからかあるくKVS風に触ってみました。SQLで操作とかトランザクションとかスループットとかも多いに気になるところですが、今回はここまでにしましょう。スループットとかはErlangで10,000プロセスくらいで一気に書いてみたらいいのかしらん……?
ところでガラパゴスではエンジニアを募集しています。ご興味をお持ちの方はぜひ弊社の採用ページをご覧ください。
では、ご機嫌よう。
--
この記事は業務の一環として業務時間中に書きました。