Redis 使用 lua 脚本

lua教程-菜鸟

Redis里面为什么要用脚本?

  • 减少网络开销,一个脚本包含多个命令
  • 原子操作, redis是单线程的,Redis的API是原子性的操作,所以一个脚本在Redis里面是作为一个整体执行,中途不会被插入其他操作,脚本本身就是事务,更简单,速度更快
  • 可复用,客户端发送的脚步会永久存在redis中,这样,其他客户端可以复用这一脚本而不需要使用代码完成相同的逻辑

注意事项

  • lua中不能使用block命令,否则会造成堵塞

Redis调用lua脚本语法

redis-cli方式

# KEYS和ARGV中间的 ',' 两边的空格,不能省略。 
Redis-cli -h address -p port --eval path/to/redis.lua KEYS[1] KEYS[2] , ARGV[1] ARGV[2] ...
  • --eval,告诉redis-cli读取并运行后面的lua脚本
  • path/to/redis.lua,是lua脚本的位置
  • KEYS[1] KEYS[2],是要操作的键,可以指定多个,在lua脚本中通过KEYS[1], KEYS[2]获取
  • ARGV[1] ARGV[2],参数,在lua脚本中通过ARGV[1], ARGV[2]获取

redis命令模式

> EVAL script numkeys key [key ...] arg [arg ...]
  • key代表要操作的rediskey
  • arg可以传自定义的参数
  • numkeys用来确定key有几个
  • script就是你写的lua脚本
  • lua脚本里面使用KEYS[1]和ARGV[1]来获取传递的key和arg

tips

  • 在用eval命令的时候,可以注意到每次都要把执行的脚本发送过去,这样势必会有一定的网络开销,所以redis对lua脚本做了缓存,通过script load 和 evalsha实现
  • script load命令会在redis服务器缓存你的lua脚本,并且返回脚本内容的SHA1校验和,然后通过evalsha 传递SHA1校验和来找到服务器缓存的脚本进行调用
  • Redis 会把所有执行过的脚本都缓存在内存中,但是在重启的时候会释放掉之前保存的脚本
  • Lua 脚本中的变量一定是本地变量,即变量前面加上 local 前缀:local var = 1;
  • 通过 eval 带入的 ARGV 参数如果原来是数字的,会被转换为字符串,如果你的逻辑中需要判断该变量 > 0 或 < 0 之类的数字判断则必须进行字符串到数字的转换,使用 tonumber() 方法 if (tonumber(ARGV[1]) > 0) then return 1; end;

PHP使用示例

<?php

$redisHost = '127.0.0.1';
$redisPort = 6379;
//实例化redis类
$redis = new Redis();
$redis->connect($redisHost, $redisPort);
$lua = <<<SCRIPT
      return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}
SCRIPT;
//对应的redis命令如下 eval "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" 2 key1 key2 first second
//2表示KEYS的值为前2个,剩下的参数为ARGV
$s = $redis->eval($lua,array('key1','key2','first','second'),2);
var_dump($s);
本作品采用《CC 协议》,转载必须注明作者和本文链接
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!