Redis大Key导致性能下降及处理

1.什么是大key

Redis是一个key,value数据库。大key即Key存储的value非常大。当value为哈希表、集合、有序集或链表时指存储的元素过多(上万)。当value为字符串时一般指单个字符串超过1M。也包括Key数量极多的情况,例如key数量达到千万上亿的规模。

2.大key导致性能下降的原因

大key导致性能下降redis的结构相关,首先redis是一个key,value数据库,其次redis使用了单线程模型来处理任务。

2.1 redis的key、value存储结构

redis是一个key,value数据库。内部通过dict数据结构保存key, value。如下图所示,key也是会占用空间。因此大量的key也会造成空间大量消耗。

在这里插入图片描述

2.2 redis单线程模型

Redis通过socket与客户端进行连接,并将服务器对socket的操作抽象为文件事件。服务端与客户端的通信会产生文件事件。

redis通过单线程,并通过I/O多路复用来处理来自客户端的多个连接请求,当产生连接后,将socket放入队列,并通过事件分派器来选择相应的处理程序。服务端通过监听这些事件,并完成相应的处理。

Redis基于Reactor模型开发了网络事件处理器,并称之为文件事件处理器文件事件处理器使用I/O多路复用来同时监听多个套接字,并根据不同的套接字所执行的任务选择相应的事件处理器。被监听的套接字准备好执行连接应答(accept)、读取(read)、写入(write)、关闭(close)等操作,与操作相关的文件事件就会产生,这是文件事件处理器就会调用套接字之前关联好的事件处理器来处理这些事件。

I/O多路复用监听多个套接字,并向文件事件分派器分派产生事件的套接字。如果有多个文件事件,I/O多路复用程序会将所有产生事件的套接字放到一个队列里,并通过有序、同步、一次一个套接字的方式向文件事件分派器传送套接字。当上一个套接字的事件被处理完毕后,I/O多路复用才会向文件分派器传送下一个套接字。文件事件分派器接受到I/O多路复用程序分派的套接字后,根据套接字类型选择相应的事件处理器。服务器根据套接字类型的不同,关联不同的事件处理器,即发生某事件后,该执行哪些操作。

在这里插入图片描述

3 大key的几种处理方式

通过2.1与2.2可知,处理大key耗时过多,会导致其它请求响应时间变长以及空间消耗过大。而大key的几种场景及处理方式可以分为如下几种。

3.1 哈希、集合、有序集合、链表中元素数量过多

如果单个集合中元素过多,那么我们将其拆分成多个小集合,然后再通过路由算法找到具体的子集即可。以哈希表为例,将大哈希表拆分为5个小哈希表。那么拆分后,先计算key的哈希值,利用hash(key)%5得到key到底落在哪个哈希表上即可。同理集合,有序集合,链表的处理方式也是一样。但如果某些场景下拆分后,要保证按照元素存储顺序获取,就需要附加一些额外属性来实现。但总体思路就是拆分,但实际操作还要考虑具体的业务场景。

3.2 存储的key过多

key也是会占据空间。如果存储一个用户信息通过string去存结构如下:

user.name = michael;
user.age=19
user.id=111

由于存储的信息都属于一个用户。因此为了减少前缀占用的空间可以通过哈希表存储。

key=111
value= hashMap
Key:name,value michael
Key:age,value 19

修改后,不再重复存储key中公共前缀,降低空间浪费。因此这种处理方法依然是拆分,减少公共数据,降低存储空间浪费。当然最终的使用和实际的业务场景相关。

3.3 字符串类型单个key存储的value过大

思路依然是拆分,然后通过批量获取命令获取。value过大进行拆分其目的是降低单次操作的对服务端带来压力,避免value过大对IO产生的影响。

3.4.bitmap/布隆过滤器过大时的处理

bitmap/布隆过滤器处理思路依然是拆分。一个大的bitmap拆分后需要注意,利用多个hash函数计算key的哈希值后,最终key应该都落在一个bitmap上。如果落在拆分后的多个bitmap上,获取一个key的值将会产生多次查询,那么将大大降低查询的效率。

在这里插入图片描述

要保证多个hash函数计算后路由到同一个节点,那么才能提高查询效率。否则会向上图所示,拆分后要查询多个节点才能拿到结果。拆分后bitmap虽然变小,当作为布隆过滤器使用时,其误判概率并不会随之增大。因为误判是概率是与哈希函数个数,集合元素数量及bitmap大小相关。

4 总结

本文主要介绍了大key产生的影响及其原因,并介绍了处理方式。就是通过拆分路由的形式进行改造。这样避免大key对redis性能造成影响。

5 参考资料

[1]. redis设计与实现第二版 12.1
[2]. redis单线程模型,https://github.com/doocs/advanced-java/blob/master/docs/high-concurrency/redis-single-thread-model.md

  • 5
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值