Redis--事务与Lua脚本

一、简介:

Redis从2.6版本开始引入对Lua脚本的支持,通过在服务器中嵌入Lua环境,Redis客户端可以使用Lua脚本,直接在服务端原子的执行多个Redis命令。它是由C语言实现的,虽然简单小巧但是功能强大,所以许多应用都选用它作为脚本语言

二、redis中的事务

1.概述

如果熟悉关系型数据库应该对事务比较了解,简单地说,事务表示一 组动作,要么全部执行,要么全部不执行,但是reids中的事务是 没有原子性的 只是简单的事务有异常会直接跳过并不支持回滚

2.不支持回滚的原因

(1)Redis命令只会因为错误的语法而失败(并且这些问题不能在入队时发现),或是命令用在了错误类型的键上面:这也就是说,从实用性的角度来说,失败的命令是由编程错误造成的,而这些错误应该在开发的过程中被发现,而不应该出现在生产环境中。

(2)因为不需要对回滚进行支持,所以 Redis的内部可以保持简单且快速。

3.保证事务原子性的两种方法:

Redis虽然不支持事务,但是提供了类似事务的两种方法如:

(1)watch命令

虽说 Redis不支持直接回滚,但我们可以通过 Redis提供的一个命令来实现回滚这个命令就是 watch,该命令可以为 Redis事务提供 check-and-set (CAS)行为。我们可以使用 watch命令来监视一个 或多个key,如果被监视的 key在事务执行前被修改过那么本次事务将会被取消,也就是所谓的回滚

注意事项:

watch要在事务开启之前就监控不然会报错
watch是一次性的
watch开启的客户端端口连接这个客户端对watch的监听就会被取消

(2)lua脚本:接下来会重点讲

三、Lua脚本的数据类型

Lua 语言提供了如下几种数据类型: booleans (布尔)、 numbers (数 值)、strings (字符串)、 tables (表格),和许多高级语言相比,相对简单

1.字符串

local strings val = "world"

其中,local代表val是一个局部变量,如果没有local代表是全局变量。

2.数组

Lua 中,如果要使用类似数组的功能,可以用 tables 类型,下面代码使 用定义了一个tables 类型的变量 myArray ,但和大多数编程语言不同的是, Lua的数组下标从 1 开始计算
local tables myArray = {"redis", "jedis", true, 88.0}

3.哈希

如果要使用类似哈希的功能,同样可以使用 tables 类型,例如下面代码 定义了一个tables ,每个元素包含了 key value ,其中 strings1..string2 是将两个字符串进行连接:
local tables user_1 = {age = 28, name = "tome"}

4.函数定义

Lua 中,函数以 function 开头,以 end 结尾, funcName 是函数名,中间部 分是函数体
function funcName()
...
end
contact 函数将两个字符串拼接:
function contact(str1, str2)
return str1 .. str2
end

三、在Redis中使用Lua

Redis中执行Lua脚本有两种方法:evalevalsha

1.eval

eval 脚本内容 key个数 key列表 参数列表
eval 命令执行 Lua 脚本过程

2.evalsha

除了使用 eval Redis 还提供了 evalsha 命令来执行 Lua脚本。首先要将 Lua 脚本加载到 Redis 服务端,得到该脚本的 SHA1 校验和, evalsha命令使用 SHA1 作为参数可以直接执行对应 Lua 脚本,避免每次发送 Lua脚本的开销。这样客户端就不需要每次执行脚本内容,而脚本也会常驻 在服务端,脚本功能得到了复用

加载脚本

# redis-cli script load "$(cat lua_get.lua)" 

执行脚本

evalsha 脚本SHA1值 key个数 key列表 参数列表

3.script flush

此命令用于清除Redis内存已经加载的所有Lua脚本

4.script kill

此命令用于杀掉正在执行的 Lua 脚本。如果 Lua 脚本比较耗时,甚至 Lua 脚本存在问题,那么此时Lua 脚本的执行会阻塞 Redis ,直到脚本执行完毕或 者外部进行干预将其结束

四、Lua脚本中调用redis

Lua 可以使用 redis.call 函数实现对 Redis 的访问,例如下面代码是 Lua 使用

redis.call调用了Redissetget操作:

redis.call("set", "hello", "world") 
redis.call("get", "hello")
除此之外 Lua 还可以使用 redis.pcall 函数实现对 Redis 的调用, redis.call 和 redis.pcall的不同在于,如果 redis.call 执行失败,那么脚本执行结束会直接返 回错误,而redis.pcall 会忽略错误继续执行脚本,所以在实际开发中要根据 具体的应用场景进行函数的选择

五、Lua脚本的优点

1.Lua 脚本在 Redis 中是原子执行的,执行过程中间不会插入其他命令。
2.Lua 脚本可以帮助开发和运维人员创造出自己定制的命令,并可以将这
些命令常驻在 Redis 内存中,实现复用的效果。
3.Lua 脚本可以将多条命令一次性打包,有效地减少网络开销
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值