redis使用Lua脚本

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/c295477887/article/details/52486348

最近在看《Redis入门指南》第二版,感觉收获挺大,推荐大家有时间看一看。其中有一章讲Lua脚本,感觉挺实用,把总结整理一下。

Redis在2.6中推出了脚本功能,允许开发者使用Lua语言编写脚本传到Redis中执行。Lua脚本可以调用大部分的Redis命令,使用Lua脚本的好处是:

1)减少网络开销,作为内存型数据库redis的性能开销主要花在发送指令和接收结果的网络开销上,把多条redis指令写在1个Lua脚本里,只需要通过网络发送1次就可以了

2)原子操作 Redis将整个脚本作为1个整体执行,中间不会被其他命令插入。

3)复用,客户端发送的脚本会存储在redis中,其他客户端就可以复用

先说一下Lua的语法

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

Lua调用redis命令


redis.call('set','name','chen')
local value = redis.call('get','name')
redis返回值Lua会自动转换成自己的类型
image

在redis中执行

EVAL script numkeys key [key ...] arg [arg ...]

java调用lua脚本:

String script ="local result={} " +
                " for i,v in ipairs(KEYS) do " +
                " result[i] = redis.call('get',v) " +
                " end " +
                " return result ";

Jedis jedis = new Jedis(ip,port);

jedis.eval(script,keyCount,String … params);

注意,不要再Lua脚本中出现死循环和耗时的运算,否则redis将不接受其他的命令,这个redis就挂了,只能script kill,如果有写入的话,只能shutdown nosave。
所以使用时要注意不能出现死循环、耗时的运算。redis是单进程、单线程执行脚本

猜你喜欢

转载自blog.csdn.net/c295477887/article/details/52486348