読者です 読者をやめる 読者になる 読者になる

Riak事始

Erlang Riak

RiakはErlang製の分散型KVS。

「またKVSですか」という見方もあるかと思うが、RiakはRiakなりの良さがある。まずインストールが簡単。以下のページからRPMをダウンロードしてインストールすればOK。

Erlangを使っているKVSだと他にmembaseHibari等があるが、これらが「どうしてパッケージ構成がこんなに複雑なんだろう」と首を傾げてしまうのに対して、Riakはかなり親切。RPMもRHELの流儀にのっとっており、好感度が高い。

もう一つの特徴として、ストレージ層やトランスポート層がpluggableであるという点がある。Riakに興味をもったきっかけは、innostoreというEmbedded InnoDBを使ったストレージプラグインを試してみたかったから。InnoDBをストレージエンジンに使った分散型KVSというのは自分的には理想型に近い。

innostoreもRPMでさくっと入る。

innostoreを有効にしてRiakを使うにはapp.config(RHRL, CentOSならば/etc/riak/app.config)のstorage_backendの設定を変更し、

 %% Riak KV config
 {riak_kv, [
            %% Storage_backend specifies the Erlang module defining the storage
            %% mechanism that will be used on this node.
            %%{storage_backend, riak_kv_bitcask_backend},
            {storage_backend, riak_kv_innostore_backend},

同じくapp.configにinnostoreの設定を追加する。

 %% SASL config
 {sasl, [
         {sasl_error_logger, {file, "/var/log/riak/sasl-error.log"}},
         {errlog_type, error},
         {error_logger_mf_dir, "/var/log/riak/sasl"},      % Log directory
         {error_logger_mf_maxbytes, 10485760},   % 10 MB max file size
         {error_logger_mf_maxfiles, 5}           % 5 files max
         ]},

  %% Inno db config
  {innostore, [
               {data_home_dir,      "/var/lib/riak/innodb"},
               {log_group_home_dir, "/var/lib/riak/innodb"},
               {error_log,          "/var/log/riak/innostore.log"},
               {buffer_pool_size,   16777216} %% 16M of buffer
              ]}

さらにvm.config(/etc/riak/vm.config)に、

## Enable innostore
-smp enable
-pa /usr/lib64/innostore/ebin

を追加。64ビット環境ならば"-pa /usr/lib64/innostore/ebin"が必要、Single CPUの環境では"-snp enable"の方が必要。VirtualBox上の仮想マシンで試していてこの点をわすれていてちょっとハマッた。

innostoreの設定方法に関しては公式のドキュメントが一番詳しい。

Riakを起動するには、

$ sudo /sbin/service riak start

Riakの使い方としては、Pythonならば、riakクライアントライブラリをインストールした上で、次のような感じ。

from riak import RiakClient                                                                                                   
from riak import RiakPbcTransport, RiakHttpTransport                                                                          
                                                                                                                              
client = RiakClient('127.0.0.1', port=8087, transport_class=RiakPbcTransport)                                                 
#client = RiakClient('127.0.0.1', port=8098, transport_class=RiakHttpTransport)                                               
bucket = client.bucket('bucket')                                                                                              
obj = bucket.new('spam', {'spam': 1, 'egg': 2, 'ham': 3})                                                                     
obj.store()                                                                                                                   
obj = bucket.get('spam')                                                                                                      
                                                                                                                              
print 'bucket', obj.get_bucket().get_name()                                                                                   
print 'key', obj.get_key()                                                                                                    
print 'data', obj.get_data()