首页 > 解决方案 > HMGET 与字段数和读取性能之间的相关性

问题描述

对 HMGET 性能有一些疑问。

您能解释一下哈希中的字段数如何影响读取性能吗?

示例 1. 20000 个请求。HMGET 有 4 个字段。管道中的命令。哈希包含 760 个字段在测试机器上大约需要 1500 毫秒。

示例 2. 20000 个请求。HMGET 有 4 个字段。管道中的命令。哈希包含 30 个字段在测试机器上大约需要 300 毫秒。

标签: performanceredis

解决方案


在这两种情况下它都应该是 O(1) - 与散列中的字段数无关。所以 20 倍的按键数量需要 5 倍的时间听起来有点过分。

我试图复制并获得非常一致的性能。这是我所做的:

创建了三个散列,每个散列有 10、1000、100000 个字段:

> EVAL "for i=1,10 do redis.call('HSET', KEYS[1], i, i) end" 1 Test1HMGET
(nil)
> EVAL "for i=1,1000 do redis.call('HSET', KEYS[1], i, i) end" 1 Test2HMGET
(nil)
> EVAL "for i=1,100000 do redis.call('HSET', KEYS[1], i, i) end" 1 Test3HMGET
(nil)
> HLEN Test1HMGET
(integer) 10
> HLEN Test2HMGET
(integer) 1000
> HLEN Test3HMGET
(integer) 100000

然后运行redis-benchmark测试HMGET:

$ redis-benchmark -n 200000 -c 1 -q HMGET Test1HMGET 4 6 7 9
HMGET Test1HMGET 4 6 7 9: 8841.73 requests per second
$ redis-benchmark -n 200000 -c 1 -q HMGET Test2HMGET 4 6 7 9
HMGET Test2HMGET 4 6 7 9: 8788.89 requests per second
$ redis-benchmark -n 200000 -c 1 -q HMGET Test3HMGET 4 6 7 9
HMGET Test3HMGET 4 6 7 9: 8863.68 requests per second
$ redis-benchmark -n 200000 -c 1 -q HMGET Test3HMGET 45 667 567 56789
HMGET Test3HMGET 45 667 567 56789: 8819.51 requests per second

如图所示,无论散列长度如何,它始终获得约 8800 rps。

其他命令,如 HGETALL,确实显示出下降。

$ redis-benchmark -n 20000 -c 1 -q HGETALL Test1HMGET
HGETALL Test1HMGET: 7840.06 requests per second
$ redis-benchmark -n 20000 -c 1 -q HGETALL Test2HMGET
HGETALL Test2HMGET: 600.08 requests per second

在您的测试中必须有其他东西驱动您观察到的差异,如果您使用不同的字段,可能是有效载荷差异。

更新:正如 OP 所指出的,一旦你接近hash-max-ziplist-entries. 请参阅Antirez 文章这篇文章。由于压缩,您的平均读取性能下降。这是 CPU / 内存的权衡。

在我的机器上,我有max-ziplist-entries= 512。在密钥空间结束时,性能要慢 2.3 倍。一旦我们超过压缩优化阈值(514 个字段),它在整个键空间中保持不变,但内存使用量增加了 6.6 倍。


推荐阅读