redis-5

本文介绍了Redis 2.6版本引入的Lua脚本功能,允许开发者编写Lua脚本来减少网络开销,实现原子操作和脚本复用。文章通过实例展示了如何使用Lua脚本进行访问频率限制,讲解了Lua的基础语法,包括数据类型、变量、注释、赋值、操作符,以及在Redis中的应用。同时,文中提到了Redis中与脚本相关的命令,如EVAL、EVALSHA,以及如何在PHP中使用Lua脚本。
摘要由CSDN通过智能技术生成

redis学习第五章

脚本

  1. 介绍

redis在2.6版本中退出了脚本功能,允许开发者使用Lua语言编写脚本传到redis中执行。在Lua脚本中可以调用大部分的redis命令。使用脚本的好处:
1).减少网络开销。
2).原子操作:redis会将整个脚本作为一个整体执行,也就是说不必单行出现静态条件,也不用使用事务,事务可以完成的,脚本也可以完成。
3).复用:客户端发送的脚本会永远存储在redis中,这意味着其他客户端(可以是其他语言开发的项目)可以复用这一脚本而不需要使用代码完成同样的逻辑。

  1. 实例:访问频率控制

因为无需考虑事务,使用redis脚本实现访问频率限制就非常简单了。Lua如下:

local times = redis.call('incr',KEYS[1])

if times == 1 then
    -- KEYS[1] 键刚创建,所以为其设置生存时间
    redis.call('expire',KEYS[1],ARGV[1])
end

if times > tonumber(ARGV[2]) then
    return 0
end

return 1

如何运行测试该脚本呢?
首先把这段代码村委ratelimiting.lua,然后在命令行中输入:
$redis-cli --eval /path/to/ratelimiting.lua rate.limiting:127.0.0.1 , 10 3

其中–eval是告诉redis-cli读取并运行后面的Lua脚本
/path/to/ratelimiting.lua是lua脚本的位置
rate.limiting:127.0.0.1 , 10 3 是lua脚本的参数,其中“,”之前的是键,之后的是参数。分别用KEYS[1]和ARGV[1]、ARGV[2]获取
结合脚本可知,改脚本是限制访问频率为10s内三次。
注意: 参数和键之间的逗号“,”两边的空格不能省略,否则会出错。

  1. Lua语言

3.1).Lua语法

3.1.1).数据类型
Lua是一个动态类型的语言,一个变量可以存储任何类型的值。编写redis脚本会用到的类型如下表(Lua常用数据类型):

类型名 取值
空(nil) 空类型只包含一个值,即nil。nil表示空,所以没有赋值的变量或表的字段都是nil
布尔(boolean) 布尔类型包含true和false
数字(number) 整数和浮点都是使用数字类型来存储,如:1、0.2、3.5e20等
字符串(string) 该类型可以存储字符串,且与redis的键值一样都是二进制安全的。字符串可以使用单引号或双引号表示,两个字符是相同的。比如’a’,“b” 都是可以的。字符串中可以包含转义字,如\n、\r等
表(table) 表类型是lua语言中唯一的数据结构,既可以当数组又可以当字典(表类型的索引从1开始)
函数(function) 函数在Lua中是一等值(first-class value),可以存储在变量中、作为函数的参数或返回结果

3.1.2).变量

Lua的变量分为全局变量和局部变量。全局变量无需声明就可以直接使用,默认值是nil。如:
a = 1 – 为全局变量a赋值
print(b) --无需声明直接使用,默认值为nil
a = nil – 删除全局变量a的方法是将其赋值为nil。全局变量真没有声明和未声明之分,只有非nil和nil的区别。

在redis脚本中不能使用全局变量,值允许使用局部变量,以防止脚本之间相互影响。声明全局变量的方法为local变量名,就像这样:
local c --声明一个局部变量c,默认值是nil
local d = 1 – 声明一个局部变量d并赋值为1
local e, f --可以同时声明多个局部变量

声明一个存储函数的局部变量的方法为:
local say_hi = function ()
print ‘hi’
end

注意: 变量名只能是非数字开头,只能包含字母、数字和下划线,区分大小写。变量名不能与Lua关键字相同,保留关键字如下:
and break do else elseif
end false for function if
in local nil not or
repeat return then true until while

局部变量的作用域为从声明开始到所在层的语句块末尾,比如:
local x = 10
if true then
local x = x + 1
print(x)//11
do
local x = x + 1
print(x)//12
end
print(x)//11
end
print(x)//10

3.1.3).注释

Lua的注释分为单行和多行两种:
单行注释以–开始,到行位结束,一般习惯在–后面跟一个空格
多行注释以–[[开始,到]]结束,如:
–[[
这是一个注释
]]

3.1.4).赋值
Lua支持多重赋值:
local a,b = 1,2 --a=1 b=2
local c,d = 1,2,3 – c=1 d=2 3废弃
local e,f = 1 – e=1 f = nil

在执行多重赋值时,Lua会先计算所有表达式的值,比如:
local a = {1,2,3}
local i = 1
i,a[i] = i + 1 , 5
Lua计算所有表达式的值后,上面最后一个赋值语句变为i,a[1] = 2,5,所以赋值后i的值为2,a则为{5,2,3}
Lua中函数也会返回多个值。

3.1.5).操作符

Lua有以下5类操作符。

  1. 数学操作符。数学操作符包括常见的+、-、*、/、%(取模)、-(一元操作符,取负)和幂运算^。
    数学操作符的操作数如果是字符串会自动转换成数字,比如:
    print(‘1’ + 1) – 2
    print(‘10’ * 2) – 20

  2. 比较操作符
    == 比较两个操作数的类型和值是否都相等
    = 与==的结果相反
    <,>,<=,>= 小于,大于、小于等于、大于等于
    比较操作符的结果一定是布尔类型,比较操作符不同于数学操作符,不会对两边的操作数进行自动类型转换,也就是说:
    print(1 == ‘1’) --false,二者类型不同,不会进行自动类型转换
    print({‘a’} == {‘a’}) --false,对于表类型的值,比较的是二者的引用
    如果比较字符串和数字,可以手动进行类型转换,如下:
    print(1 == tonumber(‘1’)) – true
    print(‘1’ == tostring(1)) – true
    其中 tonumber函数还可以进行进制转换,比如 print(tonumber(‘F’,16)) – 将字符串’F’从16进制转换成10进制结果是15

  3. 逻辑操作符
    not 根据操作数的真和假相应地返回false和true
    and a and b 中如果a是真则返回b,否则返回a
    or a or b 中如果a是真则返回a,否则返回b

只要操作数不是nil或false,逻辑操作符就认为操作数是真,否则是假。特别需要注意的是即时是0或空字符串也被当做真。例如:
print(1 and 5) – 5
print(1 or 5) – 1
print(not 0) – false
print(’’ or 1) – ‘’

<
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值