java redis 批量删除_在Spring中使用Redis Lua脚本批量删除缓存

背景

之前分享了一篇利用lua脚本批量删除redis的key的文章.现在项目中我打算使用spring的缓存,而Spring缓存以前我是用ehcache来做实现的.没发现什么问题..这次我换成redis来做缓存了..一般也没什么大问题...目前唯一遇到的一个比较坑的问题就是缓存通过注解删除不了..我想想好像也算正常吧.因为java里面做缓存的话可能会使用map类似的结构,我remove掉一个key,不管对应的value是什么结构都能删除掉..但是redis的key是没有层级的...比如2个key分别是a:a1和a:a2.虽然可视化工具上看上去都是属于a下面的..但是redis的del a并不会删除a下属的所有key而是只会删除key为a的这个数据.所以我得自己实现Spring Cache中删除缓存的那部分逻辑.而redis本身是没有批量删除key的功能的.

问题

所以现在的问题就是 如何在Spring的redisTemplate中使用lua脚本删除key

解决办法

我觉得可以这么做:

1.首先把之前文章写的批量删除的lua脚本放到maven项目的resources下.

2.然后写一个Beanimplements InitializingBean在启动的时候加载这些脚本.

1 /**

2 * 加载批量lua脚本3 *4 *@throwsException5 */

6 @Override7 public void afterPropertiesSet() throwsException {8 loadDelScript();9 }10

11 /**

12 * 加载批量删除脚本13 */

14 private void loadDelScript() throwsIOException {15 String s = FileUtils.readFileToString(new ClassPathResource(CRedisCacheConstant.SCRIPT_PATH + "/" + "dels.lua").getFile(), Charset.forName("UTF-8"));16 DefaultRedisScript sc = new DefaultRedisScript<>(s, List.class);17 scripts.put("dels", sc);18 }

3.需要批量删除的时候通过DefaultRedisScript去使用这个脚本

1 DefaultRedisScript sc = scripts.get("dels");2 List cache = (List) redisTemplate.execute(sc, stringRedisSerializer, stringRedisSerializer, Collections.singletonList(wholeKey));3 log.info("删除page缓存 {}", cache);

这样就可以在Java代码中使用lua脚本成功批量删除缓存啦.

有些小朋友可能会问.这样做每次都需要把脚本序列化传给redis吗?那脚本大了不是很占用网络吗?

其实并不会...

DefaultScriptExecutor中有一段代码:

1 protected T eval(RedisConnection connection, RedisScript script, ReturnType returnType, intnumKeys,2 byte[][] keysAndArgs, RedisSerializerresultSerializer) {3

4 Object result;5 try{6 result =connection.evalSha(script.getSha1(), returnType, numKeys, keysAndArgs);7 } catch(Exception e) {8

9 if (!exceptionContainsNoScriptError(e)) {10 throw e instanceof RuntimeException ? (RuntimeException) e : newRedisSystemException(e.getMessage(), e);11 }12

13 result =connection.eval(scriptBytes(script), returnType, numKeys, keysAndArgs);14 }15

16 if (script.getResultType() == null) {17 return null;18 }19

20 returndeserializeResult(resultSerializer, result);21 }

会先计算这个脚本的sha1的值,通过redis的EVALSHA去允许脚本..如果失败了,比如第一次没有加载.就把脚本序列化传过去执行...往后都通过这个sha1值直接调用.

127.0.0.1:6379>SCRIPT EXISTS f7cb6ede3d6d2e14b812f32f129633443197b42c1) (integer) 1

小结

通过使用DefaultRedisScript可以比较方便的在java中使用lua脚本操作redis

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值