perf(X-Pack): 集群环境中redis缓存清除机制

This commit is contained in:
fit2cloud-chenyw 2024-10-14 17:48:20 +08:00
parent 6ba6fba4ca
commit c4fe12f71f
2 changed files with 73 additions and 1 deletions

View File

@ -1,10 +1,13 @@
package io.dataease.cache.impl;
import io.dataease.cache.DECacheService;
import io.dataease.utils.CommonBeanFactory;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;
@ -20,11 +23,21 @@ public class RedisCacheImpl implements DECacheService {
@Resource
private RedisTemplate redisTemplate;
private static CacheManager cacheManager;
private static CacheManager getCacheManager() {
if (cacheManager == null)
cacheManager = CommonBeanFactory.getBean(CacheManager.class);
return cacheManager;
}
private ValueOperations ops() {
ValueOperations valueOperations = redisTemplate.opsForValue();
return valueOperations;
}
@Override
public void put(String cacheName, String key, Object value, Long expTime, TimeUnit unit) {
ValueOperations ops = ops();
@ -57,7 +70,10 @@ public class RedisCacheImpl implements DECacheService {
@Override
public void keyRemove(String cacheName, String key) {
redisTemplate.delete(cacheName + SEPARATOR + key);
// redisTemplate.delete(cacheName + SEPARATOR + key);
Cache cache = getCacheManager().getCache(cacheName);
if (null == cache) return;
cache.evictIfPresent(key);
}
@PostConstruct

View File

@ -0,0 +1,56 @@
package io.dataease.listener;
import io.dataease.utils.LogUtil;
import jakarta.annotation.Resource;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.core.annotation.Order;
import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.stereotype.Component;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
@ConditionalOnExpression("'${spring.cache.type}'.equals('redis')")
@Component
@Order(100)
public class RedisCacheListener implements ApplicationListener<ApplicationReadyEvent> {
@Resource
private RedisTemplate redisTemplate;
@Override
public void onApplicationEvent(ApplicationReadyEvent event) {
try {
deleteKeysContainingString(redisTemplate, "de_v2_");
} catch (Exception e) {
LogUtil.error(e.getMessage(), e);
}
}
public void deleteKeysContainingString(RedisTemplate<String, String> redisTemplate, String searchString) {
// 扫描所有的key
ScanOptions scanOptions = ScanOptions.scanOptions().match("*" + searchString + "*").count(1000).build();
Cursor<byte[]> cursor = redisTemplate.getConnectionFactory()
.getConnection()
.scan(scanOptions);
List<byte[]> keysToDelete = new ArrayList<>();
while (cursor.hasNext()) {
keysToDelete.add(cursor.next());
}
if (!keysToDelete.isEmpty()) {
List<String> keys = new ArrayList<>(keysToDelete.size());
for (byte[] key : keysToDelete) {
keys.add(new String(key, StandardCharsets.UTF_8));
}
redisTemplate.delete(keys);
}
}
}