首页 > 数据库 >Redis中的大key和热key

Redis中的大key和热key

时间:2023-11-28 19:31:42浏览次数:34  
标签:缓存 hash Redis 成员 redis key 节点

  • 大key定义
  • string类型的key值大于10kb
  • list,set,zset,hash的成员个数超过5000
  • list、set、zset、hash的成员数量虽然只有1000个但这些成员的value总大小为100MB(成员体积过大)

带来的问题

  • 对redis的请求变慢
  • Redis内存不断变大导致OOM,或达到maxmemory值引发写阻塞或重要key被逐出
  • Redis集群中某个node内存远超其他node
  • 由于对大key的请求很慢,容易造成请求的阻塞,在微服务架构中下容易造成服务雪崩
  • 删除一个key很耗时,容易造成主节点阻塞,从而主从切换

产生原因

  • 存放不合理,存储了不适合存放在内存中的数据,如用key存放音频视频这一类大体积二进制文件
  • 设计不合理,造成个别key中成员太多
  • 未定期清理数据,没有设置过期时间,造成了如hash类型中key中的成员不断增加

解决方法

1.查找

  • 知道哪个key有问题
    debug key-name,对key进行分析并返回分析结果;
    STRLEN(string),HLEN(hash),SCARD(set),ZCARD(zset),LLEN(list)返回成员长度;
  • 不知道哪个key有问题
    redis-cli bigkeys,仅能输出最大key,如果想进行范围查询,比如找出全部成员数量超过10的hash是做不到的

2.处理

  • 拆分:如将一个成员很多的hash拆分为多个hash
  • 删除:使用UNLINK进行异步删除,否则使用del可能造成阻塞
  • 热key定义
  • 某个key接收到的访问次数显著高于其他key时,称之为热key

带来的问题

  • 大量请求直接打过来,服务器可能会扛不住,造成缓存击穿从而直接打挂后端存储(数据库),影响其他使用后端存储的服务
  • 可能使得redis集群失去意义,redis集群中各node流量不均衡造成redis集群的分布式优势无法被利用,一个分片负载很高而其他分片十分空闲

产生原因

  • 流量陡增,如出现某款爆款商品等

解决方法

1.查找

redis-cli hotkeys用来分析热key,该参数能够返回所有key被访问的次数,使用hotkeys的前提条件是将redis-server的maxmemory-policy参数设置为LFU

2.处理

  • 复制:在使用redis集群时,可以将热key复制多份,每个redis节点上存放一份,这样不存在请求的重定向使得压力全部定向到单个节点,能够有效减轻单节点的压力。缺点是要进行复制的话只能在代码层手动操作,而且复制多份存放后会存在数据一致性问题。因此复制方案只能用于临时解决线上问题。
  • 读写分离:热key多数是读热key的操作,读写分离能够保证从节点中数据的一致性,并且能够轻松的横向扩展,能够有效地分散压力,只是有点浪费资源,因为读写分离每个从节点上存的都是一样的数据。
  • 多级缓存:当热key数量不多,比如电商平台促销活动,热key都集中在少部分key上面,为此做读写分离增加机器性价比不高,使用多级缓存是个不错的解决方法。具体实现思路两种:
    ①本地缓存:redis和业务服务器之间增加一个中间层(proxy),专门用来进行热key探查,这个proxy专门用来监视redis来统计达到预设的热key阈值的key,统计好后推送给业务服务器,让业务服务器存在本地缓存;
    ②单独缓存:将proxy探查到的热key推送到单独的一个缓存热key的redis上去,如果扛不住,热key服务器再横向扩容,当然这个方案也是单独增加了服务器节点去处理热key的,除非保证系统中经常会有热key出现,不然的使用本地缓存性价比更高。
    使用多级缓存会存在一个问题,因为每次推送之间有时间间隔,缓存中的数据和redis中的数据不是呈现强一致性的,而是呈现最终一致性的。这种代价也是不得不接受的,在使用缓存的时候注意不要拿缓存做逻辑,只用来做查询即可。

标签:缓存,hash,Redis,成员,redis,key,节点
From: https://blog.51cto.com/u_16357390/8604457

