Redis Lua脚本简介、以及Redis实现计数器

Redis在2.6推出了脚本功能,允许开发者使用Lua语言编写脚本传到Redis中执行。

使用Lua脚本的好处

  • 减少网络开销:通过在脚本中定义多条命令(甚至业务逻辑)可以减少了网络I/O开销。从这一点上看其比管道功能更强大。
  • 原子操作:Redis会将整个脚本作为一个整体执行,中间不会被其他命令插入。
  • 复用:客户端发送的脚本会永久存储在Redis中,意味着其他客户端可以复用这一脚本,而不需要使用代码完成同样的逻辑。

Redis中Eval命令介绍
      
Redis通过Eval命令来执行Lua脚本,Eval命令从Redis 2.6.本开始的,使用内置的 Lua 解释器,可以对Lua 本进行求值。语法如下

  1. script:需要执行的lua脚本,在Lua中可以通过变量KEYS、ARGV数组访问后面定义的key、arg。比如keys[1]代表第一个key,argv[1]代表第一个arg,注意的是下标是从1开始 
  2. numkeys: 指定key的个数
  3. key:指定每个key的名字
  4. arg:自定义参数,比如value。  

        要注意的是,在Cluster集群环境下,操作的多个key,必须要映射到同一slot上才行,否则命令会执行失败。如下:

redis.call() 和 redis.pcall() 的区别

        当redis.call() 在执行命令的过程中发生错误时,脚本会停止执行,并返回一个脚本错误,错误的输出信息会说明错误造成的原因。由于第一个执行错误,导致后面的也没有执行,设置不成功。 redis.pcall() 出错时并不引发(raise)错误,而是返回一个 nil,后面的命令任然可以执行成功。如下

192.168.192.128:6703> eval "redis.call('MSETXX',KEYS[1],KEYS[2],ARGV[1],ARGV[2]);return redis.call('set','k02','v02');" 2 k02 k02 v02 v04
(error) ERR Error running script (call to f_8cc6dd9c34e3a223c8d1f9a8f314497f77e442a2): @user_script:1: @user_script: 1: Unknown Redis command called from Lua script 
192.168.192.128:6703> eval "redis.pcall('MSETXX',KEYS[1],KEYS[2],ARGV[1],ARGV[2]);return redis.call('set','k02','v02');" 2 k02 k02 v02 v04
OK
192.168.192.128:6703> 


Redis中Lua脚本其它命令介绍

 1)SCRIPT LOAD script :用于将脚本 script 添加到脚本缓存中,返回脚本的SHA1校验和,但并不立即执行这个脚本。

192.168.192.128:6703>  SCRIPT LOAD "return redis.call('set',KEYS[1],ARGV[1])"
"c686f316aaf1eb01d5a4de1b0b63cd233010e63d"

 

2)evalsha sha1 numkeys key [key ...] arg [arg ...]

     根据给定的 SHA1 校验码(比如上面SCRIPT LOAD返回的哈希值),对缓存在服务器中的脚本进行求值。

192.168.192.128:6703>  SCRIPT LOAD "return redis.call('set',KEYS[1],ARGV[1])"
"c686f316aaf1eb01d5a4de1b0b63cd233010e63d"
192.168.192.128:6703> evalsha c686f316aaf1eb01d5a4de1b0b63cd233010e63d 1 k02 v02
OK
192.168.192.128:6703> 


3) SCRIPT EXISTS script [script ...] :通过sha1校验和判断脚本是否在缓存中

192.168.192.128:6703> script exists c686f316aaf1eb01d5a4de1b0b63cd233010e63d
1) (integer) 1


 4)SCRIPT FLUSH :清空脚本缓存

192.168.192.128:6703> script flush
OK
192.168.192.128:6703> script exists c686f316aaf1eb01d5a4de1b0b63cd233010e63d
1) (integer) 0
192.168.192.128:6703> 

 

5)SCRIPT KILL :杀死目前正在执行的脚本

 

编写Lua脚本统计在线用户数
        
Lua脚本内容如下:

[root@localhost src]# cat activeuser.lua 
if redis.call("EXISTS",KEYS[1]) == 1 then
     return redis.call("INCRBY",KEYS[1],ARGV[1])
   else
     return nil
   end

      执行脚本

[root@localhost src]# ./redis-cli -h 192.168.192.128 -p 6703 --eval activeuser.lua activeuser , 1
(integer) 303
[root@localhost src]# ./redis-cli -h 192.168.192.128 -p 6703 --eval activeuser.lua activeuser , 1
(integer) 304
[root@localhost src]# ./redis-cli -h 192.168.192.128 -p 6703 --eval activeuser.lua activeuser , 1
(integer) 305
[root@localhost src]# ./redis-cli -h 192.168.192.128 -p 6703 --eval activeuser.lua activeuser , 1
(integer) 306
[root@localhost src]# ./redis-cli -h 192.168.192.128 -p 6703 --eval activeuser.lua activeuser , 1
(integer) 307

      --eval参数是告诉redis-cli读取并运行后面的Lua脚本,activeuser.lua是脚本文件位置,后面跟着是传给Lua脚本的参数。逗号前的是key列表,用脚本中可以用KEYS[index]来获取;逗号之后的参数列表,对应在脚本中通过ARGV[index]获取。要注意的是:,逗号两边的空格不能省略,否则会出错。个人就因为这一个逗号,耽误了半个多小时。

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值