我有一个具有2个节点(即2个JVM)的集群环境。我正在尝试检查Hazelcast ILock内部的Hazelcast IMap是否存在密钥,如下所示:
解决方案1:
public static final String CUR_ACC_MAP = "CUR_ACC_MAP";
private static final HazelcastInstance hazelInstance = Hazelcast.getHazelcastInstanceByName("accountCache");
public static boolean currencyAccountCreationInPorgress(String key) {
ILock lock = hazelInstance.getLock(CUR_ACC_MAP);
lock.lock();
try {
IMap<Object, Object> map = hazelInstance.getMap(CUR_ACC_MAP);
if (!map.containsKey(key)) {
map.putIfAbsent(key, System.currentTimeMillis());
return false;
}
return true;
} finally {
lock.unlock();
}
}
但是问题是,当在2个节点中同时调用请求时,两个节点都将进入if条件[if(!map.containsKey(key)){...}]。
因此,群集中的两个节点都从上述方法返回false。我在做什么吗?
我最初尝试使用以下代码,但该代码也不起作用,因此我切换到了上面的解决方案1,但是那也不起作用。
解决方案2:
public static final String CUR_ACC_MAP = "CUR_ACC_MAP";
private static final HazelcastInstance hazelInstance = Hazelcast.getHazelcastInstanceByName("accountCache");
public static boolean currencyAccountCreationInPorgress(String key) {
IMap<Object, Object> map = hazelInstance.getMap(CUR_ACC_MAP);
map.lock(CUR_ACC_MAP);
try {
if (!map.containsKey(key)) {
map.putIfAbsent(key, System.currentTimeMillis());
return false;
}
return true;
} finally {
map.unlock(CUR_ACC_MAP);
}
}
这是我的Hazelcast配置:
<hz:hazelcast id="hzInstance">
<hz:config>
<hz:instance-name>accountCache</hz:instance-name>
<hz:group name="hzAcc" password="Vam123" />
<hz:network port="${account.hazelcast.port}" port-auto-increment="true">
<hz:join>
<hz:multicast enabled="false" />
<hz:tcp-ip enabled="${account.hazelcast.join.tcpip.enabled}">
<hz:members>${account.hazelcast.members}</hz:members>
</hz:tcp-ip>
</hz:join>
</hz:network>
<!-- Account File Upload Concurrent Processing Maps -->
<hz:map name="CUR_ACC_MAP" max-idle-seconds="60" eviction-policy="LRU" max-size="100000" />
最佳答案
@Rajib,
在解决方案2中,尝试使用map.lock(key)
代替,即使没有要锁定的键,它也可以工作。
在解决方案1中,如果您的两个成员都是同一个Hazelcast群集的一部分,那么只有一个成员可以访问if
块,而不是两个都可以。
没有锁的更好的解决方案是:
public static boolean currencyAccountCreationInPorgress(String key) {
return hazelInstance.getMap(CUR_ACC_MAP).putIfAbsent(key, System.currentTimeMillis()) != null;
}
putIfAbsent
操作是原子的,因此只能成功完成一次,所有其他请求将仅返回前一个值,因此您的方法将仅返回true。关于java - 在锁定范围内更新 map 时,Hazelcast ILock在群集中不起作用,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/54416184/