Skip to content

Commit dd7e98e

Browse files
author
qiujiayu
committed
Redis使用lua 进行批量删除缓存
1 parent 35cf9ab commit dd7e98e

File tree

4 files changed

+59
-43
lines changed

4 files changed

+59
-43
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ AutoLoadHandler(自动加载处理器)主要做的事情:当缓存即将
3434
<dependency>
3535
<groupId>com.github.qiujiayu</groupId>
3636
<artifactId>autoload-cache</artifactId>
37-
<version>1.5</version>
37+
<version>1.6</version>
3838
</dependency>
3939

4040

pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<modelVersion>4.0.0</modelVersion>
44
<groupId>com.github.qiujiayu</groupId>
55
<artifactId>autoload-cache</artifactId>
6-
<version>1.5</version>
6+
<version>1.6</version>
77
<packaging>jar</packaging>
88
<name>AutoLoadCache</name>
99
<description>User Spring AOP and annotation to do with cache.</description>
@@ -12,7 +12,7 @@
1212
<license>
1313
<name>The Apache Software License, Version 2.0</name>
1414
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
15-
<distribution>repo</distribution>
15+
<distribution>The Apache Software License, Version 2.0</distribution>
1616
<comments>A business-friendly OSS license</comments>
1717
</license>
1818
</licenses>

src/main/java/com/jarvis/cache/redis/CachePointCut.java

Lines changed: 42 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,13 @@
22

33
import java.io.Serializable;
44
import java.util.List;
5-
import java.util.Set;
65

76
import org.apache.log4j.Logger;
87
import org.springframework.dao.DataAccessException;
98
import org.springframework.data.redis.connection.RedisConnection;
9+
import org.springframework.data.redis.connection.ReturnType;
1010
import org.springframework.data.redis.core.RedisCallback;
1111
import org.springframework.data.redis.core.RedisTemplate;
12-
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
1312

