Redis相关的那些事(一)

背景

目前工作所负责的工作主要是投放业务,属于读高并发场景,记录一下之前碰到的redis相关的问题。

热点大值Key&缓存击穿问题

问题表现

在某次流量峰值过程中,redis的CPU突然飙升,从监控看起来就是CPU飙升到一定程度,内存突然掉0,然后命中率掉0(实际上是主节点被打挂了,触发了主备切换)。流量和系统调用链路逻辑跟之前并无区别。

原因分析

先看一下计划发布流程和投放端读取计划配置的逻辑:

具体逻辑:

  1. 配置端会生成一个全局的索引index_key,来存放坑位和所关联投放计划的关系(注意这里是一个大值key);
  2. 配置端每次更新完全局索引后,会在redis刷新一个全局的时间戳time_key,记录索引的最后更新时间;
  3. 投放端请求进来后,获取redis时间戳缓存(这里是一个热点key),会判断本地索引时间戳缓存是否和redis的时间戳一致,若时间戳不一致,会刷新本地全局index缓存,刷新成功后会刷新本地时间戳缓存;

好处:

  1. 只要时间戳更新,投放端就会获取最新的索引版本,能保证索引发布后,所有对于所有机器来说就马上生效;

弊端

  1. 时间戳redis值本来就是个热点key,投放端每次请求都会打到redis;
  2. 全局索引会是大值key,当QPS很高的时候,每次发布新的索引之后,所有机器会同时触发刷新,若集群的机器数量很多的时候,瞬间会打到同一个redis分片

上面所说的问题就是由于在流量峰值期间,有运营发布了新计划,导致全局索引刷新,瞬间1000+qps打到同一个redis分片获取全局索引,导致分片被打崩。

解决办法:

  1. 最简单的解决办法就是把全局索引复制多个备份,key值加入后缀,使value分布到redis集群的每个分片中。比如复制20个备份,index_key_{random},投放端机器随机访问0-20后缀的全局索引分片,解决热点问题;
    弊端:需要保持多个备份的一致性,可能会存在一致性问题;
  2. 把全局索引根据业务划分为更小的颗粒度。比如在这个场景,可以把全局索引改为资源位-计划的索引,减少value的值大小,而且根据资源位进行索引后,value的分布也自然就打散了;
  3. 使用压缩工具,减少value的值。因为存放的value为json格式,json格式其实是有很大的压缩空间,使用压缩工具能够大大减少value的值;
  4. 增加时间戳本地缓存过期时间,使更新本地索引的请求不会同时触发,通过减少并发量解决问题。
    弊端:会导致计划发布之后,投放端会有延迟更新,因为本地缓存时间的存在,所以并不会马上去校验索引是否更新。

总结

总结一下,解决热点大值key基本就几个思路:

  1. 通过预热的方式,把热点key打散,把压力分散到整个集群;
  2. 通过减小value的size,压缩、修改缓存颗粒度;
  3. 引入缓存过期时间对峰值尖刺进行削峰,减少并发量;
相关推荐
To_OC6 小时前
Next.js + Redis 构建笔记系统:Redis Hash 实战与性能优化
redis·后端·next.js
lv__pf9 小时前
redis【msb 2026金三银四redis上】
数据库·redis·缓存
Diligently_11 小时前
Anolis 系统更新与密码设置&磁盘扩容
java·后端·spring
spter。13 小时前
一次 Redis SETNX 的小插曲,我重新理解了原子性
前端·redis·bootstrap
霸道流氓气质13 小时前
Spring 事务同步机制 —— AfterTransactionActionCollector 的异步解耦原理
java·后端·spring
星空15 小时前
Springboot复习
java·spring boot·spring
霸道流氓气质17 小时前
Redis Pub/Sub — 概念、原理、场景与代码示例
数据库·redis·缓存
钱栈up18 小时前
数据开放服务 Redis 缓存架构设计:从腹稿到落地方案
数据库·redis·缓存
聊浮游18 小时前
JAVA2026最新全套学习资料、学习路线
java·开发语言·jvm·mysql·spring·maven·idea
夕除19 小时前
redis--002
数据库·redis·缓存