下面是我们的用例:
我们有4-8个节点实现分布式hazelcast缓存,每个节点可以通过具有相同事务密钥的JMS获得多个消息,我们使用密钥对象对(其中对象是一个可缓存项列表)添加缓存中的所有消息。
聚合是通过apache-camel完成的,其中我们有一个聚合器,在300 MILLISECS之后运行300 MILLISECS,我们关闭聚合窗口并从缓存中删除与事务键对应的所有项,并以编程方式聚合它们。Hazelcast的作用只是在缓存映射中收集消息,并使所有节点保持同步,因为所有节点都知道缓存问题场景中有哪些项:
问题是node1、node2知道item1和item2,因为它们有时间同步缓存项。但是node3添加item3的时间太晚了,以至于node1和node2在17:01:01:400不知道item3。假设我们在17:01:01:400从node1 (不知道item3 )开始逐出,它将给我们一个只有2项的对象,然后node1将广播给每个人,将所有用于事务的缓存项逐出-key= it 1作为响应,所有节点都将清除其缓存中的事务-key=tx1,这将导致丢失项(Item3)。
感谢您的帮助.�
发布于 2015-11-11 21:17:48
我认为您的IMap设计如下:
IMap<TransactionKey,List<CacheItem>> transactionMessagesMap
。
问题是node1、node2知道item1和item2,因为它们有时间同步缓存项。但是node3添加item3的时间太晚了,以至于node1和node2在17:01:01:400不知道item3。
您是如何将条目放入IMap的?您正在使用set()
、put()
或putAsync()
吗?put()
和set()
是同步调用,因此节点3所做的更改将以同步方式反映出来。
注意,put()
/ set()
对IMap
的操作是同步的。但是,如果您希望确保当一个节点在您的列表上操作(例如添加一个新项)时,来自其他节点的所有其他后续请求都应该看到更新的列表,那么您可能需要使用针对相关密钥的分布式锁。即
添加新项目的代码如下:
transactionMessagesMap.lock(transactionKey);
list = transactionMessagesMap.get(transactionKey);
list.add(newItem);
transactionMessagesMap.set(transactionKey, list);
transactionMessagesMap.unlock(transactionKey);
驱逐物品的守则如下:
// In your case node1 will block here until node3 has successfully updated
// item3 in the list.
transactionMessagesMap.lock(transactionKey);
list = transactionMessagesMap.get(transactionKey);
for(CacheItem item : list)
{
// perform your eviction logic here.
}
transactionMessagesMap.unlock(transactionKey);
您可以根据您的逻辑决定何时释放锁。其基本思想是根据您的用例使用一些分布式锁定机制,如IMap.lock()
或ILock
。希望这能有所帮助。
https://stackoverflow.com/questions/33635752
复制相似问题