Skip to content

Latest commit

 

History

History
50 lines (28 loc) · 3.83 KB

AboutLateralCacheKit.md

File metadata and controls

50 lines (28 loc) · 3.83 KB

LateralCacheKit

实现了分布式组件之间的缓存共享(不保证数据一致性)

LateralCacheKit架构

服务发现

使用UDP组播的方式,从局域网中进行缓存信息的组播与接收组播中其他缓存发送过来的注册信息。KitCacheFactory创建缓存实例时,通过检查KitCacheAttributes,可以判断当前缓存是否需要创建LateralCacheKit。创建了LateralCacheKit之后,缓存实例内部会有下述活动发生:

  1. createDiscoveryService():创建发现服务,用于监听指定的端口,接收来自局域网中UDP组播;
  2. 在上一步创建发现服务的过程中(创建发送线程过程中),会马上往UDP组播中发送一条带有UDPDiscoveryMessage.BroadcastType.REQUEST请求组播的信息,让已经启动并加入UDP组播的远程实例,开始组播发送相关注册信息;
  3. 调用discoveryService.startup()方法后,开始持续轮询监听,这时如果上一条请求组播的信息成功传递至其他远程实例中,就会得到一条带有UDPDiscoveryMessage.BroadcastType.PASSIVE标识的注册信息,拿到该信息,注册至本地缓存中;
  4. 调用service.setScheduledExecutorService(),使用一个定时线程池,每15s进行定时发送注册信息至其他缓存实例中,用于让其他远程实例发现本缓存;
  5. 当缓存所处的JVM是正常关闭时(非强制关闭),JVM的shutdownHook将起作用,会发送一条带有UDPDiscoveryMessage.BroadcastType.REMOVE的移除缓存的信息,至其他远程缓存中,远程缓存将在本地的注册信息中移除该缓存信息。

数据同步

这里的数据同步分为两种:

  • 更新时同步
  • 获取时同步

为什么有两种同步方式?

假设有Service-AService-B两个远程服务。

  1. 更新时同步的意义:假设Service-A插入了一个数据K-V,此时未开启更新时同步,Service-B去根据K获取对应数据V时,突然Service-A宕机了,或因为网络通信原因,无法连接至Service-A
  2. 获取时同步的意义:假设Service-A先启动,且插入新的数据K1-V1,在插入之后Service-B才启动,去获取数据K1所对应的值,如果此时缓存只开启更新时同步,则无法取得值V1,若开启了获取时同步,则可以去请求Service-A获取对应值V1

更新时同步-流程

Service-A往本地缓存存入一个K-V数据时,最终会访问到LateralCacheAsyncFacade.update() / remove()方法;

这个对象内部维护了一个远程实例LateralCacheAsyncs列表,最终会一一调用其中每个实例的update() / remove()方法;

在这些实例的update() / remove()中,都使用了事件包装的方法,将updateremove事件进行各自不同的事件封装,最终由LateralCache调用lateralTCPService中的sender进行发送至其他服务。

假设Service-B接收到了Service-A发送来的更新信息,LateralTCPReceiver.ListenerReceiverThread线程会接收到该信息(该线程一直开启,循环监听),并将其包装成对应的事件通过线程池进行处理,最终调用本地缓存的localUpdate()方法将K-V数据存储到本地中。

获取时同步-流程

Service-A需要去获取键K对应的值V,在本地上并没有存储,则需通过分布式的其他缓存中进行获取。

同样是通过LateralCacheAsyncFacade中的一个列表LateralCacheAsyncs,对每个Async实例进行轮询,若得到了结果,则停止轮询;

在这些实例中,最终调用了LateralTCPSender.sendAndReceive()方法,发送信息,并且等待其他客户端,返回对应的信息;

拿到结果后,若为null继续轮询,不为null,则得到对应的值V