2015-11-10 4 views
0

Вот наш вариантом использования:Распределенного использование Кэширования случая с Hazelcast

У нас есть 4-8 узлов, которые реализуют распределенный кэш hazelcast Каждых узлы могут получить несколько сообщений через JMS, которые имеют один и тот же ключ транзакции, мы добавим все сообщения в кеше с парой ключевого объекта, где объект является списком элементов, подлежащих кэшированию.

Агрегация выполняется через apache-camel, где у нас есть агрегатор, который работает на 300 МИЛЛИЗЕЦ. . После 300 МИЛЛИЗЕЦ мы закрываем агрегирования и выселить все элементы из кеша, соответствующие ключу транзакции, и программно их заполнить. Роль Hazelcast является только для сбора сообщений в карте кэша и сохранить все узлы синхронизированы где-так как все узлы знают, какие элементы находятся в кэше Проблемы сценарии:

  1. узел 1 добавляет item1 в кэше для транзакции -key = tx1 в 17: 01: 01: 100 - и мы предполагаем, что hazelcast передает эту информацию другим узлам, так что все узлы получают копию кэшированного элемента.
  2. Узел 2 добавляет элемент item2 в кэш для транзакционной клавиши = tx1 в 17: 01: 01: 105
  3. Узел 3 добавляет элемент 3 в кэш для транзакционной клавиши = tx1 в 17: 01: 01: 350 Теперь предположим, что на 17: 01: 01: 400 мы стараемся, чтобы закрыть окно агрегации и программно выселить всех элементов из кэша с помощью транзакции ключ = TX1

проблема заключается в том, что node1, node2 знать о item1 и item2, поскольку они успели синхронизировать свои элементы кэша. НО узел3 добавил элемент3 настолько поздно, что node1 и node2 не знают о item3 в 17: 01: 01: 400. Предположим, что мы вытаскиваем выселение в 17: 01: 01: 400 из узла1, который не знает о item3, и он даст нам объект только с двумя элементами. Затем node1 будет транслировать всем, чтобы выселить все элементы кэша для транзакций, ключ = TX1 в ответ на что все узлы будут очищать свой кэш для транзакции ключа = TX1 Это приводит к потерянному пункту (ст.3)

признателен за любую помощь.

+0

Я попытался ответить на ваш вопрос ниже. Если вам нужна дополнительная помощь, добавьте более релевантные детали к вашему вопросу. – Dinesh

ответ

0

Я полагаю, ваш IMap разработан следующим образом :

IMap<TransactionKey,List<CacheItem>> transactionMessagesMap.

Проблема заключается в том, что node1, node2 знать о item1 и item2, так как они успели синхронизировать свои элементы кэша. BUT node3 добавил item3 так поздно , что node1 и node2 не знают о item3 в 17: 01: 01: 400.

Как вы помещаете запись в 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 в соответствии с вашим прецедентом. Надеюсь это поможет.

Смежные вопросы