Redis性能优化
这篇文章来总结一下常见的性能优化策略,这些情况也是影响 Redis 性能的关键因素,使用 Redis 的时候应该格外注意。
批量传输
Pipeline命令可以实现批量传输,批量传输可以减少网络传输时间,但是注意,在集群模式下,批量传输由于哈希槽不在同一个节点也可能经过多次网络传输
Key集中过期
大量key集中过期会导致内存得不到及时释放,内存占用虚高
- 开启lazy free机制,启动后台线程异步扫描删除机制
- 过期时间尽量随机,避免集中过期
大Key问题
大key问题是一个非常经典的问题,是指key对应的value占用内存过大,带来的问题很多:
- 服务端请求处理慢
- 网络传输时间长
- 客户端响应慢,用户体验差
那如何去排查定位这些大key呢?
- RDB快照分析工具,可以借助这些工具定期分析RDB文件,提前定位大key
- SCAN命令,SCAN命令属于游标扫描方式,每次扫描部分数据,分批返回,非常适合线上环境,但是一致性和实时性会差一些
线上环境禁止使用KEYS命令,会返回全量数据,命令延迟很大
解决大key的根本之道在于不要存储大key,有以下方案:
- 将一个大key分割成多个小key,查询时,由客户端负责查询拼接这些分散的key
- value压缩存储
- 如果是删除操作,可以启用异步删除机制
热Key问题
与大Key相似的还有一个热Key问题,大量请求访问热key所在机器导致机器宕机或者热key不在缓存,发生缓存击穿
解决热key的前提是发现热key:
- 客户端或者代理层上报:代理层对访问进行收集并上报,但是并非所有redis缓存架构都有代理
- 抓包分析上报:Redis基于TCP和RESP协议进行网络通信,可以抓包对RESP协议进行解析,无侵入,但开发复杂度比较高
那怎么解决热key问题呢?
- 多级缓存,对于只读数据或者可以容忍一定程度不一致的数据,采用多级缓存,在本地缓存一个副本
- 集群模式,数据分散存储
- 读写分离,从节点支持读并发
慢查询问题
Redis 提供了一个内置的慢查询日志 (Slow Log) 功能,专门用来记录执行时间超过指定阈值的命令,类似于MySQL的慢查询日志
在 redis.conf 文件中,我们可以使用 slowlog-log-slower-than 参数设置耗时命令的阈值,并使用 slowlog-max-len 参数设置耗时命令的最大记录条数。当 Redis 服务器检测到执行时间超过 slowlog-log-slower-than 阈值的命令时,就会将该命令记录在慢查询日志(slow log)中,这点和 MySQL 记录慢查询语句类似。当慢查询日志超过设定的最大记录条数之后,Redis 会把最早的执行命令依次舍弃。
缓存三件套
缓存穿透
key对应的数据在数据源并不存在,每次请求都会打到后端数据库,从而造成服务宕机,常见于构造不合理的请求进行攻击
- 白名单IP,过滤掉非法用户请求
- 布隆过滤器,预先判断数据是否在缓存或数据库中,有一定的误判率
- 缓存无效key,如果造成缓存穿透的大量请求是同一个或少量的key,可以缓存无效key到缓存中
缓存击穿
针对热点key不在缓存中的场景(过期),若大量请求落到后端数据库,会导致宕机
- 对于静态热点数据,比如秒杀活动一般都有持续时间,可以预先设置合理的过期时间
- 对于只读或可以容忍一定程度数据不一致的数据,采用多级缓存在本地缓存副本
- 缓存击穿不可避免,需要进行兜底,避免大量请求落到数据库,缓存数据没命中去数据库加锁请求时,加锁访问,保证只有一个线程请求数据库
缓存雪崩
大量缓存key集中在某一个时间段失效,对数据库造成严重威胁
- 过期时间尽量设置的随机,避免集中过期
- 逻辑删除,设置过期标记和过期时间,达到过期时间后,并不执行真正的删除,只是在逻辑上删除,这样客户端正常返回,后端异步地从数据库重新加载这个数据
- 多级缓存,本地缓存+分布式缓存策略

浙公网安备 33010602011771号