【发布时间】:2016-09-12 11:36:43
【问题描述】:
我正在使用休眠二级缓存(使用 spring 配置)使用 Hazelcast,而第一台服务器向第二台服务器发送驱逐消息。第二台服务器上的驱逐时间戳包括实际驱逐时间 + 1 小时。
这会导致第二台服务器丢失缓存并在接下来的一小时内或直到本地缓存(来自第二台服务器)被驱逐之前对数据库运行查询。
在查看版本 3.6.2 实现时,1 小时间隔是由于 com.hazelcast.hibernate.HazelcastTimestamper下的getTimeout函数
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 实际上被添加到驱逐消息时间戳中,导致缓存时间戳有问题
是我遗漏了什么还是实际逻辑非常有问题? 有没有人真正有一个使用休眠 2 级的分布式服务器的工作配置,它实际上按预期工作?
【问题讨论】:
标签: hazelcast