如何获取Redis哈希表的长度?

13
我在 Redis 中使用哈希表存储对象,我想从 Redis 的角度计算这些哈希表的长度。
对于字符串,您可以轻松使用“STRLEN”命令来完成此操作。
但是我在文档中没有找到适用于哈希数据类型的合适命令。 这似乎与列表或集合相同。
基本上,我发现的唯一解决方案是使用“HGETALL”获取整个哈希表,并在客户端上计算长度。
这是完全超出了预期的吗?
如果我错了,请不要犹豫向我解释原因或提供相关链接/帖子/SO问题。
编辑: HLEN不是解决方法,因为它“返回哈希表中包含的字段数”。
我想为 Redis 数据库的容量规划和活动监视计算此大小。

你能解释一下为什么你需要这个吗?是为了估计Redis中的内存使用情况吗?还是你需要实现一个特定的功能?有方法可以从Redis的角度找出散列的长度,但根据你的用例,它可能有用也可能没有用。 - Sripathi Krishnan
@Cybermaxs 你最终做了什么? - Abhijit Sarkar
5个回答

38

只需使用HLEN命令即可。

redis> HSET myhash field1 "Hello"
(integer) 1
redis> HSET myhash field2 "World"
(integer) 1
redis> HLEN myhash
(integer) 2

编辑: 问题已经澄清为OP想要主动监视哈希的磁盘大小。在这种情况下,我肯定会使用Lua脚本来计算服务器上哈希的大小,并将值返回给您。不要使用HGETALL如果您期望有大型哈希,因为您需要将整个哈希从服务器传输到客户端计算机,这将很快成为瓶颈。仅在Redis服务器上使用Lua进行此计算意味着您只需传输网络字节数的int,而不是可能是整个哈希的MB数据。


正如我之前所说,HLEN仅返回哈希表中字段的数量。 - Cybermaxs
2
@Cybermaxs-Betclic,你在帖子中从未提到过HLEN。哈希的长度是字段(键)的数量。如果不是这个,你指的是什么长度?在任何其他语言中,当你执行类似len(hash)的操作时,你期望得到的就是返回值。 - Eli
哦,这是真的。HLEN“返回存储在键中的哈希中包含的字段数”;而不是整个哈希的长度或大小,如果您更喜欢这样说。 - Cybermaxs
@Cybermaxs-Betclic 我觉得这里存在一个基本的误解。Redis在数据库中有指向特定数据结构的键。在你的情况下,Redis键指向你的哈希表(该哈希表由许多哈希键组成,这些哈希键指向值)。HLEN确实会给出哈希表的长度(哈希表中键的数量)。对我来说,这仍然听起来像是你所要求的内容。如果你真正想要的是哈希表在磁盘上的大小,我已经在上面编辑了我的答案。 - Eli

10

如果您想了解键的长度作为磁盘空间,可以使用DEBUG OBJECT,因为它会返回每个键的多个信息项。

redis 127.0.0.1:50001> hset myhash field1 'hello'
(integer) 1
redis 127.0.0.1:50001> hset myhash field2 'world'
(integer) 1
redis 127.0.0.1:50001> DEBUG OBJECT myhash
Value at:0x7fb8de4ad590 refcount:1 encoding:zipmap serializedlength:31 lru:696871 lru_seconds_idle:0

希望它有所帮助


1
那个对象占用了多少字节?我不明白“序列化长度”31是什么意思? - christopher clark
你实际上没有回答楼主的问题。多少字节? - Abhijit Sarkar

5

根据哈希值长度的用途不同,操作也会有所不同。

如果您想要通过长度进行一些诊断或监控,比如查找内存消耗,我建议您使用离线工具(例如redis-rdb-tools,免责声明:我是这个工具的作者)。CSV转储文件将为您提供有关每个键的统计信息--包括总大小、总内存消耗等。

但是,如果您想使用大小来实现某些应用程序功能,则没有现成的解决方案。HGETALL加上客户端长度计算是可行的方法。您可以编写一个Lua脚本,以便在Redis服务器本身上进行长度计算,可能能够实现优化。


Downvoter - 你能否请留下一条评论,解释一下为什么要给我点踩?我不介意被点踩,但是很想知道我错过了什么或者说错了什么 :) - Sripathi Krishnan
我没有给你点踩,但是因为你的好工具redis-rdb-tools,我给你点了赞。 - Cybermaxs
@SripathiKrishnan 我给你的回答点了踩,因为“如何获取Redis哈希长度”的明显答案是HLEN,但显然OP在他的问题中意味着除哈希的“长度”之外的其他内容,所以你的回答实际上很好。我想撤销这个踩,但是SO不会让我这样做,除非你以某种方式编辑你的回答。如果你这样做了,我很乐意把它移除:)。 - Eli
1
@Eli 没问题,我完全不介意。感谢留下评论,这是有人花功夫解释“踩票”的第一次! - Sripathi Krishnan

1
使用 MEMORY USAGE 命令。
127.0.0.1:6379> hmset user:1000 username antirez birthyear 1977 verified 1 
OK
127.0.0.1:6379> memory usage user:1000 
(integer) 110

由于您正在用于容量规划,此命令的优点在于包括 Redis 在数据本身大小之上添加的任何管理开销。

127.0.0.1:6379> SET "" ""
OK
127.0.0.1:6379> MEMORY USAGE ""
(integer) 46

0

看起来你最好的选择是在遇到哈希时使用HSCAN来获取字段,并对每个字段使用HSTRLEN进行求和。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接