Hibernate Hazelcast事件队列重载更新缓存区域默认更新时间戳区域
我最近添加了一个新的工作线程,它将队列排入不同的表中,然后退出。在跑步时,我看到了很多follow日志信息Hibernate Hazelcast事件队列重载更新缓存区域默认更新时间戳区域,hibernate,hazelcast,Hibernate,Hazelcast,我最近添加了一个新的工作线程,它将队列排入不同的表中,然后退出。在跑步时,我看到了很多follow日志信息 2021-05-16 11:25:19.496 WARN 18 --- [Thread-1] com.hazelcast.spi.EventService : [127.0.0.1]:5701 [dev] [3.12.6] EventQueue overloaded! TopicEvent{name='default-update-timestamps-region'
2021-05-16 11:25:19.496 WARN 18 --- [Thread-1] com.hazelcast.spi.EventService : [127.0.0.1]:5701 [dev] [3.12.6] EventQueue overloaded! TopicEvent{name='default-update-timestamps-region', publishTime=1621164319495, publisherAddress=[172.18.0.4]:5701} failed to publish to hz:impl:topicService:default-update-timestamps-region
表中没有缓存我正在读取/写入的实体,所以我想知道为什么缓存会在这个线程上刷新,更不用说它是如何突破这个事件队列的限制的了
我还没有更改配置的默认值(使用Hazelcast 3.12.6),所以我很困惑这怎么会如此迅速地使缓存水合
请参阅下面我的新服务的粗略伪代码
private void processForever() {
threadRef = Thread.currentThread();
synchronized (syncObject) {
//notify init that we're good to continue
syncObject.notifyAll();
}
while (threadRef == Thread.currentThread()) {
boolean foundWork = false;
try {
foundWork = process();
} catch (Exception e) {
log.debug("stack", e);
}
long sleep = foundWork ? 1000 : 60000;
try {
Thread.sleep(sleep);
} catch (InterruptedException e) {
}
}
}
private boolean process() {
try {
// N.B this attempts to grab a shared lock on the current tenant and skips of already taken
return dataGrid.runExclusiveForCurrentTenantOrSkip(LockName.PROCESS, this::processInternal).orElse(true);
} catch (Exception ex) {
log.error("error", ex);
return true;
}
}
private boolean processInternal() {
Long maxSid = sourceQueueRepo.findMaxSid();
if (maxSid == null) {
return false;
}
Set<Worker> agents = workerRepo.findAllWorkers();
queueWork(maxSid, agents);
return true;
}
public void queueWork(Long maxId, Set<Worker> workers) {
sourceQueueRepo.dedupeByMaxSid(maxId);
List<SourceQueue> batch = sourceQueueRepo.findAllBySidLessThanEqual(maxId);
Map<Long, List<SourceQueue>> batched = // Redacted
for (Worker worker : workers) {
// Method 'batchInsert' calls a save query (transactional)
batchInsert(worker, batched.getOrDefault(Type.TYPE_1, new HashMap<>()));
batchInsert(worker, batched.getOrDefault(Type.TYPE_2, new HashMap<>()));
batchInsert(worker, batched.getOrDefault(Type.TYPE_3, new HashMap<>()));
}
sourceQueueRepo.deleteByMaxId(maxId);
}
private void processForever(){
threadRef=Thread.currentThread();
已同步(同步对象){
//通知init我们可以继续
syncObject.notifyAll();
}
while(threadRef==Thread.currentThread()){
布尔foundWork=false;
试一试{
foundWork=过程();
}捕获(例外e){
调试(“堆栈”,e);
}
长睡眠=基础工作?1000:60000;
试一试{
睡眠;
}捕捉(中断异常e){
}
}
}
私有布尔进程(){
试一试{
//注意:此操作试图获取当前租户的共享锁,并跳过已获取的共享锁
返回dataGrid.runExclusiveForcurrentTenantTorSkip(LockName.PROCESS,this::processInternal).orElse(true);
}捕获(例外情况除外){
日志错误(“错误”,ex);
返回true;
}
}
私有布尔processInternal(){
Long maxSid=sourceQueueRepo.findMaxSid();
if(maxSid==null){
返回false;
}
Set agents=workerRepo.findAllWorkers();
队列工作(maxSid、代理);
返回true;
}
public void queueWork(Long maxId,Set worker){
sourceQueueRepo.dedupeByMaxSid(maxId);
List batch=sourceQueueRepo.findAllBySidLessThanEqual(maxId);
映射批处理=//已编辑
用于(工人:工人){
//方法“batchInsert”调用保存查询(事务性)
batchInsert(worker,batched.getOrDefault(Type.Type_1,new HashMap());
batchInsert(worker,batched.getOrDefault(Type.Type_2,new HashMap());
batchInsert(worker,batched.getOrDefault(Type.Type_3,new HashMap());
}
sourceQueueRepo.deleteByMaxId(maxId);
}
注意
- 每个查询都是事务性的,其目标是保持数据库事务简短,因为目标表上的其他线程可能存在争用
- 插入此队列的代码在此新线程上调用中断,以确保其正在排空新队列。有多个线程调用此函数,因此重载下的停机时间很少
@Modifying
查询,我选择使用NativeQuery对象,并通过addSynchronizedEntityClass
指定要使其失效的缓存项
例如,
返回em.createNativeQuery(“DELETE FROM dbo.SourceQueue,其中id来自我所看到的-运行上述代码似乎正在更新所有实体的缓存(偶尔会看到此日志消息中列出的一些实体),对于此操作,我不依赖任何缓存实体或查询
return em.createNativeQuery("DELETE FROM dbo.SourceQueue WHERE id <= :id")
.unwrap(NativeQuery.class)
.setParameter("id", id)
.addSynchronizedEntityClass(SourceQueue.class)
.executeUpdate();