redis使用lua

基本操作

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"
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,142评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,298评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,068评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,081评论 1 291
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,099评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,071评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,990评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,832评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,274评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,488评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,649评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,378评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,979评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,625评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,796评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,643评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,545评论 2 352

推荐阅读更多精彩内容