redis lua运用

lua 脚本如下:

local key = KEYS[1]
-- 限流大小
local limit = tonumber(ARGV[1])

-- 获取当前流量大小
local curentLimit = tonumber(redis.call('get', key) or "0")

if curentLimit + 1 > limit then
    -- 达到限流大小 返回
    return 0;
else
    -- 没有达到阈值 value + 1
    redis.call("INCRBY", key, 1)
    redis.call("EXPIRE", key, 2)
    return curentLimit + 1
end

jedis 执行脚本

result = jedis.eval(script, Collections.singletonList(key), Collections.singletonList(String.valueOf(limit)));
三个参数 1 脚本、2 key集合、3 arg集合

EVAL script numkeys key [key ...] arg [arg ...]
script 参数是一段 Lua 5.1 脚本程序,它会被运行在 Redis 服务器上下文中,这段脚本不必(也不应该)定义为一个 Lua 函数。
numkeys 参数用于指定键名参数的个数。
键名参数 key [key ...] 从 EVAL 的第三个参数开始算起,表示在脚本中所用到的那些 Redis 键(key),这些键名参数可以在 Lua 中通过全局变量 KEYS 数组,用 1 为基址的形式访问( KEYS[1]KEYS[2] ,以此类推)。
在命令的最后,那些不是键名参数的附加参数 arg [arg ...] ,可以在 Lua 中通过全局变量 ARGV 数组访问,访问的形式和 KEYS 变量类似( ARGV[1]ARGV[2] ,诸如此类)。

在 Lua 脚本中,可以使用两个不同函数来执行 Redis 命令,它们分别是:

•redis.call()
•redis.pcall()

redis.call() 和 redis.pcall() 的唯一区别在于它们对错误处理的不同。

当 redis.call() 在执行命令的过程中发生错误时,脚本会停止执行,并返回一个脚本错误,错误的输出信息会说明错误造成的原因:

redis> lpush foo a
(integer) 1

redis> eval "return redis.call('get', 'foo')" 0
(error) ERR Error running script (call to f_282297a0228f48cd3fc6a55de6316f31422f5d17): ERR Operation against a key holding the wrong kind of value

和 redis.call() 不同, redis.pcall() 出错时并不引发(raise)错误,而是返回一个带 err 域的 Lua 表(table),用于表示错误:

redis 127.0.0.1:6379> EVAL "return redis.pcall('get', 'foo')" 0
(error) ERR Operation against a key holding the wrong kind of value

1、数据类型

1个变量可以存储任意数据类型

2、变量

分全局、局部变量,全局变量无需声明可以直接使用默认nil。如a =1 print(b) redis脚本中不允许使用全局变量,防止脚本间影响
变量名命名规则和java一样。
局部变量声明方式:
local a -- 默认为nil
local b=1
local c,d

局部变量的作用域是 从声明开始到所在层的语句块结尾

声明一个存储函数:
local say_hi = function()
print "hi"
end

3、注释

单行注释 --
多行注释 –[[ ]]

4、赋值

local a = 1
多重赋值:
local a,b = 1,2,3 -- 1=1 b=2 3 舍弃
local a,b = 1 -- a=1 b=nil
执行多重赋值时,会先计算出表达式的值
local a = { 1 ,2 ,3}
local i = 1
i,a[i] = i+1 , 5 -- i,a[1] = 2,5
所以 i= 2 a = {5 , 2 , 3}

5、操作符

1)数学操作符
+、-、 *、 /、 %、-(取负)、^(幂运算)
数学操作符的操作数如果是字符串会自动转成数字
'1' + 1 --2
2)比较操作符
== 比较类型和值是否都相等
~= > >= < <=
1 == ‘1’ --false 类型不同
{'1'} == {'1'} --false 表类型比的是引用

3)逻辑操作符
and or not
Lua只认为 nil和false是假,其他都是真

4)连接操作符 .. 相当于 “+”
print('hello' .. ' '.. 'world' ) -- hello world

5)获取长度操作符 #
#'hello' --5

6、条件判断

if 表达式 then
语句块
elseif 表达式 then
语句块
else
语句块
end

6、循环

while: 如果条件成立就循环
while 表达式 do
语句块
end

repeat: 循环,直到条件成立
repeat
语句块
until 表达式

for
for i=0, 100 [, 1] do
语句块
end
或者
for 变量1,变量2 ... in 迭代器 do
语句块
end

7、表类型

表是Lua中唯一的数据结构,可以当成关联数组,任何类型都可以作为索引
定义表:
a = {} --定义a为一个空表
a['field'] = 'value' -- 把a的field字段赋值value 索引为“field”
a.field --value a.field是a['field']的语法糖
user = {name='chen',age='28'}
user.name --chen
当索引为整数时表和数组一样 索引从1开始
a[1] = 'Bob' a[2] = 'Jack'
等同于 a = {'Bob','Jack'}
遍历:
for index,value in ipairs(a) do
print(index)
print(value)
end
ipairs是Lua内置函数,实现类似迭代器功能
-- 1 Bob 2 Jack
或者
for i=1, #a do
print(i)
print(a[i])
end

Lua还提供一个迭代器 pairs,用来遍历非数组
for index ,value in pairs(user) do
print(index)
print(value)
end
name chen age 28

8、函数

function (参数)
函数体
end

local add = function(a,b)
return a+b
end
语法糖
local function add (a,b)
return a + b
end

你可能感兴趣的:(redis lua运用)