主题
为啥会有这篇文章呢? 在redis里我需要批量删除一些 "特殊" 的数据...这些特殊的数据用正常方法比较难删除...所以记录一下我的删除方法..
背景与问题
我再用SpringBoot集成Spring的@Cacheable的时候遇到了一些比较麻烦的事情...
第一个是序列化问题...相信大家一般都会遇到过..
redisTemplate默认用的是JdkSerializationRedisSerializer
所以会生成这个样子的字符串...
其实这个样子的字符串也没关系......只要他能正常删除就行了...可是偏偏很多可视化工具都不支持...
redis本身是没有批量删除命令的...可是话工具是提供批量删除的..原理是把所有满足条件的key找出来1个1个删除...那现在问题就是他key不认识...是乱码..所以也就删除不了了..
在命令行1个1个删除是没问题的...但是key多了就GG了.......
解决办法
办法1
用这种jdk自带的序列化来序列化string的key我觉得是不合理的...这个key看都看不懂...所以我们可以指定用其他方法来序列化key...
spring本身提供了String的序列化方式(StringRedisSerializer)...所以我们可以用这个序列化类来序列化key
这样生成的key很正常..很美观...也是我们想要的
方法2
方法1是一种解决办法...但是最为学习来说我希望能有一种不是回避而是通过技术手段来解决这个问题的方法...方法1的解法是可行的.也是不错的...但到底是有没有办法批量去删除redis的key...
有的...网上大部分给的解法是这样的:
1 redis-cli -h 192.168.0.8 -p 6380 keys "obj_base_*" |xargs redis-cli -h 192.168.0.8 -p 6380 del
这样是一种解决办法...但是可能是我LINUX命令不太好吧...这种删除方法对于key里面有\xAC等jdk序列化生成的字符的时候是会报错的...如果这种方法不报错...那可视化工具也是能删除的...所以这就很尴尬了...
xargs: WARNING: a NUL character occurred in the input. It cannot be passed through in the argument list. Did you mean to use the --null option?
可能精通linux命令的小朋友会有什么命令可以处理这些字符吧...但是我还不太会....= =
所以我自己用另外1种办法...
我想:在命令行可以删除.那再命令行可以获取真正的带引号的字符串..那只要批量执行这个命令行就OK了吧..
redis是支持lua脚本的...那我自己写个lua脚本就行了吧
花了十几分钟学习了语法以后成功写出了1个非常简单的脚本...但是还是蛮实用的..
1 local key=KEYS[1] 2 local result={}; 3 local list=redis.call("keys", key); 4 for i,v in ipairs(list) do 5 redis.call("del", v); 6 table.insert(result,i,v); 7 end 8 9 return result;
这样就比较完美的解决了批量删除问题.
小结
redis可以支持lua脚本真的很好...通过这个脚本可以做一些扩展功能...
那么我能不能自定义一些dels命令去调用lua脚本做批量删除呢? 值得尝试.....