热key总结
什么是热key?
1 、MySQL等数据库会被频繁访问的热数据
如爆款商品的skuId。
2 、redis的被密集访问的key
如爆款商品的各维度信息,skuId、shopId等。
3 、机器人、爬虫、刷子用户
如用户的userId、uuid、ip等。
4 、某个接口地址
如/sku/query或者更精细维度的。
5、 用户id+接口信息
如userId + /sku/query,这代表某个用户访问某个接口的频率。
6 、服务器id+接口信息
如ip + /sku/query,这代表某台服务器某个接口被访问的频率。
7 、用户id+接口信息+具体商品
如userId + /sku/query + skuId,这代表某个用户访问某个商品的频率。
以往热key问题怎么解决?
我们分别以redis的热key、刷子用户、限流等典型的场景来看。
redis热key:
这种以往的解决方式比较百花齐放,比较常见的有:
1)上二级缓存,读取到redis的key-value信息后,就直接写入到jvm缓存一份,设置个过期时间,设置个淘汰策略譬如队列满时淘汰最先加入的。或者使用guava cache或caffeine cache进行单机本地缓存,整体命中率偏低。
2)改写redis源码加入热点探测功能,有热key时推送到jvm。问题主要是不通用,且有一定难度。
3)改写jedis、letture等redis客户端的jar,通过本地计算来探测热点key,是热key的就本地缓存起来并通知集群内其他机器。
4)其他
刷子爬虫用户:
常见的有:
1)日常累积后,将这批黑名单通过配置中心推送到jvm内存。存在滞后无法实时感知的问题。
2)通过本地累加,进行实时计算,单位时间内超过阈值的算刷子。如果服务器比较多,存在用户请求被分散,本地计算达不到甄别刷子的问题。
3)引入其他组件如redis,进行集中式累加计算,超过阈值的拉取到本地内存。问题就是需要频繁读写redis,依旧存在redis的性能瓶颈问题。
限流:
1)单机维度的接口限流多采用本地累加计数
2)集群维度的多采用第三方中间件,如sentinel
3)网关层的,如Nginx+lua
综上,我们会发现虽然它们都可以归结到热key这个领域内,但是并没有一个统一的解决方案,我们更期望于有一个统一的框架,它能解决所有的对热key有实时感知的场景,最好是无论是什么key、是什么维度,只要我拼接好这个字符串,把它交给框架去探测,设定好判定为热的阈值(如2秒该字符串出现20次),则毫秒时间内,该热key就能进入到应用的jvm内存中,并且在整个服务集群内保持一致性,要有都有,要删全删。
热key进内存后的优势
热key问题归根到底就是如何找到热key,并将热key放到jvm内存的问题。只要该key在内存里,我们就能极快地来对它做逻辑,内存访问和redis访问的速度不在一个量级。
譬如刷子用户,我们可以对其屏蔽、降级、限制访问速度。热接口,我们可以进行限流,返回默认值。redis的热key,我们可以极大地提高访问速度。
以redis访问key为例,我们可以很容易的计算出性能指标,譬如有1000台服务器,某key所在的redis集群能支撑20万/s的访问,那么平均每台机器每秒大概能访问该key200次,超过的部分就会进入等待。由于redis的瓶颈,将极大地限制server的性能。
而如果该key是在本地内存中,读取一个内存中的值,每秒多少个万次都是很正常的,不存在任何数据层的瓶颈。当然,如果通过增加redis集群规模的形式,也能提升数据的访问上限,但问题是事先不知道热key在哪里,而全量增加redis的规模,带来的成本提升又不可接受。
热key探测关键指标
1、实时性
这个很容易理解,key往往是突发性瞬间就热了,根本不给你再慢悠悠手工去配置中心添加热key再推送到jvm的机会。它大部分时间不可预知,来得也非常迅速,可能某个商家上个活动,瞬间热key就出现了。如果短时间内没能进到内存,就有redis集群被打爆的风险。
所以热key探测框架最重要的就是实时性,最好是某个key刚有热的苗头,在1秒内它就已经进到整个服务集群的内存里了,1秒后就不会再去密集访问redis了。同理,对于刷子用户也一样,刚开始刷,1秒内我就把它给禁掉了。
2、准确性
这个很重要,也容易实现,累加数量,做到不误探,精准探测,保证探测出的热key是完全符合用户自己设定的阈值。
3、集群一致性
这个比较重要,尤其是某些带删除key的场景,要能做到删key时整个集群内的该key都会删掉,以避免数据的错误。
4、高性能
这个是核心之一,高性能带来的就是低成本,做热key探测目的就是为了降低数据层的负载,提升应用层的性能,节省服务器资源。不然,大家直接去整体扩充redis集群规模就好了。
理论上,在不影响实时性的情况下,要完成实时热key探测,所消耗的机器资源越少,那么经济价值就越大。