Redis大key引发的思考

生活本是不进则退,不管这一步走的多多少少,至少要迈出去

线上业务依赖redis做一些数据存储,由于年底的业务量突增,导致redis中的一个key的存储突增,带来的大家口中所说的redis大key问题。

Redis大key带来的问题

命令执行: redis是单线程模型,所以对于一条客户端发起的命令,如果服务器端执行的时间过长,那么必然会导致同一redis slot上其他命令的阻塞。如果是不同的业务共用了同一个redis集群(必然共用同一slot),一个业务的大key问题就会有可能导致其他业务的不可用。

数据存储: 因为大key的问题,导致slot分片数据存储分配不均匀,会导致集群就算有较大的剩余容量,仍然会出现响应慢的情况

为什么redis大key就会导致上边的问题?

以上我只明白了redis大key会给线上服务带来什么样的问题。
1、但什么样的操作导致redis在处理数据的时候那么慢?
2、为什么一个key对应的value数据过大,操作起来就很慢,而redis却能支持上千万的key存储而又不慢呢?

那么针对以上问题,我了解了一下redis底层的数据模型:


redis存储结构

上图可以看到,redis底层db中存放的键空间其实就是一个dict字典的存储,字典的键是一个string类型的key,value则是不同redisObject。

而一般容易发生大key问题的操作,主要是在对list,hash等数据结构进行批量操作的时候。

O(1)操作:对于hget,hmget这种操作,对key进行hash再对dict的长度取模即可获取到对应元素的位置,所以时间复杂度为O(1);
而取到对应的元素之后,如果元素也是dict的话,我们再进行hash取模,获取到对应到field,时间复杂度仍然是O(1);
所以对于单元素的插入,查询等操作的时间复杂度都是O(1);

O(n)操作:但是对于hgetall,hdel,zrange等等很多,需要查询到所有数据的操作,时间复杂度都是O(n),

总结:

那么回到最开始的问题,
问题1在上文中已经有了答案,问题2的答案也很明显,因为操作redis的key其实就是在操作键空间的dict,一般单key的操作时间复杂度都是O(1),所以会比较快;如果也是涉及到查询所有的key,时间复杂度同样是O(n)

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 转载:可能是目前最详细的Redis内存模型及应用解读 Redis是目前最火爆的内存数据库之一,通过在内存中读写数据...
    jwnba24阅读 635评论 0 4
  • 前言 Redis是目前最火爆的内存数据库之一,通过在内存中读写数据,大大提高了读写速度,可以说Redis是实现网站...
    小陈阿飞阅读 812评论 0 1
  • 1林欢语刚在地铁口站定不久,一辆黑色轿车便精准地停在她身边。 车窗慢慢摇下,露出的是一张干净好看的脸:“是林小姐吧...
    枫阳阅读 252评论 1 0
  • 学名:Leucanthemum vulgare Lam。 多年生草本,高15-80厘米。 茎直立,通常不分枝,被绒...
    植物分类图像库阅读 1,203评论 0 7
  • 笔者:杀死那朵花 右=玮琪,左=沙烨,0=旁白 #1 玮琪:请问您是我在博客上看到的那个灵异法师吗? 沙烨:我是,...
    苏闲花阅读 2,731评论 1 6