Redis Cluster を構成する Godisを試してみた。

こんにちは k-jun です。今日は Golang 製の Redis Cluster なる Godis を試してみます。

https://github.com/HDT3213/godis

書き込みのパフォーマンスが通常の Redis と比べてどうなるのかも見ていきたいですね。 インストールは homebrew、go install など何も用意されていないので、ソースから落とします。

$ godis

   ______          ___
  / ____/___  ____/ (_)____
 / / __/ __ \/ __  / / ___/
/ /_/ / /_/ / /_/ / (__  )
\____/\____/\__,_/_/____/
[INFO][server.go:44] 2021/08/21 12:28:12 bind: 0.0.0.0:6399, start listening...

書いてあった通りに redis-cli との互換性も問題なさそうです。

$ redis-cli -p 6399
127.0.0.1:6399> set name k-jun
OK
127.0.0.1:6399> get name
"k-jun"

どの程度パフォーマンスが出るのかを、redis-benchmark を使用して調べてみます。

Summary:
  throughput summary: 86132.64 requests per second
  latency summary (msec):
          avg       min       p50       p95       p99       max
        0.434     0.072     0.343     0.743     0.791     2.471
Error from server: ERR unknown command 'spop'

あら、spop には対応していないんですね。では、項目を絞って get, set, lpush, rpush, lpop, rpop, sadd, hset だけでやってみます。

$ redis-benchmark -p 6399 -t get,set,lpush,rpush,lpop,rpop,sadd,hset | grep -e '======' -e 'summary'
ERROR: ERR unknown command 'config'
ERROR: failed to fetch CONFIG from 127.0.0.1:6399
WARN: could not fetch server CONFIG
====== SET ======
  throughput summary: 80645.16 requests per second
  latency summary (msec):
====== GET ======
  throughput summary: 87565.68 requests per second
  latency summary (msec):
====== LPUSH ======
  throughput summary: 94876.66 requests per second
  latency summary (msec):
====== RPUSH ======
  throughput summary: 93370.68 requests per second
  latency summary (msec):
====== LPOP ======
  throughput summary: 95238.10 requests per second
  latency summary (msec):
====== RPOP ======
  throughput summary: 93984.96 requests per second
  latency summary (msec):
====== SADD ======
  throughput summary: 93196.65 requests per second
  latency summary (msec):
====== HSET ======
  throughput summary: 92081.03 requests per second
  latency summary (msec):

比較対象として、普通の redis にもベンチマークを当ててみます。

$ redis-benchmark -t get,set,lpush,rpush,lpop,rpop,sadd,hset | grep -e '======' -e 'summary'
====== SET ======
  throughput summary: 101112.23 requests per second
  latency summary (msec):
====== GET ======
  throughput summary: 111111.12 requests per second
  latency summary (msec):
====== LPUSH ======
  throughput summary: 108459.87 requests per second
  latency summary (msec):
====== RPUSH ======
  throughput summary: 106723.59 requests per second
  latency summary (msec):
====== LPOP ======
  throughput summary: 111731.84 requests per second
  latency summary (msec):
====== RPOP ======
  throughput summary: 112612.61 requests per second
  latency summary (msec):
====== SADD ======
  throughput summary: 111358.58 requests per second
  latency summary (msec):
====== HSET ======
  throughput summary: 111982.08 requests per second
  latency summary (msec):

この時点では若干劣化する程度。問題はここから。Cluster として他の Node を追加した場合の性能も同じように見ていきます。

# node1.conf
peers localhost:7379,localhost:7389 // other node in cluster
self  localhost:6399 // self address
# node2.conf
peers localhost:6399,localhost:7389 // other node in cluster
self  localhost:7379 // self address
# node3.conf
peers localhost:7379,localhost:6399 // other node in cluster
self  localhost:7389 // self address

そもそも、正しく Cluster として動作しているのかも不安になってきたので 確認する。

$ CONFIG=/tmp/node3.conf godis

   ______          ___
  / ____/___  ____/ (_)____
 / / __/ __ \/ __  / / ___/
/ /_/ / /_/ / /_/ / (__  )
\____/\____/\__,_/_/____/
[INFO][server.go:44] 2021/08/21 12:47:33 bind: :0, start listening...
$ CONFIG=/tmp/node2.conf godis

   ______          ___
  / ____/___  ____/ (_)____
 / / __/ __ \/ __  / / ___/
/ /_/ / /_/ / /_/ / (__  )
\____/\____/\__,_/_/____/
[INFO][server.go:44] 2021/08/21 12:47:33 bind: :0, start listening...
$ CONFIG=/tmp/node1.conf godis

   ______          ___
  / ____/___  ____/ (_)____
 / / __/ __ \/ __  / / ___/
/ /_/ / /_/ / /_/ / (__  )
\____/\____/\__,_/_/____/
[INFO][server.go:44] 2021/08/21 12:47:33 bind: :0, start listening...

ひとまず大丈夫そう。node が1つ落ちても動作もしている。

$ redis-cli -p 6399
127.0.0.1:6399> set name k-jun
OK
127.0.0.1:6399> get name
"k-jun"
127.0.0.1:6399>

$ redis-cli -p 7379
127.0.0.1:7379> get name
"k-jun"
127.0.0.1:7379>

$ redis-cli -p 7389
127.0.0.1:7389> get name
"k-jun"
127.0.0.1:7389>

ベンチを当ててみる。

$ redis-benchmark -p 6399 -t get,set,lpush,rpush,lpop,rpop,sadd,hset | grep -e '======' -e 'summary'
ERROR: ERR unknown command 'config', or not supported in cluster mode
ERROR: failed to fetch CONFIG from 127.0.0.1:6399
WARN: could not fetch server CONFIG
====== SET ======
  throughput summary: 41946.31 requests per second
  latency summary (msec):
====== GET ======
  throughput summary: 43252.59 requests per second
  latency summary (msec):
====== LPUSH ======
  throughput summary: 86956.52 requests per second
  latency summary (msec):
====== RPUSH ======
  throughput summary: 76804.91 requests per second
  latency summary (msec):
====== LPOP ======
  throughput summary: 85324.23 requests per second
  latency summary (msec):
====== RPOP ======
  throughput summary: 79617.83 requests per second
  latency summary (msec):
====== SADD ======
  throughput summary: 86132.64 requests per second
  latency summary (msec):
====== HSET ======
  throughput summary: 40225.26 requests per second
  latency summary (msec):

半分くらいか... 結構落ちるなぁ... Redis が SPOF になっている場合には使ってみてもいいかもしれないが、やはり性能劣化は避けられないのか... まとめると。

性能 set get lpush rpush lpop rpop sadd hset
redis 1 101112.23 111111.12 108459.87 106723.59 111731.84 112612.61 111358.58 111982.08
godis 0.8351843437 80645.16 87565.68 94876.66 93370.68 95238.10 93984.96 93196.65 92081.03
godis cluster 0.6161080346 41946.31 43252.59 86956.52 76804.91 85324.23 79617.83 86132.64 40225.26

うーん.. 結構エグい。それでは今日はこのへんで。