最近记录了一些java中常踩的坑、设计思路和小知识点,大家可以看看
详细记录一次接入xxl-job的踩坑路径
30s快速解决循环依赖
idea中一个小小的操作竟能解决如此多的问题
docker中的服务接入xxljob需要注意的一点
关于一次fullgc的告警分析
mysql中的int类型竟变成了它?
jpa中的字段总是自己莫名更新?
获取不到类上的注解?空指针?
学会这招,再也不怕依赖冲突!
redis的热点key还能这么处理?
领导让我设计一个任务系统
当服务重启时,大部分人没考虑这点
参数还能这么优雅校验?
文件上传报错,全局异常处理!
常见的点赞功能如何实现,如何防止刷赞
背景
其实这是一个很常见的场景
- 我们单台redis的承载是有上限的
- 业务场景中经常会有这种,比如热点商品抢购场景,热搜等,都会出现同时搜索同一个key的场景。
- 哪怕部署了集群,通过一致性hash之后,这些请求还是会打到一个机子上,因为是一个key。
如何发现热点数据
主要针对的是C端,B端的话一是不会有这么高的并发,二是也能够预测中哪些是热点key。
即便是C端,其实有些业务场景也是能够预测出热点key的,比如在做某些电商活动的时候,可以给一些热销商品做一个提前缓存。
某些无法预测的,只能实时去处理,比如热搜。
当然,实时处理的有很多办法,redis自带的一些参数,或者是客户端自己统计收集一些信息等。
如何解决
主要是两个思路
- 本地缓存也就是二级缓存。把热点key缓存到JVM中,当请求到来时,如果是热点key,直接在JVM中取,不走redis,就避免了打垮redis。毕竟应用服务器是有很多台的嘛,可以负载。
- 复制热点key到多个redis实例上,但是这种方法不推荐,维护起来不方便。
什么时候缓存热点key?
我们最理想的场景,当然是程序可以自己去实时的判断一个key是否有成为热点key的趋势或者说已经是一个热点key,当确认的时候,就把他缓存到jvm中,下次有请求来就直接去jvm拿。
实现思路也有几种。
- 本地实现一个sdk,这个sdk就是来做一个流量分析,类似于redis自带的那个工具,只不过放在了应用这边。
- 或者是利用kafka之类的,做一个异步的流量统计,发送到一些流量计算系统,然后发现是热点数据的时候,就推给应用层,应用层及时的缓存起来。