このエントリーをはてなブックマークに追加

influxdb性能評価

influxdbを試しに触ってみました。

実は1台テストとclusterテストの間には1月ぐらい間隔が開いています。また、あまりきちんとした性能評価ではありませんので、参考程度にしてください。

1台テスト

  • DigitalOcean 1GB 30GB(SSD)

最初512MBで試していましたが、OOM Killerに殺されてしまったので1GBにしました。

登録

以下のようなデータを 1000万行 分 (6GB)別ノードからHTTP POSTで送りました。

バッチサイズは30で、30個を同時に登録することにしました。

{"int": -74, "str": "ɊƭŷćҏŃȅƒŕƘȉƒŜőȈŃɊҏŷ","uint":3440,"time":1386688205}

ちなみに文字列は rotunicodeで生成したunicode文字です。100文字分を生成しています。

その時のdstatの結果がこれでした。完全に負荷側が負けてますね。

----total-cpu-usage---- -dsk/total- -net/total- ---paging-----system--
usr sys idl wai hiq siq| read  writ| recv  send|  in   out | int   csw
 52  19  27   0   2   0|   0  1508k|2313k  140k|   0     0 |5180  10k
 40  18  40   0   1   0|   0     0 |1853k  112k|   0     0 |4922  9888
 41  19  36   2   1   0|   0  2740k|1894k  113k|   0     0 |4928  9944
 46  18  34   1   1   0|   0  1504k|2009k  121k|   0     0 |4752  9516
 42  19  38   0   1   0|   0     0 |1830k  110k|   0     0 |5050  10k
 44  20  34   0   2   0|   0     0 |2022k  121k|   0     0 |5536  11k

と思って放置してたらこうなってきたので、いい感じかも。

88   8   0   3   1   0|   0  6124k|4806k  131k|   0     0 |2655  4280
87   8   0   3   2   0|   0  7232k|4785k  129k|   0     0 |2185  3364
54  11   0  34   1   0|   0  2136k|4784k  129k|   0     0 |4640  8752

そんなこんなでこれだけ時間がかかりました。

real    56m35.234s
user    16m19.658s

この時点で、DBは2.7GBでした。

1000万行を56分ということは、単純に割ると1秒に2800行処理できたということです。ただ、実際には30行をまとめて送っているので、93qpsかもしれません。

なお、前述のdstatの結果を見てもらえば分かるように、CPUが律速しているようです。Digital OceanはSSDなのでI/Oは問題にならなかっただけで、普通のHDDだとI/Oが問題になるかもしれません。

Query

それぞれ10回の合計時間です。

select * from stress limit 1000
real 0.417sec
select max(int) from stress
real 15m50.002s
select max(int) from stress where time < '2013-12-12'
236400レコードreal 0m10.699s
select count(int) from stress where '2013-12-10 23:00:00' < time and time < '2013-12-11 00:00:00'
7202レコードreal 0m0.454s

ちなみにmaxの時のCPUは99%でしたので、CPUがボトルネックかと思います。

クラスタ体制

influxdbといえばclusterですね。今度はclusterを組んでみましょう。

influxdbのclusterの組み方はドキュメントにも書いていませんが、以下の設定をconfig.tomlにすることで組むことが出来ました。

  • 1台目はseed-serversをコメントアウト
  • 2台目はseed-servers = ["(1台目のアドレス):8090"] とする

でした。clusterが組まれると、WebUIの"cluster"に出てきます。

3台目の時に2台目のアドレスを加えるかどうかは分かりませんが、おそらく加えてもいいと思います。要は1台目だけ特別、ということみたいです。

このあたりは、このメールでようやく分かりました。

結果

さきほどと同じ条件で投げてみました。なお、POST先は1台のみです。

real    35m25.989s
user    14m33.846s

と、半分までは行きませんが、結構早くなりました。4700行/秒、156qpsという感じです。

この時点で、disk容量は両方共1.4GBでした。つまり、ほぼ均等に分けられたことになります。

なお、shardが18個できました。

Query

select * from stress limit 1000;
real 0m3.746s
select max(int) from stress where time < '2013-12-12'
236400レコードreal 0m11.530s

なぜか全体的に遅くなっています。特に最初のはshardをまたがるわけではないし、queryを投げたサーバーとは別のサーバにshardがあるわけではないのですが。

shardについて

influxdb 0.5からは以下に述べられているようにデータが置かれます。

https://groups.google.com/forum/#!msg/influxdb/3jQQMXmXd6Q/cGcmFjM-f8YJ

つまり、

  • 入ってきた値のtimeを見て、一定時間(初期設定は7日)ごとにshardが分けられる。shardごとにleveldbが出きる
  • shardごとに担当サーバーが決まっている
  • replication factor分だけ、shardがcopyされる。つまり、shardの担当サーバーが増える
  • shardはsplitという値でさらに分割される
  • splitされたどちらに入るかは(database, seriesName)というhash値で決定される
  • split-randomという値を設定すると、randomに決定される(regexでの指定も可能?)

これから導き出されることというと、

  • 1つのqueryの速度は変わらない。それもそうで、1台にのみqueryがいっているから、結局leveldbに律速される
  • shardの大きさ(期間)も重要で、1shardに収まるqueryであれば速いが、shardをまたがるqueryになると遅くなる。
  • replication factorを増やすとcopyが増えることになるので、並列読み込み性能が上がる。ただしその分書き込みも増える
  • splitを設定すると、shard内でもさらに分散できるので、書き込み性能はあがる。ただし、分割されるので、おそらくそれをまたがるqueryは遅くなる

という感じでしょうか。ちゃんと確かめたわけではないので、間違いがあるかもしれません。

今回書き込みに関してはもう一台に割り当てられているshardの分はディスクへの書き込みが発生しなかったのでその分早くなったのではと思われます。

ただ、shardをまたいでないはずのqueryが遅くなったのは分かりませんね。そのあたりは他の人の検証を待ちます。

ということで、あんまりきちんとした検証ではありませんが、雰囲気でもということで。