我使用的是Infinispan 6.0.2缓存,我的所有缓存条目都有一个可能在其生命周期内发生变化的失效日期。我使用Cache.replace
方法更新infinispan生命周期:
manager.begin();
Data current = cache.get(token);
Data copy = new Data(current);
update(copy);
validTokens.replace(token, copy, copy.getLifespan(), TimeUnit.MILLISECONDS);
manager.commit();
在观察到期后,没有按预期发生,我转储了缓存的内部数据结构,发现它的所有缓存实例都没有以相同的方式更新本地元数据。初始放置后对两个缓存都说明:
[{
"entry" : {
"key" : "2c90c80f-dcfc-4ab9-b1c5-ad7f253923b3",
"value" : {
[...]
},
"metadata" : {
"version" : {
"topologyId" : 2,
"version" : 1
},
"lifespan" : 86400000,
"maxIdle" : 86400000
},
"created" : false,
"lastUsed" : 1458213367042,
"expired" : false,
"null" : false,
"valid" : false,
"loaded" : false,
"removed" : false,
"changed" : false,
"evicted" : true
},
"hash" : 718741768,
"null" : false,
"valid" : false,
"loaded" : false,
"created" : false,
"removed" : false,
"changed" : false,
"evicted" : true,
"expired" : false
}
]
更换启动替换的节点上的条目后:
[{
"entry" : {
"key" : "2c90c80f-dcfc-4ab9-b1c5-ad7f253923b3",
"value" : {
[...]
},
"metadata" : {
"version" : {
"topologyId" : 2,
"version" : 2
},
"lifespan" : 86400000,
"maxIdle" : 86400000
},
"created" : false,
"lastUsed" : 1458213394345,
"expired" : false,
"null" : false,
"valid" : false,
"loaded" : false,
"removed" : false,
"changed" : false,
"evicted" : true
},
"hash" : 718741768,
"null" : false,
"valid" : false,
"loaded" : false,
"created" : false,
"removed" : false,
"changed" : false,
"evicted" : true,
"expired" : false
}
]
第二个缓存实际上已更改:
[{
"entry" : {
"key" : "2c90c80f-dcfc-4ab9-b1c5-ad7f253923b3",
"value" : {
[...]
},
"metadata" : {
"version" : {
"topologyId" : 2,
"version" : 2
},
"lifespan" : 57314,
"maxIdle" : 57314
},
"created" : false,
"lastUsed" : 1458213394349,
"expired" : false,
"null" : false,
"loaded" : false,
"valid" : false,
"changed" : false,
"removed" : false,
"evicted" : true
},
"hash" : 1057353610,
"null" : false,
"loaded" : false,
"valid" : false,
"created" : false,
"changed" : false,
"removed" : false,
"evicted" : true,
"expired" : false
}
]
因此只在第二个缓存上发生过期。
使用的缓存配置:
builder
.clustering().cacheMode(CacheMode.REPL_SYNC)
.transaction().transactionMode(TransactionMode.TRANSACTIONAL)
.lockingMode(LockingMode.OPTIMISTIC).locking().isolationLevel(IsolationLevel.REPEATABLE_READ)
.writeSkewCheck(true).versioning().enable()
.scheme(VersioningScheme.SIMPLE)
.expiration().enableReaper().wakeUpInterval(1, TimeUnit.MINUTES);