Skip to content

Commit

Permalink
Redis使用lua 进行批量删除缓存
Browse files Browse the repository at this point in the history
  • Loading branch information
qiujiayu committed Apr 22, 2015
1 parent 35cf9ab commit dd7e98e
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 43 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ AutoLoadHandler(自动加载处理器)主要做的事情:当缓存即将
<dependency>
<groupId>com.github.qiujiayu</groupId>
<artifactId>autoload-cache</artifactId>
<version>1.5</version>
<version>1.6</version>
</dependency>


Expand Down
4 changes: 2 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.github.qiujiayu</groupId>
<artifactId>autoload-cache</artifactId>
<version>1.5</version>
<version>1.6</version>
<packaging>jar</packaging>
<name>AutoLoadCache</name>
<description>User Spring AOP and annotation to do with cache.</description>
Expand All @@ -12,7 +12,7 @@
<license>
<name>The Apache Software License, Version 2.0</name>
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
<distribution>repo</distribution>
<distribution>The Apache Software License, Version 2.0</distribution>
<comments>A business-friendly OSS license</comments>
</license>
</licenses>
Expand Down
73 changes: 42 additions & 31 deletions src/main/java/com/jarvis/cache/redis/CachePointCut.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,13 @@

import java.io.Serializable;
import java.util.List;
import java.util.Set;

import org.apache.log4j.Logger;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.ReturnType;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;