相关文章

  • Redis安装
    Linux安装下载redis上传到linux服务器的/opt目录下,解压tar-zxvfredis-7.2.3.tar.gz进入redis-7.2.3目录,执行make命令cdredis-7.2.3make&&makeinstall查看安装结果ll/usr/local/bin/redis-benchmark:性能测试工具redis-check-aof:修复有问题的AOF文......
  • 中间件:Redis-x64-5.0.14.1高可用集群-哨兵(Sentinel)模式(Win10)
     原文:https://blog.csdn.net/chenyang_wei/article/details/127846656在Redis主从复制模式中,因为系统不具备自动恢复的功能,所以当主服务器(master)宕机后,需要手动把一台从服务器(slave)切换为主服务器。在这个过程中,不仅需要人为干预,而且还会造成一段时间内服务器处于不可用状态,......
  • MySQL5.6建索引时遇到 Specified key was too long; max key length is 767 bytes错误
    解决方法//查看showvariableslike"innodb_large_prefix";showvariableslike"innodb_file_format"; //修改最大索引长度限制 setglobalinnodb_large_prefix=1;或  setglobalinnodb_large_prefix=on;setglobalinnodb_file_format=BA......
  • Linux部署Redis哨兵集群 一主两从三哨兵
    目录一、哨兵集群架构介绍二、下载安装Redis2.1、选择需要安装的Redis版本2.2、下载并解压Redis2.3、编译安装Redis三、搭建Redis一主两从集群3.1、准备配置文件3.1.1、准备主节点6379配置文件3.1.2、准备从节点6380配置文件3.1.3、准备从节点6381配置文件3.2、启动Redis主从复制......
  • 带有 on duplicate key update 的批量插入 mybatisPlus
    1packagecom.autewifi.dataaods.common.data.datascope;23importcom.baomidou.mybatisplus.annotation.IdType;4importcom.baomidou.mybatisplus.core.enums.SqlMethod;5importcom.baomidou.mybatisplus.core.injector.AbstractMethod;6importcom......
  • Redis Sentinel(哨兵)实现原理之领导者Sentinel节点选举和故障转移
    领导者Sentinel节点选举Sentinel节点之间会做一个领导者选举的工作,选出一个Sentinel节点作为领导者进行故障转移的工作。Redis使用了Raft算法实现领导者选举。故障转移领导者选举出的Sentinel节点负责故障转移,过程如下:1.在从节点列表中选出一个节点作为新的主节点,这一步是相对复杂......
  • Redis 6种淘汰机制,看看你知道哪些?
    大家好,我是pub,还记得redis缓存淘汰机制吗?今天我们回顾一下!redis是个基于内存的缓存数据库,既然是基于内存的,那肯定就会有存满的时候如果真的存满了,再有新的数据过来肯定就存不进去了此时redis会执行既定的一些淘汰策略,本文大概讲一下redis六种淘汰策略六种淘汰策略1.noeviction(默......
  • 京东技术面:Redis是如何保证高效查询的?
    大家好,我是pub,马上就到一年中最热闹的金九银十,你是不是要检验一下自己。这篇我们来看看redis。为什么Redis比较快Redis中的查询速度为什么那么快呢?1、因为它是内存数据库;2、归功于它的数据结构;3、Redis中是单线程(引入了多线程,但核心内存读写仍为单线程);4、Redis中使用了多路复......
  • 面试官:为什么阿里不推荐使用 keySet() 遍历 HashMap?太叼钻了吧。。
    来源:https://juejin.cn/post/7295353579002396726Part1引言HashMap相信所有学Java的都一定不会感到陌生,作为一个非常重用且非常实用的Java提供的容器,它在我们的代码里面随处可见。因此遍历操作也是我们经常会使用到的。HashMap的遍历方式现如今有非常多种:使用迭代器(Iterator)......
  • Vue3中 使用v-for嵌套 获取其他数组中的值作为key值 渲染数据
    <tbody><trv-for="(row,idx)inrows":key="idx"><tdv-for="(item,key)intitle":key="key">{{row[key]}}</td></tr>......