-
redis:7.0.4-alpine3.16
$ docker run --rm -it -p 6379:6379 --name mem-redis redis:7.0.4-alpine3.16
-
dragonfly
$ docker run --rm -it -p 6380:6379 --name mem-dragon --ulimit memlock=-1 docker.dragonflydb.io/dragonflydb/dragonfly:v0.4.0
つまりほぼデフォルト設定ということ。
docker stats で数秒間隔で3回計測
$ docker stats --no-stream
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
f46762c52191 mem-dragon 6.53% 4.062MiB / 11.7GiB 0.03% 656B / 0B 0B / 0B 7
768780b69d7c mem-redis 0.05% 2.379MiB / 11.7GiB 0.02% 876B / 0B 0B / 0B 5
$ docker stats --no-stream
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
f46762c52191 mem-dragon 6.46% 4.062MiB / 11.7GiB 0.03% 726B / 0B 0B / 0B 7
768780b69d7c mem-redis 0.05% 2.379MiB / 11.7GiB 0.02% 946B / 0B 0B / 0B 5
$ docker stats --no-stream
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
f46762c52191 mem-dragon 6.52% 4.062MiB / 11.7GiB 0.03% 726B / 0B 0B / 0B 7
768780b69d7c mem-redis 0.06% 2.379MiB / 11.7GiB 0.02% 946B / 0B 0B / 0B 5
dragonflyのほうがCPU使用率が高く、使用メモリも多い
$ redis-cli -p 6379 info memory | grep human
used_memory_human:904.26K
used_memory_rss_human:6.48M
used_memory_peak_human:904.26K
total_system_memory_human:11.70G
used_memory_lua_human:31.00K
used_memory_vm_total_human:63.00K
used_memory_scripts_human:184B
maxmemory_human:0B
$ redis-cli -p 6380 info memory | grep human
used_memory_human:860.3KiB
used_memory_rss_human:9.98MiB
maxmemory_human:8.94GiB
dragonflyのほうが info
で読める項目がかなり少ない。
比較可能な項目は3つ。
used_memory_human
- サーバーが認識している、malloc等で割り当てたメモリ総量used_memory_rss_human
- OSから見たメモリ使用総量。仮想メモリを含むmaxmemory_human
-maxmemory
の設定値。比較する意味なし
なので容易に比較可能なのは前2項目 (ほかに比較できるものもあるがちゃんと見る意味はない)
まとめると起動時点では:
- コンテナを通して見るとdragonflyのほうがメモリ使用量が多く、CPU使用率が大きい
- サーバー自身が認識しているメモリ使用量はredisのほうが多い
- OSが認識しているメモリ使用量はdragonflyのほうが多い
推測ではあるが、dragonflyはマルチスレッドで動いてるため、 スレッド間で何らかの調停が必要でアイドル時でもCPUを必要とするし、 スレッドのローカルメモリーというmalloc外で確保され OS等が認識しているメモリが表出していると考えられる。
ベンチマークの流れは以下の通り:
-
redis-benchmark -t set
で大量のキーを作るランダムに10万キーを作成する。値は3バイト。
-
メモリ使用量を確認する
$ redis-benchmark -p 6379 -t set -r 100000 -n 1000000
====== SET ======
1000000 requests completed in 19.96 seconds
50 parallel clients
3 bytes payload
keep alive: 1
50.79% <= 1 milliseconds
97.71% <= 2 milliseconds
99.90% <= 3 milliseconds
99.96% <= 4 milliseconds
99.98% <= 5 milliseconds
100.00% <= 6 milliseconds
100.00% <= 6 milliseconds
50092.67 requests per second
$ redis-cli -p 6379 dbsize
(integer) 99994
$ docker stats --no-stream mem-redis
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
517aa55b283c mem-redis 0.05% 10.68MiB / 11.7GiB 0.09% 116MB / 71MB 0B / 3.06MB 5
$ redis-cli -p 6379 info memory | grep human
used_memory_human:8.77M
used_memory_rss_human:14.72M
used_memory_peak_human:9.82M
total_system_memory_human:11.70G
used_memory_lua_human:31.00K
used_memory_vm_total_human:63.00K
used_memory_scripts_human:184B
maxmemory_human:0B
$ redis-benchmark -p 6380 -t set -r 100000 -n 1000000
====== SET ======
1000000 requests completed in 20.71 seconds
50 parallel clients
3 bytes payload
keep alive: 1
47.37% <= 1 milliseconds
96.54% <= 2 milliseconds
99.82% <= 3 milliseconds
99.92% <= 4 milliseconds
99.96% <= 5 milliseconds
99.98% <= 6 milliseconds
99.99% <= 7 milliseconds
100.00% <= 8 milliseconds
100.00% <= 9 milliseconds
100.00% <= 10 milliseconds
100.00% <= 11 milliseconds
100.00% <= 11 milliseconds
48295.18 requests per second
$ redis-cli -p 6380 dbsize
(integer) 99998
$ docker stats --no-stream mem-dragon
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
f46762c52191 mem-dragon 6.45% 10.39MiB / 11.7GiB 0.09% 116MB / 71MB 0B / 0B 7
$ redis-cli -p 6380 info memory | grep human
used_memory_human:6.74MiB
used_memory_rss_human:16.61MiB
maxmemory_human:8.94GiB
-
純粋な set 速度は若干ではあるがDragonflyのほうが遅い
おおよそ4%ほど(5万req/secに対して4.8万req/sec) ただしどちらも同一PCで動かしているのでその分の考慮は必要かもしれない。
-
コンテナを通して見るとDragonflyのほうが若干メモリ使用量が少ない。
10万キーでおおよそ3%
-
malloc量はDragonflyが20%以上少ない
-
RSSベースでみるとDragonflyのほうが13%近く多い
確かにDragonflyのほうが使用メモリが少なくなってる気配がある。
しかしRSSベースの比較ではそうでもない。スレッド分だろうか?
件数をさらに多くしてみたほうが良いかも。
今の設定は10万件、100万回だけど、メモリ使用量だけみるならもっと絞って良さそう。
Redis (1-redis.log)
Size | Container | Malloc | RSS |
---|---|---|---|
100000 | 10.59M | 8.77M | 14.72M |
200000 | 18.61M | 16.62M | 22.66M |
300000 | 28.64M | 25.47M | 31.68M |
400000 | 35.57M | 32.32M | 39.68M |
500000 | 41.41M | 39.15M | 45.55M |
Dragonfly (2-dragonfly.log)
Size | Container | Malloc | RSS |
---|---|---|---|
100000 | 10.36M | 6.74M | 16.22M |
200000 | 16.80M | 13.27M | 22.60M |
300000 | 28.30M | 24.79M | 34.15M |
400000 | 29.80M | 26.31M | 35.74M |
500000 | 32.29M | 28.74M | 38.29M |
40万件を超えたあたりからDragonflyが有意に少なくなっている。