我的基於Hazelcast的程序可以在兩種模式下工作:提交者和工作者。奇怪的Hazelcat IMap#put()行爲
發佈者通過一些關鍵,例如:hazelcastInstance.getMap(MAP_NAME).put(key, value);
工人具有一個無限循環(具有Thread.sleep(1000L);
內部超時),必須從地圖處理實體提出一些POJO到分佈式映射。現在我只是在這個循環中打印地圖大小。
現在是這個問題。我開始工人應用程序。然後,我同時啓動四個提交者(每個添加一個條目到地圖並終止它的工作)。但是,在所有提交者應用完成後,工作者應用會打印任意大小:有時它會檢測到只添加了一個條目,有時是兩個,有時是三個(實際上從未看過全部四個條目)。
這個簡單的流程有什麼問題?我在Hazelcast文檔中看到put()
方法是同步的,所以它保證在它返回後,將條目放置到分佈式映射中,並且被複制。但在我的實驗中似乎並不如此。
UPD(代碼)
發佈者:
public void submit(String key) {
Object mySerializableObject = ...
IMap<String, Object> map = hazelcastInstance.getMap(MAP_NAME);
map.putIfAbsent(key, mySerializableObject, TASK_TTL_IN_HOURS, TimeUnit.HOURS);
}
工人:
public void process() {
while (true) {
IMap<String, Object> map = hazelcastInstance.getMap(MAP_NAME);
System.out.println(map.size());
// Optional<Map.Entry<String, Object>> objectToProcess = getObjectToProcess();
// objectToProcess.ifPresent(objectToProcess-> processObject(id, objectToProcess));
try {
Thread.sleep(PAUSE);
} catch (InterruptedException e) {
LOGGER.error(e.getMessage(), e);
}
}
}
我註釋掉 「處理」 部分本身,因爲現在我只是想獲得一致的地圖狀態。上面的代碼每次打印不同的結果,例如:「4,3,1,1,1,1,1 ...」(因此它甚至可以看到4個提交的任務一會兒,但是然後它們消失) 。
UPD(日誌)
工人:
...
tasksMap.size() = 0
tasksMap.size() = 0
tasksMap.size() = 0
tasksMap.size() = 0
tasksMap.size() = 1
tasksMap.size() = 2
tasksMap.size() = 2
tasksMap.size() = 2
tasksMap.size() = 2
tasksMap.size() = 2
...
發佈者1:
Before: tasksMap.size() = 0
After: tasksMap.size() = 1
發佈者2:
Before: tasksMap.size() = 1
After: tasksMap.size() = 4
Submi tter 3:
Before: tasksMap.size() = 1
After: tasksMap.size() = 2
發佈4:
Before: tasksMap.size() = 3
After: tasksMap.size() = 4
IMap :: size方法是一種估計,無論如何它應該最終穩定下來。你能分享更多的代碼嗎? – noctarius
@noctarius,我已經更新了這個問題。 –
您的代碼是否使用嵌入式成員,並且在提交值後實際停止了嗎?我可以想象會員可以快速離開集羣,以滿足休假時的備份要求。 – noctarius