Cassandraのgetを計測する

insertを計るならgetも計るべし,ということでgetも計測してみた.

計測方法

まずはデータの大きさを1バイトから10kバイトまで変えながらinsert.
キーを一意にするために,データサイズと繰り返し回数を使って生成したMD5をキーに使っています.

require 'digest/md5'
require 'rubygems'
require 'cassandra'

client = Cassandra.new('MyKeyspace', 'server:9160')

0.step(10000, 100) do |data_size|
  1.upto(1000) do |count|
    key = Digest::MD5.hexdigest("#{data_size}#{count}")
    client.insert(:Scores, key, {"cource" => {"math" => rand(10 ** data_size)}})
  end
end

ここまでは下ごしらえ.後は,事前insertしておいたデータをgetを繰り返して計測です.

require 'digest/md5'
require 'benchmark'
require 'rubygems'
require 'cassandra'

client = Cassandra.new('MyKeyspace', 'server:9160')

# キー値生成を計測に含めないように事前に生成
keys = []
0.step(10000, 100) do |data_size|
  same_data_size_keys = []
  1.upto(1000) do |count|
    key = Digest::MD5.hexdigest("#{data_size}#{count}")
    same_data_size_keys << key
  end
  keys << same_data_size_keys
end

keys.each do |same_data_size_keys|
  puts Benchmark.measure {
    same_data_size_keys.each do |key|
      client.get(:Scores, key, "cource", "math")
    end
  }
end

MD5生成の時間をベンチマーク内に入れないようにするため,汚いコードになってしまった...

実行結果

 0.450000   0.010000   0.460000 (  1.640000)
 0.410000   0.020000   0.430000 (  1.460000)
 0.340000   0.010000   0.350000 (  1.356000)
 0.310000   0.010000   0.320000 (  1.360000)
 0.300000   0.000000   0.300000 (  1.348000)
 0.320000   0.010000   0.330000 (  1.348000)
 ...

相変わらずこれでは何だかさっぱりなので,グラフで.

※縦軸は1回当たりの数値と見なすために1000で割っています.


データサイズが1KB以下の場合に1.2〜1.5倍程度遅くなっていた.それを除けばほぼ一定で推移している.
何で,こうなるのかは分からない...
その後,もしかして,insertした直後はサーバ側のメモリ上にキャッシュとして残ってるのではと思い,
一度Cassndra自体を再起動して計り直してみた.

再起動すると最初が倍以上遅い.その後は変わらなくなる.
安定すると再起動前と同じ位の速度になるようです.
データサイズを大きい順に走行させれば逆の傾向になるのかなー.今度やってみよう.