关于java:redis使用lua

48次阅读

共计 2014 个字符,预计需要花费 6 分钟才能阅读完成。

基本操作

redis 中执行 lua 能够通过两种形式:

  • eval
  • evalsha

第一种是将 lua 脚本或命令间接应用 redis 执行,第二种相当于把脚本或命令保留到 redis 中,而后应用一串 sha 码调用(能够了解为调用函数)

eval

命令行执行

eval 脚本内容 key 个数 key 列表 参数列表
  • 脚本内容就是要执行的 lua 脚本内容
  • key 个数示意参数中有多个个 key,redis 中的 key 是从 1 开始的,如果没有 key 的参数,就写 0
  • key 列表,作为参数传递给 Lua 语言,lua 中是用 KEYS[n] 来获取对应的参数
  • 参数列表是传递给 Lua 语言,可填可不填,lua 中应用 ARGV[n] 来获取对应的参数

例子(在 redis 中执行):

eval 'return"hello".. KEYS[1] .. ARGV[1]' 1 redis world 

输入:

"hello redisworld"

这里传入的 key 个数为 1,所以 redis 是 key 而 world 是参数

执行 lua 脚本文件

redis-cli --eval 脚本文件 key 列表,参数列表

evalsha

这个操作相当于把脚本加载到 redis,失去一个 SHA1 的校验和,而后应用这个 SHA1 码来调用对于的 Lua 脚本,防止每次去发送 Lua 脚本。

加载脚本

script load

例子:

redis-cli script load "$(cat del-batch.lua)"
"e812abcb57c0360287ff97f74e444c04144382c9"

应用

执行 evalsha

evalsha 脚本 sha 值 key 个数 key 列表 参数列表

如:

127.0.0.1:6379> evalsha e812abcb57c0360287ff97f74e444c04144382c9 1 A*
"del pattern is : A*, count is:0"

redis 治理脚本的形式

redis 提供了几个命令来治理脚本

  • script load
  • script exists
  • script flush
  • script kill

script load

用于将 Lua 脚本加载到 redis 内存中

script load [script]

script exists

用于判断 sha1 值是否曾经加载到 redis 内存中

script exists sha1...

返回个数

script flush

用于革除 redis 内存曾经加载的所有脚本

script flush

script kill

用于杀掉正在执行的 Lua 脚本

script kill

如果 Lua 脚本比拟耗时,甚至 Lua 脚本存在问题,那么此时 Lua 脚本的执行会阻塞 redis,直到脚本执行结束或者内部干涉将其完结

有一点须要留神,如果 Lua 脚本正在执行写操作,script kill命令不会失效,这时只能期待脚本执行完结,或应用 shutdown save 停掉 redis 服务

应用 lua 的长处

  • Lua 脚本在 Redis 中是原子执行的,执行过程中不会插入其余命令
  • Lua 脚本能够帮忙开发和运维人员发明出本人定制的命令,并能够将这些命令寄存在内存中,实现复用的成果
  • Lua 脚本能够将多条命令一次性打包,无效缩小网络开销

在 lua 脚本中调用 redis 办法

可参看 redis 官网文档

有两种形式能够调用

  • redis.call()
  • redis.pcall()

这两种办法都能够调用,区别是 call()办法是遇到就进行执行前面的内容并间接返回谬误,而 pcall 遇到异样会疏忽掉继续执行

eval "return redis.call('set','foo','bar')" 0
OK

其余命令可参看文档这里不赘述

应用 scan 进行批量删除的例子

一个应用 Lua 脚本执行 redis scan 命令进行批量删除的例子,文件名为del-batch.lua

-- 定义游标 cur 初始值为 0
local cur = 0
-- 定义删除个数初始值
local count=0
-- 循环调用
repeat
    -- 调用游标
    local result = redis.call("scan",cur,"match",KEYS[1])
    -- 将下个游标点转化为 number
    cur = tonumber(result[1])
    local arr = result[2]
    -- 循环以后游标获取到的值,进行删除
    if(arr~=nil and #arr>0) then
        for i,k in pairs(arr) do
            local key = tostring(k)
            -- 或者应用 redis.call("unlink",key)
            redis.call("del",key)
            count = count +1
        end
    end
-- 当游标点为 0 时,退出循环
until(cur<=0)
-- 返回执行的后果
return "del pattern is :"..KEYS[1]..", count is:"..count

调用

redis-cli --eval del-batch.lua "TEST_KEY*"

执行了之后会删除合乎规定 TEST_KEY* 的 key

调用后果

"del pattern is : TEST_KEY*, count is:300"

正文完
 0