Redis热key大key详解

不要阻挡我走向成功,勇者配享所有,感想敢干

hotkey热key

大量请求可能会使redis节点流量不均匀,进而导致宕机,继而打到数据库崩溃;因此需要对热key优化

引发问题:

  1. 分片服务瘫痪
  2. 可能打到数据库,造成数据库瘫痪
  3. 单分片CPU高

如何发现热key?

  1. 使用自带的--hotkeys查找,需配置LFU淘汰策略。缺点全局扫描,实时性差

  2. 业务代码记录key访问次数上报聚合:缺点侵入性强

  3. TCP抓包:解析RESP流量,统计key访问频率

  4. 京东hotkey

    Redis-rdb-tools:分析RDB文件中的 大key和热key

  5. 云服务可视化工具

如何解决hotkey?

  1. 二级缓存本地缓存:如Caffeine等,清理时可用redis的pub/sub(不可靠);可用MQ的广播模式

    1. 本地缓存->redis->DB
  2. 数据分片:key分散到多个服务器:比如可以求shard=对key的hash值,newkey=key+"_"+shard分配到多个节点中

  3. 读写分离,读从从节点上请求

  4. 限流降级

bigkey大key

产生的场景

  1. 数据结构使用不当
  2. 未及时清理垃圾数据,没过期时间
  3. 对业务预估不准确

不同的场景对于大key的判定规则是不一样的啊

都有哪些危害呢?

危害

内存不均匀:单value较大时,可能会导致节点之间的内存使用不均匀,间接地影响key的部分和负载不均匀;

阻塞请求:redis为单线程,单value较大读写需要较长的处理时间,会阻塞后续的请求处理;

阻塞网络:单value较大时会占用服务器网卡较多带宽,可能会影响该服务器上的其他Redis实例或者应用

影响主从同步

影响扩容

影响AOF重写

总之就是它很不好就是了

如何发现呢?

  • Redis4.0提供了--bigkeys,--hotkeys命令;生产慎用
  • 可借助redis可视化工具another redis desktop manager查看

如何解决?

  1. 评估业务是否必要,不必要就优化掉,已有的大key删除,这种最简单
  2. 对大key进行拆分,大list就拆分成小list
  3. 对大key进行清理,用UNLINK非阻塞
  4. 定期清理失效数据
  5. 压缩value

bigkey存在可能会导致扩容失败,严重会触发master-slave的故障切换

水平扩容都可能遇到哪些问题?

下面有一些参数会有影响,这个是某大厂经过实战总结出来的宝贵经验

  1. 【cluster-node-timeout】:控制集群的节点切换参数,

master 堵塞超过 cluster-node-timeout/2 这个时间,就会主观判定该节点下线 pfail 状态,如果迁移Bigkey 阻塞时间超过 cluster-node-timeout/2,就可能会导致 master-slave 发生切换。

  1. 【migrate timeout】:控制迁移 io 的超时时间超过这个时间迁移没有完成,迁移就会中断。

  2. 【迁移重试周期】:迁移的重试周期是由水平扩容的节点数决定的,比如一个集群扩容 10 个节点,迁移失败后的重试周期就是 10 次。

  3. 【一个迁移重试周期内的重试次数】:在一个起迁移重试周期内,会有 3 次重试迁移,每一次的 migrate timeout 的时间分别是 10 秒、20 秒、30 秒,每次重试之间无间隔

比如一个集群扩容 10 个节点,迁移时候遇到一个 Bigkey,第一次迁移的 migrate timeout 是 10 秒,10 秒后没有完成迁移,就会设置 migrate timeout 为 20 秒重试,如果再次失败,会设置 migratetimeout 为 30 秒重试,如果还是失败,程序会迁移其他新 9 个的节点,但是每次在迁移其他新的节点之前还会分别设置migrate timeout 为 10 秒、20 秒、30 秒重试迁移那个迁移失败的 Bigkey。这个重试过程,每个重试周期阻塞(10+20+30)秒,会重试 10 个周期,共阻塞 600 秒。其实后面的 9个重试周期都是无用的,每次重试之间没有间隔,会连续阻塞了 Redis 实例

优化如下

  1. 【cluster-node-timeout】:延长超时时间默认是 60 秒,在迁移之前设置为 15 分钟,防止由于迁移 Bigkey 阻塞导致 master-slave 故障切换。

  2. 【migrate timeout】:减少阻塞时间为了最大限度减少实例阻塞时间,每次重试的超时时间都是 10 秒,3 次重试之间间隔 30 秒,这样最多只会连续阻塞 Redis 实例 10 秒。

  3. 【重试次数】:去掉了其他节点迁移的重试迁移失败后,只重试 3 次(重试是为了避免网络抖动等原因造成的迁移失败),每次重试间隔 30 秒,重试 3 次后都失败了,会暂停迁移,日志记录下 Bigkey,去掉了其他节点迁移的重试。

  4. 【优化日志记录】:日志记录迁移失败日志记录迁移节点、solt、key 信息,可以立即定位到问题节点及 key

相关推荐
行百里er37 分钟前
Redis 完结篇——Redis 热点问题在 Spring Boot 项目中实战
redis·后端
唠点键盘之外的1 小时前
26 向量数据库实战:从 0 搭一条能用的检索链路(pgvector + Spring AI)
数据库·人工智能·spring
云和恩墨1 小时前
数据库监控简史:监控不止于告警——从图表大爆发到健康管理闭环
数据库
ly76891 小时前
MongoDB 事务开销实测:快照隔离下的写冲突、重试与分片事务边界
数据库·mongodb·事务·分片集群·快照隔离·写冲突
豆角焖肉1 小时前
Spring AOP 自定义注解实现系统操作日志
数据库·自定义注解·springaop·操作日志·aop 切面
金伟API10243 小时前
不会写复杂SQL怎么办?
数据库·sql
执笔为剑3 小时前
2.1.2-1、V8R3迁移到V8R6-Oracle兼容特性
数据库
geovindu3 小时前
sql:Search-Optimized SQL Queries using mysql 9.0
android·数据库·sql·mysql·数据库开发·数据库架构
for_ever_love__4 小时前
MySQL SELECT 与 WHERE 优化实战:可搜索条件、联合索引与执行计划
数据库·mysql·oracle·select·where·条件优化·查询优化技巧
2501_931803754 小时前
MySQL 锁机制详解
数据库·mysql