java - Hazelcast ILock 在锁定范围内更新地图时无法在集群中工作
问题描述
我有一个有 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" />
解决方案
@拉吉布,
- 在解决方案 2 中,尝试
map.lock(key)
改用,它应该可以工作,即使没有可锁定的钥匙。 - 在解决方案 1 中,如果您的两个成员都是同一个 Hazelcast 集群的一部分,那么只有其中一个应该访问
if
block ,而不是两个。 - 没有锁的更好的解决方案是:
public static boolean currencyAccountCreationInPorgress(String key) {
return hazelInstance.getMap(CUR_ACC_MAP).putIfAbsent(key, System.currentTimeMillis()) != null;
}
putIfAbsent
操作是原子的,因此只能成功完成一次,所有其他请求将只返回以前的值,因此您的方法将只返回 true。
推荐阅读
- google-apps-script - 使用谷歌脚本将谷歌驱动器视频插入谷歌幻灯片
- javascript - axios拦截器拦截所有axios请求
- asp.net - 如何在 Identity Server 4 保护的 webapi 中访问自定义声明?
- java - 没有虚拟方法 verifyPhoneNumber,致命异常:main
- mql4 - 为什么这个字符串函数不更新?MQL4
- java - Java 中的刽子手游戏并没有脱离循环
- python - 如何修复在赋值前引用的第 6 行封闭范围中定义的“局部变量”prev_time”错误
- html - Sendgrid 暗模式与两个徽标的兼容性
- python - 从python3中的div中获取特定文本
- javascript - 将字符串中的空格替换为值“N/A”-Javascript