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

相关推荐
小陈工2 小时前
Python Web开发入门(十七):Vue.js与Python后端集成——让前后端真正“握手言和“
开发语言·前端·javascript·数据库·vue.js·人工智能·python
科技小花6 小时前
数据治理平台架构演进观察:AI原生设计如何重构企业数据管理范式
数据库·重构·架构·数据治理·ai-native·ai原生
一江寒逸6 小时前
零基础从入门到精通MySQL(中篇):进阶篇——吃透多表查询、事务核心与高级特性,搞定复杂业务SQL
数据库·sql·mysql
D4c-lovetrain6 小时前
linux个人心得22 (mysql)
数据库·mysql
阿里小阿希7 小时前
CentOS7 PostgreSQL 9.2 升级到 15 完整教程
数据库·postgresql
荒川之神7 小时前
Oracle 数据仓库雪花模型设计(完整实战方案)
数据库·数据仓库·oracle
做个文艺程序员7 小时前
MySQL安全加固十大硬核操作
数据库·mysql·安全
不吃香菜学java7 小时前
Redis简单应用
数据库·spring boot·tomcat·maven
一个天蝎座 白勺 程序猿7 小时前
Apache IoTDB(15):IoTDB查询写回(INTO子句)深度解析——从语法到实战的ETL全链路指南
数据库·apache·etl·iotdb
不知名的老吴7 小时前
Redis的延迟瓶颈:TCP栈开销无法避免
数据库·redis·缓存