是否有可能在 Caffeine 中获得一组候选被驱逐的密钥?
Is it possible to get the set of candidate evicted keys in Caffeine?
我正在尝试使用缓存来维护基于请求类型的可路由服务器列表。
LoadingCache<Request, ActorRef> serversByRequestType = Caffeine.newBuilder()
.writer(new CacheWriter<RequestType, ActorRef>() {
@Override public void write(RequestType req, ActorRef server) {
// We need to handle this type of request now.
//
server.tell(StartUp(req))
}
@Override public void delete(RequestType req, ActorRef server, RemovalCause cause) {
// This req type can no longer be handled, so remove from
// routable servers.
//
server.tell(ShutDown(req))
}
})
.build();
在我最多只能有 n
个服务器的情况下,重要的是同步从缓存中删除(并因此关闭)服务器,然后添加(并因此旋转) -up) 相同 缓存中的服务器(即更改服务器可以处理的流量)。
在上面的代码中,没有阻塞就无法做到这一点。
在理想情况下,在缓存中删除必须在添加之前发生,因此我可以异步关闭服务器并等待 ShutdownServer
事件...但是无法从内部接收此信号write
方法,它必然需要知道何时开始。换句话说,我想发送一个 SwitchServerTraffic(from: RequestType, to: RequestType)
到 server
,其中 from
将是被逐出的密钥,而 to
将是添加的密钥。
如果我可以访问候选逐出集:当请求进入时,如果它的类型不在缓存中并且缓存已满,我可以 select 逐出集中的元素和关闭其服务器,然后将请求类型同步添加到缓存 à la Akka。
有没有办法访问 Caffeine 中的候选驱逐集?如果不是,是否有另一种方法来解决这个问题?
您可以猜测逐出顺序中的物品,但这不能保证。该策略是不确定的,概率性有助于防止 HashDoS 攻击。通常不会公开驱逐政策的低级细节以允许算法改进。
Map<K, V> coldest = cache.policy().eviction().get().coldest(count);
如果删除发生在逐出之前,则需要所有写入都由独占锁保护,或者可以同时评估策略。前者将成为瓶颈,而后者将导致命中率明显降低(例如,通过使用随机抽样)。缓存改为使用带有中间缓冲区的记录和重放策略,它吸收了并发的大部分损失。
默认情况下,逐出是与面向用户的调用异步执行的,因此大多数对 CacheWriter#delete
的调用都将被隐藏。但是,如果该调用很昂贵,那么它会延迟下一个项目的驱逐。
不幸的是,如果不站在自己的立场上就很难提供建议,因为您的场景对您的需求有独特的限制。您可能会发现 Cache.asMap()
中的计算方法对解决方案最终的样子很有用。
我正在尝试使用缓存来维护基于请求类型的可路由服务器列表。
LoadingCache<Request, ActorRef> serversByRequestType = Caffeine.newBuilder()
.writer(new CacheWriter<RequestType, ActorRef>() {
@Override public void write(RequestType req, ActorRef server) {
// We need to handle this type of request now.
//
server.tell(StartUp(req))
}
@Override public void delete(RequestType req, ActorRef server, RemovalCause cause) {
// This req type can no longer be handled, so remove from
// routable servers.
//
server.tell(ShutDown(req))
}
})
.build();
在我最多只能有 n
个服务器的情况下,重要的是同步从缓存中删除(并因此关闭)服务器,然后添加(并因此旋转) -up) 相同 缓存中的服务器(即更改服务器可以处理的流量)。
在上面的代码中,没有阻塞就无法做到这一点。
在理想情况下,在缓存中删除必须在添加之前发生,因此我可以异步关闭服务器并等待 ShutdownServer
事件...但是无法从内部接收此信号write
方法,它必然需要知道何时开始。换句话说,我想发送一个 SwitchServerTraffic(from: RequestType, to: RequestType)
到 server
,其中 from
将是被逐出的密钥,而 to
将是添加的密钥。
如果我可以访问候选逐出集:当请求进入时,如果它的类型不在缓存中并且缓存已满,我可以 select 逐出集中的元素和关闭其服务器,然后将请求类型同步添加到缓存 à la Akka。
有没有办法访问 Caffeine 中的候选驱逐集?如果不是,是否有另一种方法来解决这个问题?
您可以猜测逐出顺序中的物品,但这不能保证。该策略是不确定的,概率性有助于防止 HashDoS 攻击。通常不会公开驱逐政策的低级细节以允许算法改进。
Map<K, V> coldest = cache.policy().eviction().get().coldest(count);
如果删除发生在逐出之前,则需要所有写入都由独占锁保护,或者可以同时评估策略。前者将成为瓶颈,而后者将导致命中率明显降低(例如,通过使用随机抽样)。缓存改为使用带有中间缓冲区的记录和重放策略,它吸收了并发的大部分损失。
默认情况下,逐出是与面向用户的调用异步执行的,因此大多数对 CacheWriter#delete
的调用都将被隐藏。但是,如果该调用很昂贵,那么它会延迟下一个项目的驱逐。
不幸的是,如果不站在自己的立场上就很难提供建议,因为您的场景对您的需求有独特的限制。您可能会发现 Cache.asMap()
中的计算方法对解决方案最终的样子很有用。