分散型KVSで、cassandraと同じようにリング型マルチマスターの特徴をもつ、riakというKVSがある。
今回riakについて諸々検証してみたので、載せておく。
[バージョン]
riakKV2.3.3
[試験内容]
500万キーで、protobufを使い、20KBのバイナリデータのPUT/GETの繰り返した。
PUT/GETの繰り返し間隔は約0.1秒で、JAVAの公式が提供するriakライブラリを使って、1時間程度試験を行った。
[サーバスペック]
8core/7.2GB/SSD.100GBの仮想マシンの6クラスター
[バケットタイプ]
# riak-admin bucket-type create my_dvv_type '
{
"props":
{
"allow_mult":false,
"last_write_wins":false,
"dvv_enabled":true,
"pw":"one",
"pr":"one",
"dw":"one"
}
}'
[結果]
結論として、公式が推奨するbitcaskは使えなかった。
bitcaskは追記型のため、同一キーに対してPUTすると、
爆発的にDISK使用量が増える。
試験を始めて、即座に100GB近くDISKを消費したため、
levelDBに切り替えてテストを行った。
(ちなみに、bitcaskは、使われなくなったキーは、mergeされるまで残り続けるらしく、
mergeの処理というのもとても重いようだ。ここは未検証。)
計算上は、
500万キー、1キーあたり20KBのデータ、
6ノード、n_valは3なので、
500万×20KB×3÷6=6GB
となり、実際もだいたい、1ノードあたり、6GB程度のlevelDBのDISK使用量であった。
で、気になるパフォーマンスだが、
PUT/GETの繰り返しを秒間3000程度はさばいたところで、
各ノードのCPU使用率が60%くらいであったが、
DISK書き込みのスループットが限界に近づいていた状態であった。
また、JAVAでメモリ上にデータのHASH値を保持し、
GET時のHASHと比較したが、ひとつもずれはなかった。
単純に、last_write_wins:trueとしたときは、ずれが生じてしまっため、
同一キーに激しくPUTする環境で、最新のデータを必ず取りたいときは、
"allow_mult":false,
"last_write_wins":false,
"dvv_enabled":true,
の設定がよいのかと思っています。
[考察]
riakは永続性が求めれる大量のデータを扱う場合、
かなり使えることが分かった。
ただし、protobufを使わないと、パフォーマンスはでないし、
各言語のライブラリは確認しておく必要あり。
(phpの3rdpartyのprotobufライブラリは60KB以上のデータ扱えない問題あり。javaは1MBでも大丈夫だった。)
クラスターからの取り外し、参加させる場合など、
キーのリハッシュが生じる際は気を付ける必要があるが、
cassandraを使うよりは設定は楽で、運用も楽そうな感じはする。
サーバのスペックとしては、
CPUもMEMORYもDISKもNETWORKも、
全ての性能がある程度求められるが、かなり使える手応えである。
今回は、KVSの機能としか見ていないが、
機能は豊富であるので、今後も期待しています。
以上