マルチスレッド対応が入ったRedis6の確認

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

簡単に確認してみます。

最初は2台使ってネットワーク越しに確認していたのですが、ネットワーク帯域の上限に達してしまうのでClientとServerは同じサーバで確認しました。なので、ClientとServerの負荷が一緒くたになっていますが、CPUコア数が十分に余っている環境で絶対値ではなく相対的な比較をする事で目を瞑ることにします。負荷試験ではないので。

(仕事でこんな適当な事したら駄目ですよ..!)
実際は自分のワークロードに合わせて検証、MetricsをSnapshotではなくHistogramで見て、ボトルネックや安定動作ラインを探る必要があります。

実は、Redis2~6、ardbの比較もしたのですが、ネットワーク越しでやったためにネットワークがサチってしまったのでお蔵入りにしました。

前提

  • Instance: c5.9xlarge
    • CPUコア数は36です
  • ClientとServerが同居
  • Clientは公式のRedisBenchmarkを利用
    • --threads, -c, -nのパラメータの変更のみでテストの内容はデフォルト
    • そのため、ZSetやLuaの検証は入っていない
    • --threadsはバージョン6から導入されたオプション
  • Serverのパラメータは以下を変更
    • io-threads
    • io-threads-do-reads
  • Kernelパラメータは最低限のネットワーク、メモリ周りを設定。ulimitのopen filesも増やす。

Redisのビルド

Version 6.0.1を使いました。ビルドオプションは以下の通り。

make MALLOC=jemalloc V=1

MetricsはNetDataで取得

https://www.netdata.cloud/

bash <(curl -Ss https://my-netdata.io/kickstart.sh)

設定はglobalセクションのmemory modesaveからramに変更。プロセスを再起動するたびにMetricsがリセットされるので、計測が楽になる。(参考)

MetricsはAPIで取得。
memory modeをramにする事でmetricsが都度リセットできるので、計測期間を気にしないで全期間を取得すれば良い事になる。

curl -s "http://localhost:19999/api/v1/data?format=tsv&chart=system.cpu" > cpu-all.tsv

redis-benchmark (client)

各列の意味は次の通りです。

  • 1: デフォルト設定。つまり io-threadsは無効です。
  • 2-rw: io-threads=2, io-threads-do-reads=yes
  • 2-w: io-threads=2, io-threads-do-reads=no
  • 以下略

ケースその1

redis-benchmark -h 127.0.0.1 -c 1000 -n 1000000 --threads 10

ちゃんとスループットが上がっていますね。

ケースその2

redis-benchmark -h 127.0.0.1 -c 1000 -n 1000000 --threads 50

途中で性能が落ちてきているのは、Instanceの処理限界が来たからです。CPUのグラフしか取得していなかったのでアレですが、24-wの時はLoadAverageが40くらいになっていました。

ケースその3

redis-benchmark -h 127.0.0.1 -c 1000 -n 1000000 --threads 100

その1で十分なので、おまけ。

io-threads, io-threads-do-reads no の説明

io-threads

Redis is mostly single threaded, however there are certain threaded operations such as UNLINK, slow I/O accesses and other things that are performed on side threads.


Now it is also possible to handle Redis clients socket reads and writes in different I/O threads. Since especially writing is so slow, normally Redis users use pipelining in order to speedup the Redis performances per core, and spawn multiple instances in order to scale more. Using I/O threads it is possible to easily speedup two times Redis without resorting to pipelining nor sharding of the instance.


By default threading is disabled, we suggest enabling it only in machines that have at least 4 or more cores, leaving at least one spare core.

Using more than 8 threads is unlikely to help much. We also recommend using threaded I/O only if you actually have performance problems, with Redis instances being able to use a quite big percentage of CPU time, otherwise there is no point in using this feature.


So for instance if you have a four cores boxes, try to use 2 or 3 I/O threads, if you have a 8 cores, try to use 6 threads. In order to enable I/O threads use the following configuration directive:

http://download.redis.io/redis-stable/redis.conf

デフォルトでスレッド化は無効で、少なくとも4コア以上のサーバで動かす時に有効化するのが良く、1コアは残しておくように。つまり4コアの場合は設定を2か3くらいにするのが良く、8コアの場合は6あたりを設定するのが良い。なお、8以上を設定するのはあまり意味がない。

io-threads-do-reads no

Setting io-threads to 1 will just use the main thread as usually.

When I/O threads are enabled, we only use threads for writes, that is to thread the write(2) syscall and transfer the client buffers to the socket. However it is also possible to enable threading of reads and protocol parsing using the following configuration directive, by setting it to yes:

http://download.redis.io/redis-stable/redis.conf

io-threadsを1に設定すると、通常通りメインスレッドを使用する。
io-threadsが有効な場合、書き込み(write(2) syscall)にのみスレッドを使用する。
この設定がyesの場合は、読み込みとプロトコルのパースにもスレッドを使用する。