1413
import com.jarvis.cache.AbstractCacheManager;
1514
import com.jarvis.cache.AutoLoadHandler;
@@ -20,13 +19,20 @@
2019
/**
2120
* 缓存切面,用于拦截数据并调用Redis进行缓存
2221
* @author jiayu.qiu
22+
* @see com.jarvis.cache.redis.ShardedCachePointCut
23+
* @deprecated 建议使用com.jarvis.cache.redis.ShardedCachePointCut
2324
*/
25+
@Deprecated
2426
public class CachePointCut extends AbstractCacheManager<Serializable> {
2527

2628
private static final Logger logger=Logger.getLogger(CachePointCut.class);
2729

2830
private List<RedisTemplate<String, Serializable>> redisTemplateList;
2931

32+
private StringRedisSerializer keySerializer=new StringRedisSerializer();
33+
34+
private JdkSerializationRedisSerializer valSerializer=new JdkSerializationRedisSerializer();
35+
3036
public CachePointCut(AutoLoadConfig config) {
3137
super(config);
3238
}
@@ -43,7 +49,7 @@ public RedisTemplate<String, Serializable> getRedisTemplate(String key) {
4349
@Override
4450
public void setCache(final String cacheKey, final CacheWrapper<Serializable> result, final int expire) {
4551
if(cacheKey.indexOf("*") != -1 || cacheKey.indexOf("?") != -1) {
46-
throw new java.lang.RuntimeException("cacheKey:" + cacheKey + "; has '*' or '?'");
52+
throw new RuntimeException("cacheKey:" + cacheKey + "; has '*' or '?'");
4753
}
4854
try {
4955
result.setLastLoadTime(System.currentTimeMillis());
@@ -52,12 +58,15 @@ public void setCache(final String cacheKey, final CacheWrapper<Serializable> res
5258

5359
@Override
5460
public Object doInRedis(RedisConnection connection) throws DataAccessException {
55-
byte[] key=redisTemplate.getStringSerializer().serialize(cacheKey);
56-
JdkSerializationRedisSerializer serializer=(JdkSerializationRedisSerializer)redisTemplate.getValueSerializer();
57-
byte[] val=serializer.serialize(result);
58-
// connection.set(key, val);
59-
// connection.expire(key, expire);
60-
connection.setEx(key, expire, val);
61+
62+
try {
63+
byte[] key=keySerializer.serialize(cacheKey);
64+
byte[] val=valSerializer.serialize(result);
65+
connection.setEx(key, expire, val);
66+
} catch(Exception ex) {
67+
logger.error(ex.getMessage(), ex);
68+
}
69+
6170
return null;
6271
}
6372
});
@@ -75,15 +84,20 @@ public CacheWrapper<Serializable> get(final String cacheKey) {
7584

7685
@Override
7786
public CacheWrapper<Serializable> doInRedis(RedisConnection connection) throws DataAccessException {
78-
byte[] key=redisTemplate.getStringSerializer().serialize(cacheKey);
87+
88+
byte[] key=keySerializer.serialize(cacheKey);
7989

8090
byte[] value=connection.get(key);
8191
if(null != value && value.length > 0) {
82-
JdkSerializationRedisSerializer serializer=
83-
(JdkSerializationRedisSerializer)redisTemplate.getValueSerializer();
84-
@SuppressWarnings("unchecked")
85-
CacheWrapper<Serializable> res=(CacheWrapper<Serializable>)serializer.deserialize(value);
86-
return res;
92+
93+
try {
94+
@SuppressWarnings("unchecked")
95+
CacheWrapper<Serializable> res=(CacheWrapper<Serializable>)valSerializer.deserialize(value);
96+
return res;
97+
} catch(Exception ex) {
98+
logger.error(ex.getMessage(), ex);
99+
}
100+
87101
}
88102
return null;
89103
}
@@ -137,26 +151,24 @@ public void delete(final String cacheKey) {
137151
return;
138152
}
139153
final AutoLoadHandler<Serializable> autoLoadHandler=this.getAutoLoadHandler();
154+
String params[]=new String[]{cacheKey};
155+
final byte[][] p=new byte[params.length][];
156+
for(int i=0; i < params.length; i++) {
157+
p[i]=keySerializer.serialize(params[i]);
158+
}
140159
if(cacheKey.indexOf("*") != -1 || cacheKey.indexOf("?") != -1) {
160+
final StringBuilder script=new StringBuilder();
161+
script.append("local keys = redis.call('keys', KEYS[1]);\n");
162+
script.append("if(not keys or #keys == 0) then \n return nil; \n end \n");
163+
script.append("redis.call('del', unpack(keys)); \n return keys;");
164+
141165
for(final RedisTemplate<String, Serializable> redisTemplate: redisTemplateList) {
142166
redisTemplate.execute(new RedisCallback<Object>() {
143167

144168
@Override
145169
public Object doInRedis(RedisConnection connection) throws DataAccessException {
146-
byte[] key=redisTemplate.getStringSerializer().serialize(cacheKey);
147-
Set<byte[]> keys=connection.keys(key);
148-
if(null != keys && keys.size() > 0) {
149-
byte[][] keys2=new byte[keys.size()][];
150-
keys.toArray(keys2);
151-
connection.del(keys2);
152-
153-
for(byte[] tmp: keys2) {
154-
JdkSerializationRedisSerializer serializer=
155-
(JdkSerializationRedisSerializer)redisTemplate.getValueSerializer();
156-
String tmpKey=(String)serializer.deserialize(tmp);
157-
autoLoadHandler.resetAutoLoadLastLoadTime(tmpKey);
158-
}
159-
}
170+
byte[] scriptBytes=keySerializer.serialize(script.toString());
171+
connection.eval(scriptBytes, ReturnType.STATUS, 1, p);
160172
return null;
161173
}
162174
});
@@ -167,8 +179,7 @@ public Object doInRedis(RedisConnection connection) throws DataAccessException {
167179

168180
@Override
169181
public Object doInRedis(RedisConnection connection) throws DataAccessException {
170-
byte[] key=redisTemplate.getStringSerializer().serialize(cacheKey);
171-
182+
byte[] key=keySerializer.serialize(cacheKey);
172183
connection.del(key);
173184
autoLoadHandler.resetAutoLoadLastLoadTime(cacheKey);
174185
return null;

src/main/java/com/jarvis/cache/redis/ShardedCachePointCut.java

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import java.io.Serializable;
44
import java.util.Collection;
5-
import java.util.Set;
5+
import java.util.List;
66

77
import org.apache.log4j.Logger;
88

@@ -128,16 +128,21 @@ public void delete(final String cacheKey) {
128128
try {
129129
shardedJedis=shardedJedisPool.getResource();
130130
Collection<Jedis> list=shardedJedis.getAllShards();
131+
StringBuilder script=new StringBuilder();
132+
script.append("local keys = redis.call('keys', KEYS[1]);\n");
133+
script.append("if(not keys or #keys == 0) then \n return nil; \n end \n");
134+
script.append("redis.call('del', unpack(keys)); \n return keys;");
131135
for(Jedis jedis: list) {
132-
Set<byte[]> keys=jedis.keys(keySerializer.serialize(cacheKey));
133-
if(null != keys && keys.size() > 0) {
134-
byte[][] keys2=new byte[keys.size()][];
135-
keys.toArray(keys2);
136-
jedis.del(keys2);
137-
for(byte[] tmp: keys2) {
138-
String tmpKey=(String)keySerializer.deserialize(tmp);
139-
autoLoadHandler.resetAutoLoadLastLoadTime(tmpKey);
136+
try {
137+
@SuppressWarnings("unchecked")
138+
List<String> keys=(List<String>)jedis.eval(script.toString(), 1, cacheKey);
139+
if(null != keys && keys.size() > 0) {
140+
for(String tmpKey: keys) {
141+
autoLoadHandler.resetAutoLoadLastLoadTime(tmpKey);
142+
}
140143
}
144+
} catch(Exception ex) {
145+
logger.error(ex.getMessage(), ex);
141146
}
142147
}
143148
} catch(Exception ex) {

0 commit comments

Comments
 (0)