Hazelcast 具有hibernate二级逐出的分布式缓存

Hazelcast 具有hibernate二级逐出的分布式缓存,hazelcast,Hazelcast,我正在使用hibernate二级缓存(用spring配置)与Hazelcast一起工作,同时第一台服务器向第二台服务器发送一条退出消息。第二台服务器上的逐出时间戳包括实际逐出时间+1小时 这会导致第二台服务器丢失其缓存,并在下一个小时或直到本地缓存(来自第二台服务器)被逐出之前向DB as运行查询 在查看版本3.6.2实现时,1小时间隔是由于 com.hazelcast.hibernate.hazelcast时间戳下的getTimeout函数 public static int getTimeo

我正在使用hibernate二级缓存(用spring配置)与Hazelcast一起工作,同时第一台服务器向第二台服务器发送一条退出消息。第二台服务器上的逐出时间戳包括实际逐出时间+1小时

这会导致第二台服务器丢失其缓存,并在下一个小时或直到本地缓存(来自第二台服务器)被逐出之前向DB as运行查询

在查看版本3.6.2实现时,1小时间隔是由于 com.hazelcast.hibernate.hazelcast时间戳下的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.getTimeSeconds()==0

AbstractHazelCasterigon获取超时

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第二级的分布式服务器的工作配置,并且该配置实际按预期工作?

hibernate将在事务开始时调用preInvalidate进行更新/插入,然后一旦事务完成,它将调用UpdateTimestampsCache.invalidate(…)。这将把lastUpdate时间设置回当前时间

因此,在事务运行时,对受影响空间的任何查询都不会是最新的,但一旦事务超过上次更新时间,将设置该查询,并可以缓存将来的select查询

如果将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>
DEBUG[UpdateTimestampsCache]预失效空间[],时间戳:
... 您在这里的交易。。。
调试[AbstractTransactionImpl]提交
调试[JdbcTransaction]提交的JDBC连接
调试[JdbcTransaction]重新启用自动提交
调试[UpdateTimestampsCache]使空间[]无效,时间戳:
我观察到,如果事务未提交(可能的编码错误),则第二个“无效空间”有时会失败,使缓存处于lastUpdate设置为的错误状态(未来时间+缓存超时设置),导致在达到该时间之前,受影响空间上的所有查询都不是最新的