在项目中使用 lua 脚本执行指令去操作redis,在我们java项目中是一个比较常见到常见. 但是我们一般使用都是会基于某个百度出来的文章来跑下, 能看到下效果就能ok了。那么现在问题就来了,如果是看不到效果呢?那该怎么办?继续百度,于是你会发现出来的一堆csdn什么文章都是抄来抄去,会让你一度怀疑自己的.
于是今天这里就介绍一个使用 SpringBoot 来执行 lua 脚本的时候,来定位问题的操作.
先来一个 lua 脚本文件内容看看
local key = KEYS[1]local values = ARGV-- log 级别需要与 redis (server端的log级别是一致的.)-- redis.log(redis.LOG_WARNING,"接受到key值是 ---> " ..key)local result = {}for i,v in ipairs(values) do-- redis.log(redis.LOG_WARNING,"每次遍历v的值是 ---> " ..v)-- redis.log(redis.LOG_WARNING,"v类型 ---> " ..type(v))v = string.gsub(v,"\"","")-- redis.log(redis.LOG_WARNING,"替换后的值 ---> " ..v)local exists_result = redis.call('BF.ADD',key,v)-- redis.log(redis.LOG_WARNING,"每次返回的值是 ---> " ..exists_result)table.insert(result,exists_result)endreturn result
该lua脚本做了什么事情呢?
可以看到在for循环里面执行了 bf.add 指令.
RedisBloom : 基于redis实现的布隆过滤器插件执行的指令,使用和安装参考地址 : https://docs.redislabs.com/latest/modules/redisbloom/
紧接着,在项目中配置下.
/*** 批量注入插入数据* @return*/@Bean(name = "batchBloomFilterScript")public DefaultRedisScript batchBloomFilterScript(){DefaultRedisScript<List> redisScript = new DefaultRedisScript<>();redisScript.setResultType(List.class);redisScript.setScriptSource(new ResourceScriptSource(new ClassPathResource("lua/BatchAddBloomFilter.lua")));return redisScript;}
这里是 省掉了 redis的配置的没有贴出来.
上面这段代码贴出来的意思,是告诉下大家是可以这样配置的。
我们贴一个测试类, 就可以直接开干了.
@Testpublic void loadBatchLuaScript(){DefaultRedisScript<List> redisScript = new DefaultRedisScript<>();redisScript.setResultType(List.class);redisScript.setScriptSource(new ResourceScriptSource(new ClassPathResource("lua/BatchAddBloomFilter.lua")));List<String> list = new ArrayList<>();for(int i=0;i<10;i++){list.add("testaaaa"+i);}list.add("testaaa1");Object execute = redisTemplate.execute(redisScript, Collections.singletonList("test001"), list.toArray());System.out.println(execute);}
往下看结果, 这里的值和上面输入的内容没对上,那是我有做过修改.
这是redis中配置的logfile文件中的记录
这里可以看到,我们在redis中打印出来的值前后都是带 "" 二个串的,所以我们用 bf.exists test001 "0test" 是返回的0,那就是没有匹配到的, 这里也许会有疑惑说没问题啊?其实不让, 得使用 bf.exists test \""0test"\" 转义下,多个"",才是ok的.
难道我们程序得这么干?当然不是,于是本人在lua脚本中进行了代码修改
v = string.gsub(v,"\"","")
就是这行代码,将二个""给替换掉了。

这是我们开了aof配置中记录的执行指令
可以看到的是 aof 配置的记录,其实也就是依次解析了redis挨个执行的指令,然后使用aof配置还原的时候,也是依次解析并且执行还原回去的.

这里于是我们在lua脚本中打印的log就写入到redis的配置文件,logfile配置的日志文件中来了.
于是,我们比较好奇的点, 在开发怎么阶段,如果lua脚本出现看似没有执行,或者说执行了,返回的值都是1,我们在查询之类的操作, 却偏偏查询不出来,就可以使用这个log打印值的方式来定位问题.




