【HBZ分享】Redis的热点key问题

Redis是如何将数据落在某个Redis节点上的?

  1. 通过crc16取模(不是hash算法,是校验一种算法)计算该key应该落到哪个hash槽(solt)上,一共16384个hash槽上,这些槽位会均匀分布在每个节点 上(注意:只有主节点才有槽位,子节点没有)。
  2. 当某些高频的key落到同一个redis节点上,导致流量数据倾斜,导致大量的请求会打在某一台节点上,就会造成我们所说的热点key。
  3. 比如【热卖商品】【热点新闻】【热点评论】【大V明星】等场景可能会造成热点key
  4. 什么是热点key:访问量很大的时候才算是热点key,即某个key访问频率很高,比如qps达到1000就需要关注了

如何去发现热点key(Hot key)

  1. 经验处理:通过经验,去预估哪些会称为热点key,提前做处理(可顺便使用,不可做为主要解决方案)
    (1). 优点: 方案简单,凭借经验就可以发现热点key
    (2). 缺点: 没有办法预测所有热点key,比如火爆商品,很难预测所有火爆商品都有哪些

  2. 节点和slot流量监控:每个节点都去流量监控,比如阿里云监控CPU,内存,负载,带宽等参数,是否存在快速上升问题去判断是否出现热点key了。(监测肯定要做的,但复杂场景不能只用这一种方案,需要结合更高级的第三种方案)
    (1). 优点:监控方便,方案简单
    (2). 缺点:粒度太粗,适合前期集群,不适用于精准探测到热点key

  3. 客户端统计:需要客户端二次定制,比如应用程序连接redis需要通过jedis,可以通过程序读取jedis的日志,来进行统计,相当于对数据进行埋点采集,然后把收集的数据上报到统一的计算服务中进行聚合统计(复杂项目要使用,简单项目可以不用。)
    (1). 优点:准确性高,实时性好
    (2). 缺点:需要对SDK工具进行二次开发,开发难度很大,业务链路更复杂

如何解决热点key

  1. 本地缓存:
    (1). 用户只读的信息都放到本地缓存,即从redis读到数据后再保存到本地缓存中,无需可以发现热点key
    (2). 当读取时先读本地缓存,如果有直接返回,如果没有再去redis节点找
    (3). 缺点:本地缓存一份,redis也有一份,那就可能出现短暂的数据不一致的问题,业务如果可以接受那就可以

  2. 离散热点key:
    (1). 将业务key拼接上一个字符串,比如【机器ip】
    (2). 这样做相当于把一份数据冗余到所有redis节点上都有一份,因为不同机器的ip不同,拼接到业务key后整体的key就发生了变化,会计算出不同的hash。
    (3). 热key访问会通过nginx负载请求到不同的后端服务器, 那么这些大量请求由于后端服务器ip不同,会分散到不同的redis节点去查询,因为查询也需要拼接上机器ip,这样同样的数据就会去不同的redis节点查询,不会导致所有请求都冲向一台redis节点。
    (4). 拼接后的key举例:
    product_key_192.168.1.0,
    product_key_192.169.1.1,
    product_key_192.170.10.8

  3. 网关缓存 + 实时计算【推荐复杂项目后期】
    (1). 应用程序的日志打印访问的数据(因为访问应用程序访问redis都会有日志记录), 结合流式计算(flink), 时间窗范围内进行【key访问频率统计】
    (2). 如果统计计算出超过一定频率阈值的热key,比如时间窗内访问增长快,预判会成为热点key,那么就将这个数据放置到业务网关缓存里面,相当于前置热点缓存,客户再访问热点key,就会直接从网关缓存nginx获取, qps可达到10万+,并且无需走后端接口。(nginx可以写lua脚本,就算nginx不存在,lua脚本也可以直接访问redis,无需走后端。)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值