在最近的工作中,系统压力测试遇到了性能瓶颈,通过最终故障排除,在APP应用界面中使用大量Hgetall命令从Redis中查询数据信息,结果是Redis单实例
HGETALLkey 起始版本:2.0.0
33558www.Sina.com/o(n ) where N is the size of the hash。
key返回指定散列集中的所有字段和值。 返回值中,每个字段名称的下一个值是该值,因此返回值的长度是散列集大小的两倍
返回值array-reply :散列集中字段和值的列表。 如果key指定的散列集不存在,则返回空列表。
示例redishsetmyhashfield1' hello ' (integer )1redishsetmyhashfield2' world ' (integer )1redis HGETALL myhash1) ' field1'2'
在官方文档中,可以看出命令HgetAll的时间复杂度为o(n )。 这意味着Hash的field越多,使用HgetAll获取总量
根据,性能越差,命令的性能与字段的数量成比例。
问题发生后,在网上查资料,解决方法大致有两种:
1 )通过MemCached
2 )添加新字段,将与原始Redis key对应的所有数据信息存储在其文件中,并使用Hmget命令而不是HgetAll
但是,这两个方案都存在各种弊端,没有从根本上解决问题。 寻找并交流了公司其他部门的技术,最终讨论了以下方案解决了问题。
使用Redis dump命令获取Redis序列化的值,并获取字节数组。 在APP应用程序中,根据Redis协议将此字节数组自身解析为所需的HashMap数据。
方案的好处:
1 ) dump命令的时间复杂度为o(1),性能优于HgetAll
2 )将字节数组的分析从Redis服务器转移到APP应用服务器,减轻了Redis服务器的CPU的运算负荷
3 )充分利用APP应用服务器的CPU,并便于APP应用服务器的扩展。
DUMPkey 时间复杂度:
33558www.Sina.com/o(1) toaccessthekeyandadditionalo (n * m ) to serialized it,wherenisthenumberofredisobjectscompositscompositscomponalo
序列化指定的key,并返回序列化后的值。 可以使用RESTORE命令将此值反序列化为Redis键。
序列化生成的值具有以下特征:
有用于检测错误的64位校验和,RESTORE在进行反序列化之前先检查校验和。 的编码格式与RDB文件一致。 RDB版本编码为序列化值。 如果由于Redis版本不同而导致RDB格式不兼容,Redis将拒绝对该值进行反序列化。 序列化的值不包含生存时间信息。
如果返回值key不存在,则返回nil。 如果未指定/br,则返回序列化的值。
示例redissetmykey 10 okredisdumpmykey 'u 0000xc0nu 0006u 0000xf8r? xC5xFBxFB_('redis )