import com.jarvis.cache.AbstractCacheManager;
import com.jarvis.cache.AutoLoadHandler;
Expand All @@ -20,13 +19,20 @@
/**
* 缓存切面,用于拦截数据并调用Redis进行缓存
* @author jiayu.qiu
* @see com.jarvis.cache.redis.ShardedCachePointCut
* @deprecated 建议使用com.jarvis.cache.redis.ShardedCachePointCut
*/
@Deprecated
public class CachePointCut extends AbstractCacheManager<Serializable> {

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

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

private StringRedisSerializer keySerializer=new StringRedisSerializer();

private JdkSerializationRedisSerializer valSerializer=new JdkSerializationRedisSerializer();

public CachePointCut(AutoLoadConfig config) {
super(config);
}
Expand All @@ -43,7 +49,7 @@ public RedisTemplate<String, Serializable> getRedisTemplate(String key) {
@Override
public void setCache(final String cacheKey, final CacheWrapper<Serializable> result, final int expire) {
if(cacheKey.indexOf("*") != -1 || cacheKey.indexOf("?") != -1) {
throw new java.lang.RuntimeException("cacheKey:" + cacheKey + "; has '*' or '?'");
throw new RuntimeException("cacheKey:" + cacheKey + "; has '*' or '?'");
}
try {
result.setLastLoadTime(System.currentTimeMillis());
Expand All @@ -52,12 +58,15 @@ public void setCache(final String cacheKey, final CacheWrapper<Serializable> res

@Override
public Object doInRedis(RedisConnection connection) throws DataAccessException {
byte[] key=redisTemplate.getStringSerializer().serialize(cacheKey);
JdkSerializationRedisSerializer serializer=(JdkSerializationRedisSerializer)redisTemplate.getValueSerializer();
byte[] val=serializer.serialize(result);
// connection.set(key, val);
// connection.expire(key, expire);
connection.setEx(key, expire, val);

try {
byte[] key=keySerializer.serialize(cacheKey);
byte[] val=valSerializer.serialize(result);
connection.setEx(key, expire, val);
} catch(Exception ex) {
logger.error(ex.getMessage(), ex);
}

return null;
}
});
Expand All @@ -75,15 +84,20 @@ public CacheWrapper<Serializable> get(final String cacheKey) {

@Override
public CacheWrapper<Serializable> doInRedis(RedisConnection connection) throws DataAccessException {
byte[] key=redisTemplate.getStringSerializer().serialize(cacheKey);

byte[] key=keySerializer.serialize(cacheKey);

byte[] value=connection.get(key);
if(null != value && value.length > 0) {
JdkSerializationRedisSerializer serializer=
(JdkSerializationRedisSerializer)redisTemplate.getValueSerializer();
@SuppressWarnings("unchecked")
CacheWrapper<Serializable> res=(CacheWrapper<Serializable>)serializer.deserialize(value);
return res;

try {
@SuppressWarnings("unchecked")
CacheWrapper<Serializable> res=(CacheWrapper<Serializable>)valSerializer.deserialize(value);
return res;
} catch(Exception ex) {
logger.error(ex.getMessage(), ex);
}

}
return null;
}
Expand Down Expand Up @@ -137,26 +151,24 @@ public void delete(final String cacheKey) {
return;
}
final AutoLoadHandler<Serializable> autoLoadHandler=this.getAutoLoadHandler();
String params[]=new String[]{cacheKey};
final byte[][] p=new byte[params.length][];
for(int i=0; i < params.length; i++) {
p[i]=keySerializer.serialize(params[i]);
}
if(cacheKey.indexOf("*") != -1 || cacheKey.indexOf("?") != -1) {
final StringBuilder script=new StringBuilder();
script.append("local keys = redis.call('keys', KEYS[1]);\n");
script.append("if(not keys or #keys == 0) then \n return nil; \n end \n");
script.append("redis.call('del', unpack(keys)); \n return keys;");

for(final RedisTemplate<String, Serializable> redisTemplate: redisTemplateList) {
redisTemplate.execute(new RedisCallback<Object>() {

@Override
public Object doInRedis(RedisConnection connection) throws DataAccessException {
byte[] key=redisTemplate.getStringSerializer().serialize(cacheKey);
Set<byte[]> keys=connection.keys(key);
if(null != keys && keys.size() > 0) {
byte[][] keys2=new byte[keys.size()][];
keys.toArray(keys2);
connection.del(keys2);

for(byte[] tmp: keys2) {
JdkSerializationRedisSerializer serializer=
(JdkSerializationRedisSerializer)redisTemplate.getValueSerializer();
String tmpKey=(String)serializer.deserialize(tmp);
autoLoadHandler.resetAutoLoadLastLoadTime(tmpKey);
}
}
byte[] scriptBytes=keySerializer.serialize(script.toString());
connection.eval(scriptBytes, ReturnType.STATUS, 1, p);
return null;
}
});
Expand All @@ -167,8 +179,7 @@ public Object doInRedis(RedisConnection connection) throws DataAccessException {

@Override
public Object doInRedis(RedisConnection connection) throws DataAccessException {
byte[] key=redisTemplate.getStringSerializer().serialize(cacheKey);

byte[] key=keySerializer.serialize(cacheKey);
connection.del(key);
autoLoadHandler.resetAutoLoadLastLoadTime(cacheKey);
return null;
Expand Down
23 changes: 14 additions & 9 deletions src/main/java/com/jarvis/cache/redis/ShardedCachePointCut.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import java.io.Serializable;
import java.util.Collection;
import java.util.Set;
import java.util.List;

import org.apache.log4j.Logger;

Expand Down Expand Up @@ -128,16 +128,21 @@ public void delete(final String cacheKey) {
try {
shardedJedis=shardedJedisPool.getResource();
Collection<Jedis> list=shardedJedis.getAllShards();
StringBuilder script=new StringBuilder();
script.append("local keys = redis.call('keys', KEYS[1]);\n");
script.append("if(not keys or #keys == 0) then \n return nil; \n end \n");
script.append("redis.call('del', unpack(keys)); \n return keys;");
for(Jedis jedis: list) {
Set<byte[]> keys=jedis.keys(keySerializer.serialize(cacheKey));
if(null != keys && keys.size() > 0) {
byte[][] keys2=new byte[keys.size()][];
keys.toArray(keys2);
jedis.del(keys2);
for(byte[] tmp: keys2) {
String tmpKey=(String)keySerializer.deserialize(tmp);
autoLoadHandler.resetAutoLoadLastLoadTime(tmpKey);
try {
@SuppressWarnings("unchecked")
List<String> keys=(List<String>)jedis.eval(script.toString(), 1, cacheKey);
if(null != keys && keys.size() > 0) {
for(String tmpKey: keys) {
autoLoadHandler.resetAutoLoadLastLoadTime(tmpKey);
}
}
} catch(Exception ex) {
logger.error(ex.getMessage(), ex);
}
}
} catch(Exception ex) {
Expand Down

0 comments on commit dd7e98e

Please sign in to comment.