Redis Transaction事务,Lua脚本

Transaction事务

Redis 事务的目的是方便用户一次执行多个命令。执行 Redis 事务可分为三个阶段:

  • 开始事务
  • 命令入队
  • 执行事务

Redis事务特性

Redis 事务具有两个重要特性:

1) 单独的隔离操作

事务中的所有命令都会被序列化,它们将按照顺序执行,并且在执行过的程中,不会被其他客户端发送来的命令打断。

2) 不保证原子性

在 Redis 的事务中,如果存在命令执行失败的情况,那么其他命令依然会被执行,不支持事务回滚机制。

注意:Redis 不支持事务回滚,原因在于 Redis 是一款基于内存的存储系统,其内部结构比较简单,若支持回滚机制,则让其变得冗余,并且损耗性能,这与 Redis 简单、快速的理念不相符合。

Redis事务命令

Redis事务命令
命令说明
MULTI开启一个事务
EXEC执行事务中的所有命令
WATCH key [key ...]在开启事务之前用来监视一个或多个key 。如果事务执行时这些 key 被改动过,那么事务将被打断。
DISCARD取消事务。
UNWATCH取消 WATCH 命令对 key 的监控。

Redis事务应用

您可以把事务可以理解为一个批量执行 Redis 命令的脚本,但这个操作并非原子性操作,也就是说,如果中间某条命令执行失败,并不会导致前面已执行命令的回滚,同时不会中断后续命令的执行(不包含监听 key 的情况)。示例如下:

开启事务
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> INCR 1
QUEUED #命令入队成功
127.0.0.1:6379> SET num 10
QUEUED
#批量执行命令
127.0.0.1:6379> EXEC
1) (integer) 1
2) OK

若您在事务开启之前监听了某个 key,那么您不应该在事务中尝试修改它,否则会导致事务中断。

开启事务之前设置key/value,并监听
127.0.0.1:6379> set www.biancheng.net hello
OK
127.0.0.1:6379> WATCH www.biancheng.net
OK
127.0.0.1:6379> get www.biancheng.net
"hello"
#开启事务
127.0.0.1:6379> MULTI
OK
#更改key的value值
127.0.0.1:6379> set www.biancheng.net HELLO
QUEUED
127.0.0.1:6379> GET www.biancheng.net
QUEUED
#命令执行失败
127.0.0.1:6379> EXEC
(error) EXECABORT Transaction discarded because of previous errors.
#取消监听key
127.0.0.1:6379> UNWATCH 
OK 

 Lua脚本

从 Redis 2.6 版本开始,Redis 使用内置的 Lua 解释器执行脚本,这意味着我们可以直接在 Redis 客户端执行Lua 脚本 ,于此同时 Redis 还非常贴心地提供了用于编写 Lua 脚本的EVAL命令。

第一个Lua脚本命令

Lua 是一种轻量小巧、开源的脚本语言,用标准 C语言编写。其设计目的就是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。它被广泛的应用于:游戏开发、独立应用脚本、Web 应用脚本、扩展和数据库插件等。

Redis 使用EVAL命令编写 lua 脚本,其语法格式如下:

127.0.0.1:6379> EVAL script numkeys key [key ...] arg [arg ...]  

参数说明如下:

  • script: 该参数表示使用 Lua 语言编写的一段脚本程序,该脚本不必定义为 Lua 函数格式;
  • numkeys: 用于指定 key 参数的数量;
  • key [key ...]: 从 EVAL 命令的第三个参数算起,表示脚本中用到的所有 key。这些 key 可以使用全局变量 KEYS 数组来访问,比如 KEYS[1] 、KEYS[2] 以此类推。
  • arg [arg ...]:表示附加参数,在 Lua 语言中通过全局变量 ARGV 数组访问,访问的形式与 KEYS 数组相同,比如 ARGV[1] 、 ARGV[2]。


举一个简单的示例:在 Redis 客户端使用 Lua 语言编写“Hello World”并将其输出。

127.0.0.1:6379> EVAL "return 'Hello world'" 0
"Hello world"

为什么使用Lua脚本

虽然 Redis 官网提供了丰富指令集(200多个),但是在某些特定的领域需要对指令进行扩充,因此 Redis 允许我们使用 Lua 语言以自定义的方式编写脚本命令,这满足了一部分用户的需求。Redis 服务器会以单线程、原子性的方式执行 Lua 脚本,保证 Lua 脚本在处理过程中不会被其他请求中断。

使用 Lua 脚本有如下好处:

  • 减少网络开销:可以将多个请求通过脚本的形式一次发送,从而减少网络时延,比如本来 10 次网络请求,我们就可以通过 Lua 脚本一次性完成。
  • 原子操作:Redis 会将整个脚本作为一个整体执行,中间不会被其他请求干扰。因此在脚本运行过程中无需使用事务。
  • 脚本复用:客户端发送的脚本会一直存储在 Redis 中,这样其他客户端只需对这个脚本稍作修改就可以达到复用的目的,极大地提升了编写脚本的效率。

常用脚本命令

Redis脚本命令
命令说明
EVAL script numkeys key [key ...] arg [arg ...]使用 Lua 解释器执行脚本。
EVALSHA sha1 numkeys key [key ...] arg [arg ...]Lua 解释器根据 sha1 校验码执行脚本。
SCRIPT EXISTS script [script ...]查看指定的脚本是否保存在于缓存当中。
SCRIPT FLUSH从脚本缓存中移除所有脚本。
SCRIPT KILL杀死当前正在运行的 Lua 脚本。
SCRIPT LOAD script将脚本 script 添加到脚本缓存中,但不马上执行这个脚本。

基本命令应用

EVAL 命令使用示例:

redis 127.0.0.1:6379> EVAL "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" 2 key1 key2 first second   
1) "key1"  
2) "key2"  
3) "first"  
4) "second" 

 

Lua脚本是一种轻量级的脚本语言,常用于嵌入式系统和游戏开发中。它具有以下特点: 1. 简洁高效:Lua脚本语法简单,学习曲线低,执行速度快。 2. 可扩展性:Lua支持通过C/C++扩展其功能,可以方便地与其他语言进行交互。 3. 跨平台性:Lua脚本可以在多个操作系统上运行,包括Windows、Linux、Mac等。 管道(Pipeline)是一种用于在Redis数据库中执行多个命令的机制。它的优点包括: 1. 减少网络开销:通过将多个命令打包发送到Redis服务器,减少了网络通信的开销。 2. 原子性操作:Redis的管道可以保证多个命令的原子性执行,避免了并发操作带来的问题。 3. 提高性能:通过批量执行多个命令,可以提高Redis的性能。 事务Transaction)是Redis中用于执行一系列命令的机制,它的优点包括: 1. 原子性操作:Redis事务可以保证一系列命令的原子性执行,要么全部执行成功,要么全部失败。 2. 高效性能:事务中的命令在提交之前不会立即执行,而是在提交时一次性执行,减少了网络通信的开销。 3. 锁定资源:在事务执行期间,Redis会对相关资源进行锁定,避免了其他客户端对同一资源的并发访问。 然而,管道和事务也存在一些缺点: 1. 管道的原子性:虽然管道可以批量执行多个命令,但无法保证这些命令的原子性执行,如果其中某个命令执行失败,后续命令可能会继续执行。 2. 事务的回滚:虽然事务可以保证一系列命令的原子性执行,但如果在事务执行过程中出现错误,整个事务会被回滚,导致之前执行的命令无效。 3. 网络延迟:由于管道和事务需要将多个命令打包发送到Redis服务器,如果网络延迟较高,可能会导致整体性能下降。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值