在 Redis 的 2.6 以上版本中,除了可以使用命令外,还可以使用 Lua 语言操作 Redis。从前面的命令可以看出 Redis 命令的计算能力并不算很强大,而使用 Lua 语言则在很大程度上弥补了 Redis 的这个不足。
只是在 Redis 中,执行 Lua 语言是原子性的,也就说 Redis 执行 Lua 的时候是不会被中断的,具备原子性,这个特性有助于 Redis 对并发数据一致性的支持。
Redis 支持两种方法运行脚本,一种是直接输入一些 Lua 语言的程序代码;另外一种是将 Lua 语言编写成文件。
在实际应用中,一些简单的脚本可以采取第一种方式,对于有一定逻辑的一般采用第二种方式。而对于采用简单脚本的,Redis 支持缓存脚本,只是它会使用 SHA-1 算法对脚本进行签名,然后把 SHA-1 标识返回回来,只要通过这个标识运行就可以了。
第一步创建lua指令
创建一个lua的文件:接收key参数
-- 接收保存redis的键名称
local key = KEYS[1]
-- 接收保存redis的值名称
local value = KEYS[2]
-- 把键值对存入redis
redis.call('set',key,value)
-- 获取键值对对应的值
return redis.call('get',key)
-- 以上就是一个简单的lua例子,接收外部调用的两个参数,KEYS[1]是第一个参数的占位符,KEYS[2]是第二个参数占位符
-- 外部调用方法:redis-cli --eval test.lua name zhangsan ...(...指多个参数,用空格隔开)
-- redis-cli --eval 执行lua文件的命令
-- test.lua 要执行的文件路径为当前路径
-- name是第一个参数值,对应test.lua中的KEYS[1]位置
-- zhangsan是第二个参数值,填充到test.lua中的KEYS[2]位置
迭代
-- 从1到100每次增量1
for i=1,100,1 do
redis.call('set','key'..i,"value"..i)
end
接收key参数和value参数
--缓存抢红包列表信息列表key
local listKey = 'red_packet_list_'..KEYS[1]
--当前被抢红包key
local redPacket = 'red_packet_'..KEYS[1]
--获取当前红包库存
local stock = tonumber(redis.call('hget', redPacket, 'stock'))
--没有库存,返回为0
if stock <= 0 then return 0 end
--库存减1
stock = stock -1
--保存当前库存
redis.call('hset',redPacket,'stock', tostring(stock))
--往链表中加入当前红包信息
redis.call('rpush', listKey, ARGV[1])
--如果是最后一个红包,则返回2,表示抢红包已经结束,需要将列表中的数据保存到数据库中
if stock == 0 then return 2 end
--如果并非最后一个红包,则返回1,表示抢红包成功
return 1
-- 调用方法: redis-cli --eval lua_demo/w3c.lua k1 , v1 v2
-- 解释:redis-cli --eval是执行命令,lua_demo/w3c是文件路径,
-- 逗号前面是要给lua文件中的KEYS传递参数,
-- 逗号后面是要给lua文件中ARGV传递饿参数,逗号本身前后都要加空格
格式转换
--记录客户端访问的次数,第一次返回1,以后每次调用都加1
local times = redis.call('incr',KEYS[1])
--如果第一次访问,则设置一个过期时间
if times == 1 then
redis.call('expire',KEYS[1],ARGV[1])
end
--如果访问的次数大于给定的最大次数返回0否则返回1
if times > tonumber(ARGV[2]) then
return 0
end;
return 1