Redis奇幻之旅(三)10. lua脚本

10. lua脚本

​ 其实在《3.7.1 单机Redis的分布式锁》的一段python代码中已经使用到了lua脚本,当时是为了解决在Redis中取值和比对的原子性问题。那么Redis中的lua脚本具体有什么特点呢?我们一起来看看。

  • lua脚本在Redis中执行时是原子的。

    也正是因为这个特性,我们要防止lua脚本执行时长过大,导致Redis卡顿。为了防止这个问题,脚本还有一个最大执行时间限制,默认值是 5 秒钟。当然我们也可以通过redis.conf文件中的lua-time-limit 选项(单位:毫秒)来控制这个时间。

  • 我们写的lua脚本中一定会有对于Redis的相关操作,这时就用到了一个伪客户端。

    请求方式:客户端 ---> lua环境 ---> 伪客户端 ---> 命令执行器

    给客户端的感觉只是和Redis交互了其实中间还有其他的步骤。我们可以用redis.call()或者redis.pcall()在lua脚本中内嵌Redis相关操作

  • 对于同样的输入集,Redis执行得到的结果是一致的

    Redis对lua脚本的支持其实并不是全量的,它只引入了一部分lua的函数库(可以看官方文档来查阅)。Reids会阻止有不确定性的lua脚本执行,比如一些随机函数或者时间函数,因为这些函数可能导致Redis在不同时间段执行同样输入集的脚本得到不同的结果。并且在有序数据输出的时候,Redis还会对输出结果进行辅助排序,保证每次得到的结果是一致的。

10.1 lua相关命令

  • EVAL

    EVAL的第一个参数是一段 Lua 5.1 脚本程序。 这段Lua脚本不需要(也不应该)定义函数。它运行在 Redis 服务器中。

    EVAL的第二个参数是参数的个数,后面的参数(从第三个参数),表示在脚本中所用到的那些 Redis 键(key),这些键名参数可以在 Lua 中通过全局变量 KEYS 数组,用 1 为基址的形式访问( KEYS[1] , KEYS[2] ,以此类推)。

    在命令的最后,那些不是键名参数的附加参数 arg [arg …] ,可以在 Lua 中通过全局变量 ARGV 数组访问,访问的形式和 KEYS 变量类似( ARGV[1] 、 ARGV[2] ,诸如此类)。

    > eval "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" 2 key1 key2 first second
    1) "key1"
    2) "key2"
    3) "first"
    4) "second"
    
  • EVALSHA

    根据给定的 SHA1 校验码,对缓存在服务器中的脚本进行求值,如果在缓存中没有该脚本,就会有NOSCRIPT错误。 将脚本缓存到服务器的操作可以通过 SCRIPT LOAD 命令进行。 这个命令的其他地方,比如参数的传入方式,都和EVAL命令一样。

  • SCRIPT EXISTS

    检查脚本是否存在脚本缓存里面。

    这个命令可以接受一个或者多个脚本SHA1信息,返回一个1或者0的列表,如果脚本存在或不存在。

    还可以使用管道技术(pipelining operation)确保脚本加载(也可以使用SCRIPT LOAD), 管道技术可以单独使用EVALSHA来代替EVAL,从而节省带宽(bandwidth)。

  • SCRIPT FLUSH

    清空Lua脚本缓存 Flush the Lua scripts cache.

  • SCRIPT KILL

    杀死当前正在运行的 Lua 脚本,当且仅当这个脚本没有执行过任何写操作时,这个命令才生效。

    这个命令主要用于终止运行时间过长的脚本,比如一个因为 BUG 而发生无限 loop 的脚本,诸如此类。

    SCRIPT KILL 执行之后,当前正在运行的脚本会被杀死,执行这个脚本的客户端会从 EVAL 命令的阻塞当中退出,并收到一个错误作为返回值。

    另一方面,假如当前正在运行的脚本已经执行过写操作,那么即使执行 SCRIPT KILL ,也无法将它杀死,因为这是违反 Lua 脚本的原子性执行原则的。在这种情况下,唯一可行的办法是使用 SHUTDOWN NOSAVE 命令,通过停止整个 Redis 进程来停止脚本的运行,并防止不完整(half-written)的信息被写入数据库中。

  • SCRIPT LOAD

    将脚本 script 添加到脚本缓存中,但并不立即执行该脚本。在脚本被加入到缓存之后,通过 EVALSHA 命令,可以使用脚本的 SHA1 校验和来调用这个脚本。 EVAL 命令也会将脚本添加到脚本缓存中,但是它会立即对输入的脚本进行求值。

    脚本可以在缓存中保留无限长的时间(直到执行 SCRIPT FLUSH 为止) 如果给定的脚本已经在缓存里面了,那么不做动作。

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

推荐阅读更多精彩内容