基本操作

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')" 0OK

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

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

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

-- 定义游标cur初始值为0local 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"