HotKey学习总结
开源地址:https://gitee.com/jd-platform-opensource/hotkey
1.它用来解决啥问题?
对任意突发性的无法预先感知的热点数据,包括并不限于热点数据(如突发大量请求同一个商品)、热用户(如恶意爬虫刷子)、热接口(突发海量请求同一个接口)等,进行毫秒级精准探测到。然后对这些热数据、热用户等,推送到所有服务端JVM内存中,以大幅减轻对后端数据存储层的冲击,并可以由使用者决定如何分配、使用这些热key(譬如对热商品做本地缓存、对热用户进行拒绝访问、对热接口进行熔断或返回默认值)。
总结一句话:热点缓存,防止穿透
2.它是怎么做的?
它通过客户端主动上报数据到计算节点(wroker),通过获取配置中心的规则配置最终计算出热点数据。通过计算节点回推给所有的客户端,本地JVM缓存起来。
3.架构又是如何?
官网的一份图很清晰明了。如下:
docker集群:代表用户的客户端
worker集群:计算集群
etcd集群:配置集群,存储规则,worker节点,client节点,dashboard节点信息。
流程介绍:
客户端通过引用hotkey的client包,在启动的时候上报自己的信息给worker和worker之间建立长连接。定时拉取配置集群上面的规则信息和worker集群信息。
客户端调用hotkey的ishot的方法来首先匹配规则,然后统计是不是热key;通过定时任务把热key数据上传到worker节点。worker集群在收取到所有关于这个key的数据以后(因为通过hash来决定key 上传到哪个worker的,所以同一个key只会在同一个worker节点上),和定义的规则匹配判断是不是热key,然后推送给客户端,完成缓存
4.简单使用
//判断rekey
public Object a(String s) {
if (JdHotKeyStore.isHotKey(”store_" + s)) {
logger.error("isHot");
} else {
logger.error("noHot");
}
return 1;
}
//获取热key value
public String get(String key) {
Object object = JdHotKeyStore.getValue(key);
//如果已经缓存过了
if (object != null) {
System.out.println("is hot key");
return object.toString();
} else {
//底层获取
String value = getFromRedis(key);
//判断热key,塞入值
JdHotKeyStore.smartSet(key, value);
return value;
}
}
client仅仅需要调用JdHotKeyStore.isHotKey
来判断是不是热key,后面都会做好所有的初始化工作,几乎0接入门槛。
get
的方法演示了他是如何获取热key缓存的,当缓存失效的时候,我们还可以通过多种方式处理。
5.原理又是如何?
介绍一下最重要的几个过程
5.1 client启动过程调用
client启动,从etcd中获取所有关于我这个APP的worker集群。通过Netty和所有的worker节点保持长连接,发送信息。
worker接受到client的信息,上报client的信息和client的APP信息,在etcd里面保存。
PS:client启动的时候不止是会做这个,还会启动很多定时任务。通过定时任务的方式上传判断的热key和统计数据,还会和etcd保持长连接来监听数据的变化,来更新本地的缓存信息
5.2 client 热key的过程
上面就是热key的调用过程,比较清晰,不用文字了。
5.3 上传热key消息
@Override
public void collect(HotKeyModel hotKeyModel) {
String key = hotKeyModel.getKey