我想缓存一个昂贵的操作,并且不希望其他线程在给定时间在不同的JVM中执行相同的操作。我们保证同时获得至少5个接近实时的同一计算请求,并且无法控制这些请求的简化。
我能想到的解决方案:
- 这些其他线程可能会等待获取锁定(Hazelcast),但如果有更多线程,最后获得锁定的线程可能会花费很多 等待获得锁的时间。
醇>这些其他线程是否有办法简单地“等待锁定 被释放“而不是获取锁,因为他们只是阅读 从缓存?
使用投票。首先,阻塞threadId = cache.putIfAbsent(key)返回哪个线程将处理,其他线程将继续轮询另一个线程 threadId缓存条目以获取结果。这是浪费投票, 有没有办法“等待缓存读取”?
- 醇>
实际分发的“Shared Reentrant Read Write Lock”似乎是解决方案,但Apache Curator库似乎并不亮 重量。我正在寻找一个简单的异步P2P分布式缓存 方法
或者我如何使用HazelCast实现相同的目标? 总的来说,不是阻塞和避免计算(在我们的情况下CPU和IO绑定)首先是一个比让所有线程计算更好的方法,并说使用数据库/缓存失败额外写入并返回第一个计算的结果?
答案 0 :(得分:0)
以前做了以下事情,首先是使用Hazelcast发布了一个解决方案:https://github.com/ThoughtWire/hazelcast-locks。
此库可以替代执行分布式“共享重入读写锁定”,允许在写入时锁定,但在读取时不允许锁定,因此我们保证只发生一次。我们遇到的唯一问题是锁定释放通知等待的时间比我们预期的要长。除了这个事实之外,你必须在一定时间之后以某种方式明确地清理昂贵的锁,因为它们与特定的键绑定。
我们最终在请求到达tomcat容器之前在转发代理中实现了一个自定义逻辑,这些容器基本上根据密钥将请求路由到特定服务器,并且我们在基于相同的共享并发映射条目上有一个本地JVM锁定完成这项工作的关键。此外,清理逻辑要简单得多。