redis最佳实践

原则:redis希望存储的是热点数据,尽量可以在一天内访问到。

最佳实践

选择合适的数据结构

redis有String、Hash、Set、SortedSet、List等结构,主要依据业务需要进行选择
string:几乎所有数据都可以用string存储,但是最好适用于value较小、结构简单的数据,但是对于特殊结构如list/set这种,某种情况下可以节省存储空间和提高存取效率。(特点,可以有默认的过期时间)
list:有序列表,可以在头尾进行插入,插入效率高O(1),如果往中间插效率就很低。使用场景如博客系统可以为每篇文章设置一个list,使用lrange进行分页。
set:无序集合,可实现去重,使用场景如记录访问ip,可以实现天然去重。
SortedSet(ZSet):跳表,增删数据的复杂度都是O(logn),每个成员都有对应的分数用于排序,访问内部成员会很高效,使用场景如大型游戏积分榜,可以用zincrby增加用户分数,用zrange来获取top10,用zrange和zrank来获取用户的排名信息和附近的排名用户。
Hash:同hashmap,需要注意的是其编码有几种类型,压缩编码占据空间小但获取效率低容易导致pending,所以可以在设置时指定编码,对于对象,如果只更新部分字段就显得更加灵活而不需要像字符串一样维护整个json。
HyperLogLog:用于基数统计,如网站UV.在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定的、并且是很小的。可以参考这篇文章:
https://www.cnblogs.com/exceptioneye/p/7081896.html

杜绝大Value及热点key

String类型超过1Mb,集合的元素超过1w,就需要考虑拆分。
热点key容易导致cpu及网络高负载,需要业务上有相应的降级。

由于redis为单线程,针对大key的耗时一高就容易导致整个集群出现问题,
1.拆分大value的方法:
i:需要整存整取
将对象拆成几个key value,使用multiGet获取值来分拆单次操作的压力,将压力分摊到多个redis实例中,这种比较常见。
ii:需要部分存取
还是对其拆分为几个key value,或者使用hash进行存储分拆,每个filed去代表属性。

2.集合中元素过多(超过1w)
同样是需要进行拆分来分散单次操作的压力,比如固定桶数量,设置n个hash桶,先进行取余确定分到哪个hash桶,再去真正的hash桶内执行hash操作(相当于为key拆分编号)
对于list的pop操作如果需要按照时间,就可以在设置key的时候按照时间进行命名分拆。

单集群Key个数 < 1亿

key的数量过多(超过一亿的情况下),首先key的名字就会占据不小的空间(每个key都是有前缀的),其次服务端需要建立slot与key的关联关系,这些指针占用也规模较大。

1.对于key本身具有关联性的情况,可以选择hash结构存储。
2.key本身没有相关性,就根据数量和规模进行分桶,然后再使用hash结构存储。

尽量主动更新缓存

可以通过如dts数据订阅的方式对缓存进行更新,而不是等待使用者查询被动更新缓存,这样可能给db带来较大压力

设置合理的过期时间

过期时间尽量短,避免内存占用,同时也要防止同一时间大量内存过期(可以设置随机延时)

使用multiGet或者pipeline

原理是可以节省网络io的时间,pipeline(流水线)可以支持更多的命令,but任何事物不是完美的,使用pipeline redis需要缓存每一个命令的结果,最后一起返回,所以命令越多占用内存越大。
原生的redis-cluster 模式不支持集群pipeline命令。可以通过二开,在客户端通过key来分发pipeline命令来实现并发操作

避免复杂操作

批量操作针对的key个数不能过多,尤其避免对集合有getall这类复杂度为O(n)的操作(底层是通过迭代实现的)

踩坑:
项目里放了一个10w个key的set,已经可以被称为大value了,然后每次请求都会把这10w个数据拿回来,导致qps高的时候服务端阻塞。
redis解决方案:使用string类型拆分然后muliget(对redis的set类型并无强需求)/仍然使用set进行拆分,或者临时调大从副本数量(增加可以响应客户端请求的实例)
或者使用scan命令进行分页查询来减小每次查询的压力。

但其实这个根本用不着使用redis,数据比较固定,最后放在了本地缓存,每次启动项目进行预加载,这充分说明了技术选型的重要性。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值