2016-05-16 1 views
1

Я работаю с Hazelcast, используя спящий кэш второго уровня (настроенный с использованием пружины), а первый сервер отправляет сообщение о выселении на второй сервер. отметка времени выселения на втором сервере включает фактическое время выселения + 1 час.Распределенный кеш с выездом 2-го уровня гибернации

Это приводит к тому, что 2-й сервер потеряет свой кеш и запускает запросы к БД в течение следующего часа или до тех пор, пока локальный кеш (со второго сервера) не будет выведен.

Хотя глядя на версии 3.6.2 реализации 1-часового интервала вызывает вследствие функции getTimeout под com.hazelcast.hibernate.HazelcastTimestamper

public static int getTimeout(HazelcastInstance instance, String regionName) { 
     try { 
      final MapConfig cfg = instance.getConfig().findMapConfig(regionName); 
      if (cfg.getTimeToLiveSeconds() > 0) { 
       // TTL in ms 
       return cfg.getTimeToLiveSeconds() * SEC_TO_MS; 
      } 
     } catch (UnsupportedOperationException e) { 
      // HazelcastInstance is instance of HazelcastClient. 
      Logger.getLogger(HazelcastTimestamper.class).finest(e); 
     } 
     return CacheEnvironment.getDefaultCacheTimeoutInMillis(); 
    } 

В getDefaultCacheTimeoutInMillis вернуть 360

Хотя mapConfig .getTimeToLiveSeconds() == 0

AbstractHazelcastRegion получить тайм-аут

this.timeout = HazelcastTimestamper.getTimeout(instance, regionName); 

на org.hibernate.cache.spi.UpdateTimestampsCache

public void preInvalidate(Serializable[] spaces, SessionImplementor session) throws CacheException { 
    final boolean stats = factory != null && factory.getStatistics().isStatisticsEnabled(); 

    **final Long ts = region.nextTimestamp() + region.getTimeout();** 

    for (Serializable space : spaces) { 
     if (DEBUG_ENABLED) { 
      LOG.debugf("Pre-invalidating space [%s], timestamp: %s", space, ts); 
     } 

     try { 
      session.getEventListenerManager().cachePutStart(); 

      //put() has nowait semantics, is this really appropriate? 
      //note that it needs to be async replication, never local or sync 
      region.put(space, ts); 
     } 
     finally { 
      session.getEventListenerManager().cachePutEnd(); 
     } 

     if (stats) { 
      factory.getStatisticsImplementor().updateTimestampsCachePut(); 
     } 
    } 
} 

Во время выселения сообщения выселения таймаута = 360 * 1000 фактически добавляются в метку времени сообщения о выселении в результате с проблемной кэш-временной меткой

Я что-то упустил или реальная логика очень проблематична? У кого-нибудь действительно есть рабочая конфигурация для распределенных серверов, использующих hibernate 2-й уровень, который фактически работает так, как ожидалось?

ответ

1

Hibernate вызовет preInvalidate в начале транзакции для обновлений/вставок, а затем, как только транзакция будет выполнена, он вызовет UpdateTimestampsCache.invalidate (...). Это приведет к тому, что время lastUpdate вернется к текущему времени.

Таким образом, во время выполнения транзакции любые запросы в затронутых пространствах не будут обновлены, но как только транзакция закончится, будет установлено время lastUpdate, и будущие запросы выбора могут быть кэшированы.

Это можно увидеть в журналах, если вы установили регистрацию для org.hibernate в DEBUG. Журналы будут выглядеть следующим образом:

DEBUG [UpdateTimestampsCache] Pre-invalidating space [<affected query spaces>], timestamp: <approximate current time + timeout> 
... your transaction here ... 
DEBUG [AbstractTransactionImpl] committing 
DEBUG [JdbcTransaction] committed JDBC Connection 
DEBUG [JdbcTransaction] re-enabling autocommit 
DEBUG [UpdateTimestampsCache] Invalidating space [<affected query spaces>], timestamp: <approximate current time> 

я заметил, что иногда это второе «утратившими силу пространство» не произойдет, если сделка не совершала (возможная ошибка кодирования), оставляя кэш в плохом состоянии, в котором lastUpdate (время ожидания + тайм-аут кеша), в результате чего все запросы на затронутые пространства не будут обновляться до тех пор, пока это не будет достигнуто.