当前设置
我在两个不同的计算机上运行一个应用程序的两个实例。两个应用程序节点共享分布式缓存的Hazelcast配置。高速缓存可以与常规IMap<String, SomeSerializableValue>
正常工作。
问题
现在,我遇到了一种情况,可缓存值的计算速度慢且成本高。我想确保给定键的值仅在单个应用程序节点上计算。如果另一个节点获取了密钥的值,但计算仍在进行中,则该节点应等待计算完成。
理想的解决方案是这样的:
IMap<String, CompletableFuture<SomeSerializableValue>>
但是这种方法显然行不通,因为CompletableFuture
不可序列化。
问题
Hazelcast中是否有其他解决方案可以满足我的要求?
例如,咖啡因的概念是AsyncLoadingCache。但是,它不是分布式的。 Hazelcast可以缓存异步计算的值吗?
答案 0 :(得分:1)
Offloadable Entry Processor会工作吗?
这使您可以在边线线程中对Map.Entry.Value
应用“长时间运行”的更新。
在运行更新时,读取调用将返回现有值。仅在更新计算完成后,写入才可见。
答案 1 :(得分:0)
我和你有同样的问题。
我试图通过调用传递的回调IF(如果键的值在缓存中不存在),来创建一个通用的kotlin类来读取和填充缓存(作为ConcurrentMap 因此,当我为HazelCast创建实例(用CompletableFuture包装值) 尝试从缓存中读取时出现以下异常: 这是HZ API(包括其异步API)
https://docs.hazelcast.org/docs/3.8/javadoc/com/hazelcast/core/IMap.html 我得出以下结论: companion object {
fun <K, V> create(config: MapConfig, name: String) =
Hazelcast.newHazelcastInstance()
.apply {
this.config.addMapConfig(config)
}.getMap<K, CompletableFuture<V>>(name) //TRYING TO WRAP with CompletableFuture as the AsyncLoad cache does in caffeine
}
Failed to serialize 'java.util.concurrent.CompletableFuture'
com.hazelcast.nio.serialization.HazelcastSerializationException: Failed to serialize 'java.util.concurrent.CompletableFuture'
at com.hazelcast.internal.serialization.impl.SerializationUtil.handleSerializeException(SerializationUtil.java:115)
at com.hazelcast.internal.serialization.impl.AbstractSerializationService.toBytes(AbstractSerializationService.java:175)
at com.hazelcast.internal.serialization.impl.AbstractSerializationService.toBytes(AbstractSerializationService.java:151)
at com.hazelcast.internal.serialization.impl.AbstractSerializationService.toData(AbstractSerializationService.java:136)
at com.hazelcast.internal.serialization.impl.AbstractSerializationService.toData(AbstractSerializationService.java:124)
at com.hazelcast.spi.impl.NodeEngineImpl.toData(NodeEngineImpl.java:341)
at com.hazelcast.spi.impl.AbstractDistributedObject.toData(AbstractDistributedObject.java:78)
at com.hazelcast.map.impl.proxy.MapProxyImpl.putIfAbsent(MapProxyImpl.java:172)
at com.hazelcast.map.impl.proxy.MapProxyImpl.putIfAbsent(MapProxyImpl.java:162)
at cache.utility.caffeine.SuspendingCache$get$$inlined$read$1.invokeSuspend(
(if (cache.containsKey(key)) { //Read operations are thread-safe and are not blocking
return cache.getAsync(key).await() // In Kotlin kotlinx.coroutines.future.await(), in Java you would subscribe from this somehow
} else {
val value = callBack.invoke(key)
cache.setAsync(key,value)
return value
}