我正在尝试使用缓存来维护基于请求类型的可路由服务器列表。
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
,那么将服务器的删除(并因此关闭)与缓存同步并添加(因此启动)非常重要)缓存中的相同服务器(即,更改服务器可以处理的流量)。
在上面的代码中,没有阻止就无法做到这一点。
在理想的世界中,删除必须在添加到缓存之前进行,因此我可以异步关闭服务器并等待ShutdownServer
事件...但是无法从write
内接收此信号{1}}方法,必须知道何时开始。换句话说,我想向SwitchServerTraffic(from: RequestType, to: RequestType)
发送server
,其中from
将成为已逐出的密钥,to
将成为添加的密钥。
如果我有权访问候选驱逐集:当请求进入时,如果其类型不在缓存中并且缓存处于容量状态,我可以从驱逐集中选择一个元素并关闭其服务器,然后同步地将请求类型添加到缓存中.a Akka。
有没有办法获取咖啡因中的候选驱逐集?如果没有,是否有另一种方法可以解决这个问题呢?
答案 0 :(得分:1)
您可以获取驱逐顺序中项目的猜测,但这不能保证。该策略是非确定性的,概率有助于防止HashDoS攻击。一般而言,驱逐政策的低级细节不会被允许进行算法改进。
Map<K, V> coldest = cache.policy().eviction().get().coldest(count);
如果在驱逐之前发生删除,则要求所有写入都由独占锁保护,或者可以同时评估策略。前者将成为瓶颈,后者将导致明显更差的命中率(例如,通过使用随机抽样)。缓存改为使用记录&amp;中间缓冲区的重放策略,可以吸收大部分并发的惩罚。
默认情况下,eviction与面向用户的呼叫异步执行,因此大多数CacheWriter#delete
的呼叫都将被隐藏。但是,如果该电话费用昂贵,则会延迟下一个项目的逐出。
不幸的是,由于您的情景对您的需求有着独特的限制,因此很难提供建议而不必妥协。您可能会发现Cache.asMap()
中的计算方法对于解决方案最终看起来很有用。