使用分布式 JVM 缓存同步计算和结果
Posted
技术标签:
【中文标题】使用分布式 JVM 缓存同步计算和结果【英文标题】:synchronizing computation and result using a distributed JVM cache 【发布时间】:2015-06-28 06:53:24 【问题描述】:我想缓存一个昂贵的操作,并且不希望其他线程在给定时间在不同的 JVM 中执行相同的操作。我们保证在同一时间为同一计算获得至少 5 个近乎实时的请求,并且对简化这些请求没有任何控制权。
我能想到的解决方案:
这些其他线程可能会等待获取锁 (Hazelcast),但如果有更多线程,最后一个获取锁的线程可能会花费很多 等待获取锁的时间。
有没有办法让这些其他线程简单地“等待锁定” 被释放”而不是获取锁,因为他们只是在阅读 来自缓存?
使用轮询。首先,阻塞 threadId=cache.putIfAbsent(key) 返回哪个线程将处理,其他线程将继续轮询另一个 通过 threadId 缓存条目以获取结果。这是浪费投票, 有没有办法“等待从缓存中读取”?
一个实际的分布式“Shared Reentrant Read Write Lock”似乎是解决方案,但 Apache Curator 库似乎并不轻 重量。我正在寻找一个简单的异步 P2P 分布式缓存 接近。
或者我如何使用 HazelCast 达到同样的效果? 总的来说,首先阻塞和避免计算(在我们的例子中是 CPU 和 IO 限制)不是比让所有线程计算并说使用数据库/缓存失败额外写入并返回第一个计算结果更好的方法吗?
【问题讨论】:
很好的面试问题;)。 【参考方案1】:前段时间做了以下事情,首先发布了一个已经使用 Hazelcast 的解决方案:https://github.com/ThoughtWire/hazelcast-locks。
这个库代替了一个分布式的“共享可重入读写锁”,允许在写入时锁定,但在读取时不允许锁定,因此我们保证这只发生一次。我们面临的唯一问题是锁定释放通知的等待时间比我们预期的要长。除此之外,您必须在特定时间后以某种方式显式清理昂贵的锁,因为它们与特定的键相关联。
我们最终在请求到达 tomcat 容器之前在转发代理中实现了一个自定义逻辑,该容器基本上根据密钥将请求路由到特定服务器,并且我们在基于相同的共享并发映射条目上有一个本地 JVM 锁定完成这项工作的关键。此外,清理逻辑要简单得多。
【讨论】:
您能否扩展您的答案以显示它如何回答您的问题?以上是关于使用分布式 JVM 缓存同步计算和结果的主要内容,如果未能解决你的问题,请参考以下文章