Redis命令之HGetAll性能问题解决方案

Redis命令之HGetAll性能问题解决方案

最近工作中,系统压测遇到一个性能瓶颈问题,通过最终排查,发现应用接口中使用了大量的Hgetall命令从Redis中查询数据信息,导致Redis单实例OPS达到秒钟7W次,Redis服务器CPU使用率达到上限,遇到性能问题。


HGETALL key

起始版本:2.0.0

时间复杂度:O(N) where N is the size of the hash.

返回 key 指定的哈希集中所有的字段和值。返回值中,每个字段名的下一个是它的值,所以返回值的长度是哈希集大小的两倍

返回值

array-reply:哈希集中字段和值的列表。当 key 指定的哈希集不存在时返回空列表。

例子

redis> HSET myhash field1 "Hello"(integer) 1redis> HSET myhash field2 "World"(integer) 1redis> HGETALL myhash1) "field1"2) "Hello"3) "field2"4) "World"redis>





















通过官方文档,可以了解到命令HgetAll的时间复杂度为O(n)。这意味着Hash的field越多,当使用HgetAll获取全量数

据时,性能越差,该命令的性能与field字段的数量成正比。

遇到问题后,上网查询资料,解决方案大致两种:

1) 借助MemCached

2) 新增一个field字段,将原Redis key对应的所有数据信息全部存储在该filed中,然后使用Hmget命令代替HgetAll

但是以上两种方案,均存在各种弊端,并没有从根本上解决问题。找公司其他部门技术大拿交流,最终讨论出以下方案解决问题:

通过使用Redis dump命令获取到Redis序列化后的值,获取到的是字节数组。在应用中将该字节数组按照Redis协议自行解析成需要的HashMap数据。

方案优点:

1) dump命令的时间复杂度为O(1),性能优于HgetAll

2) 将字节数组的解析由Redis服务器转移到了应用服务器,减轻了Redis 服务器CPU的运算压力

3) 充分利用了应用服务器的CPU,并且应用服务器方便扩容。


DUMP key

起始版本:2.6.0

时间复杂度:O(1) to access the key and additional O(N*M) to serialized it, where N is the number of Redis objects composing the value and M their average size. For small string values the time complexity is thus O(1)+O(1*M) where M is small, so simply O(1).

序列化给定 key ,并返回被序列化的值,使用 RESTORE 命令可以将这个值反序列化为 Redis 键。

序列化生成的值有以下几个特点:

  • 它带有 64 位的校验和,用于检测错误,RESTORE 在进行反序列化之前会先检查校验和。
  • 值的编码格式和 RDB 文件保持一致。
  • RDB 版本会被编码在序列化值当中,如果因为 Redis 的版本不同造成 RDB 格式不兼容,那么 Redis 会拒绝对这个值进行反序列化操作

序列化的值不包括任何生存时间信息。

返回值

如果 key 不存在,那么返回 nil。</br> 否则,返回序列化之后的值。

例子

redis> SET mykey 10OKredis> DUMP mykey"u0000xC0u0006u0000xF8r?xC5xFBxFB_("redis>

免责声明:本网信息来自于互联网,目的在于传递更多信息,并不代表本网赞同其观点。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,并请自行核实相关内容。本站不承担此类作品侵权行为的直接责任及连带责任。如若本网有任何内容侵犯您的权益,请及时联系我们,本站将会在24小时内处理完毕。
相关文章
返回顶部