关于三高体系,Redis是有必要/必需的,当并发高到必定的程度就或许会出现HotKey的问题,今天咱们来看下Redis中的HotKey怎么解决。

什么是HotKey

在较短的时刻内,海量恳求拜访一个Key,这样的Key就被称为HotKey。

HotKey的损害

  • 海量恳求在较短的时刻内,拜访一个Key,势必会导致被拜访的Redis服务器压力剧增,或许会将Redis服务器击垮,然后影响线上事务
  • HotKey过期的一瞬间,海量恳求在较短的时刻内,拜访这个Key,由于Key过期了,这些恳求会走到数据库,或许会将数据库击垮,然后影响线上事务。(这是缓存击穿问题)

HotKey怎么解决

HotKey怎么解决是一个比较宽泛的问题,涉及到多个方面,咱们一个个来看。

Redis部署

通常来说,Redis有两种集群方法:数据分片集群、主从+岗兵集群,其实这两种集群方法或多或少的都必定程度上缓解了HotKey的问题。

主从+岗兵集群

假如咱们选用单主:

  • 一切的读恳求都会打在仅有的一个Redis服务器,都不用管Key是什么,只需并发一高,就会导致Redis服务器压力剧增;
  • 一旦仅有的一个Redis服务器挂了,就没有第二个Redis服务器顶上去了,无法持续供给服务。

假如咱们选用主从+岗兵集群:

  • 读恳求会被涣散到Master节点或许多台Slave节点,将恳求进行了初步的涣散;
  • Master节点挂了,Slave节点会晋级为新的Master节点,持续供给服务。

数据分片集群

Key被涣散在了不同的Redis节点,将恳求进行了进一步的涣散。

假如选用数据分片集群,同时也会部署主从+岗兵,这样又有了主从+岗兵集群的特性:

  • 读恳求会被涣散到Master节点或许多台Slave节点,将恳求进行了初步的涣散;
  • Master节点挂了,Slave节点会晋级为新的Master节点,持续供给服务。

画外音:我以前一向认为大部分公司都现已选用了数据分片集群,其实不然,某个我认为不差钱的公司,在2021年选用的仍是主从+岗兵集群,出了问题,才转变成数据分片集群,我到咱们公司一瞧,才发现咱们公司也是主从+岗兵集群。

阻隔

不同的事务分配不同的Redis集群,不要将一切的事务都“稠浊”在一个Redis集群。

只需能够做到集群+阻隔,在必定程度上就现已避免了HotKey,可是关于超高并发的体系来说,或许还有点不行,所以才会有下面的更进一步的办法。

怎么应对HotKey

这个问题,能够拆分红三个子问题:怎么发现HotKey、怎么告诉HotKey的发生、怎么对HotKey进行处理。

怎么发现HotKey

怎么发现HotKey的前提是知道每个Key的运用情况,并进行计算,所以这又拆成了两个更小的子问题:怎么知道每个Key的运用情况,怎么进行计算。

怎么知道每个Key的运用情况

谁最清楚知道每个Key的运用情况,当然是客户端、署理层,所以咱们能够在客户端或许署理层进行埋点。

客户端埋点

在客户端恳求Redis的代码中进行埋点。

长处:

  • 完成较为简略
  • 轻量级
  • 几乎没有功能损耗

缺陷:

  • 进行统一管理较为费事:假如想敞开或许关闭埋点、上报,会比较费事
  • 晋级、迭代较为费事:假如埋点、上报方法需求优化,就需求晋级Jar包,再找一个黄道吉日进行发布
  • 客户端会有必定的压力:不论是实时上报运用情况,仍是准实时上报运用情况,都会对客户端形成必定的压力
署理层埋点

客户端不直接衔接Redis集群,而是衔接Redis署理,在署理层进行埋点。

长处:

  • 客户端没有压力
  • 对客户端完全通明
  • 晋级、迭代比较简略
  • 进行统一管理比较简略

缺陷:

  • 完成复杂
  • 会有必定的功能损耗:署理层需求转发恳求到真正的Redis集群
  • 单点故障问题:需求做到高可用,更复杂
  • 单点热门问题:署理层本身便是一个热门,需求涣散热门,更复杂

怎么上报每个Key的运用情况

咱们在客户端或许署理层进行了埋点,自然是由它们上报每个Key的运用情况,怎么上报又是一个小论题。

实时/准实时
  • 实时上报:每次恳求,都进行上报
  • 准实时上报:堆集必定量或许必定时刻的恳求,再进行上报
是否预计算

假如选用准实时上报,在客户端或许署理层是否对运用情况进行预计算:

  • 进行预计算:削减上报的数据量,减轻计算的压力,本身会有压力
  • 不进行预计算:上报的数据量比较多,本身几乎没有压力

怎么计算

不论怎么进行上报,运用情况终究都会经过Kafka,发送到计算端,这个时分计算端就来活了。
一般来说,这个时分会借助于大数据,较为简略的方法:Flink开一个时刻窗口,消费Kafka的数据,对时刻窗口内的数据进行计算,假如在一个时刻窗口内,某个Key的运用达了必定的阈值,就代表这是一个HotKey。

怎么告诉HotKey的发生

经过上面的过程,咱们现已知道了某个HotKey发生了,这个时分就需求告诉到客户端或许署理层,那怎么告诉HotKey的发生呢?

  • MQ:用MQ告诉客户端或许署理层HotKey是什么
  • RPC/Http:经过RPC/Http告诉客户端或许署理层HotKey是什么
  • 装备中心/注册中心指令:既然遇到了HotKey的问题,并且想解决,那基本上是技能实力十分强大的公司,应该有十分完善的服务治理体系,此时,能够经过装备中心/注册中心下发指令到客户端或许署理层,奉告HotKey是什么

怎么处理HotKey

客户端或许署理层现已知晓了HotKey发生了,就主动敞开必定的战略,来避免HotKey带来的热门问题:

  • 运用本地缓存,不至于让一切恳求都打到Redis集群
  • 将HotKey的数据仿制多份,涣散到不同的Redis节点上

在实际开发中,或许在很大程度上,都不会有埋点、上报、计算,告诉、战略主动敞开,这一套比较完善的Redis HotKey解决方案,咱们能做到的便是预估某个Key或许会成为热门,就选用本地缓存+仿制多份HotKey数据的方法来避免HotKey带来的热门问题。咱们还经常会由于偷闲,所以设计了一个大而全的Key,一切的事务都从这个Key中读取数据,可是有些事务只需求其间的一小部分数据,有些事务只需求另外一小部分数据,假如不同的事务读取不同的Key,又能够将恳求进行涣散,这是十分简略,并且有效的方法。

End