Блокировка ключа в кластере hazelcast

Я пишу распределенное приложение, используя Hazelcast (стандарт JCache) для кэширования.

У меня есть вариант использования, когда я должен заблокировать определенный ключ в кластере, чтобы предотвратить вызовы во время обновления.

  1. thread1: получить item1 для изменения конфигурации (поставить блокировку)
  2. thread2: получить item1 для обновления.
  3. thread2: поместите item1 с обновлением и новой меткой времени.
  4. thread1: поместите item1 со старым значением и отметкой времени

Я знаю, что в EhCache есть что-то очень похожее, оно называется «acquireReadLockOnKey» (ключ объекта).

Как я могу добиться такой блокировки с помощью JCache и/или Hazelcast?


person Forin    schedule 01.06.2017    source источник


Ответы (2)


Я бы предложил использовать аналогичные операции CAS (Compare And Set) (например, ConcurrentMap::replace) и использовать оптимистичный шаблон блокировки, который сам по себе не является реальной блокировкой.

while(true) {
  // Get the old value
  T oldValue = map.get(key);
  // Create the new value based on the "known old state"
  T newValue = createNewValue(oldValue);
  // Try to atomically exchange to the new value, if oldValue is still valid
  if (map.replace(key, oldValue, newValue) break;
  // If oldValue isn't valid anymore, retry
}

В большинстве ситуаций, когда нет высокой конкуренции, это лучшая альтернатива реальной блокировке. Он решает большинство проблем чтения-изменения-записи и не требует развертывания/доступности классов EntryProcessor в кластере.

person noctarius    schedule 01.06.2017

Посмотрите на процессор ввода, который выполняет операции обновления записей кэша атомарным и безблокировочным образом.

person Mikhail Baksheev    schedule 01.06.2017
comment
Речь идет о EntryProcessor от JCache? Работает ли он правильно в распределенном кеше? - person Forin; 01.06.2017
comment
В нашем проекте мы используем входные процессоры для Hazelcast IMap, и мы не сталкивались с проблемами параллелизма. Входной процессор — это хороший способ изменить данные в распределенной среде. Процессор входа выполняется по владельцам ключей, что позволяет добиться атомарности и избежать пересылки данных по сети. - person Mikhail Baksheev; 01.06.2017
comment
Оба ответа заслуживают внимания; если у вас низкая конкуренция, вы можете использовать CAS, как описано выше. В противном случае вы можете использовать JCache EntryProcessor, его контракт гарантирует, что он будет выполнен атомарно по ключу. Вам просто нужно убедиться, что ваш код EntryProcessor развернут на всех членах кластера Hazelcast. - person Vassilis Bekiaris; 02.06.2017