Redis开发运维实践专题功能之事务

3.2 事务

用Multi(Start Transaction)、Exec(Commit)、Discard(Rollback)实现。 在事务提交前,不会执行任何指令,只会把它们存到一个队列里,不影响其他客户端的操作。在事务提交时,批量执行所有指令。 一般情况下redis在接受到一个client发来的命令后会立即处理并返回处理结果,但是当一个client在一个连接中发出multi命令后,这个连接会进入一个事务上下文,该连接后续的命令并不是立即执行,而是先放到一个队列中。当从此连接受到exec命令后,redis会顺序的执行队列中的所有命令。并将所有命令的运行结果打包到一起返回给client.然后此连接就结束事务上下文。

Redis还提供了一个Watch功能,你可以对一个key进行Watch,然后再执行Transactions,在这过程中,如果这个Watched的值进行了修改,那么这个Transactions会发现并拒绝执行。

使用discard命令来取消一个事务。

注意:redis只能保证事务的每个命令连续执行(因为是单线程架构,在执行完事务内所有指令前是不可能再去同时执行其他客户端的请求的,也因此就不存在"事务内的查询要看到事务里的更新,在事务外查询不能看到"这个让人万分头痛的问题),但是如果事务中的一个命令失败了,并不回滚其他命令。另外,一个十分罕见的问题是当事务的执行过程中,如果redis意外的挂了。只有部分命令执行了,后面的也就被丢弃了。注意,如果是笔误,语法出现错误,则整个事务都无法执行。

一个简单案例表明出错也不会回滚:

127.0.0.1:6379> del q1
(integer) 0
127.0.0.1:6379> exists q1
(integer) 0
127.0.0.1:6379> multi
OK
127.0.0.1:6379> rpush q1 bar
QUEUED
127.0.0.1:6379> scard q1
QUEUED
127.0.0.1:6379> exec
1) (integer) 1
2) (error) WRONGTYPE Operation against a key holding the wrong kind of value
127.0.0.1:6379> exists q1
(integer) 1

当然如果我们使用的append-only file方式持久化,redis会用单个write操作写入整个事务内容。即是是这种方式还是有可能只部分写入了事务到磁盘。发生部分写入事务的情况下,redis重启时会检测到这种情况,然后失败退出。可以使用redis-check-aof工具进行修复,修复会删除部分写入的事务内容。修复完后就能够重新启动了。


Redis开发运维实践指南

本文为《Redis开发运维实践指南》内容,该书作者为黄鹏程,已授权转载。

时间: 2024-08-01 01:20:59

Redis开发运维实践专题功能之事务的相关文章

Redis开发运维实践专题功能之发布订阅

3.4 发布订阅 redis作为一个pub/sub server,在订阅者和发布者之间起到了消息路由的功能.订阅者可以通过subscribe和psubscribe命令向redis server订阅自己感兴趣的消息类型,redis将消息类型称为频道(channel).当发布者通过publish命令向redis server发送特定类型的消息时.订阅该消息类型的全部client都会收到此消息.这里消息的传递是多对多的.一个client可以订阅多个 channel,也可以向多个channel发送消息.

Redis开发运维实践专题功能之排序

3.1 排序 redis支持对list,set和sorted set元素的排序.排序命令是sort 完整的命令格式如下: + SORT key [BY pattern] [LIMIT start count] [GET pattern] [ASC|DESC] [ALPHA] [STORE dstkey] 复杂度为O(N+M*log(M)).(N是集合大小,M 为返回元素的数量) 说明: [ASC|DESC] [ALPHA]: sort默认的排序方式(asc)是从小到大排的,当然也可以按照逆序或者

Redis开发运维实践专题功能之流水线

3.3 流水线 利用流水线(pipeline)的方式从client打包多条命令一起发出,不需要等待单条命令的响应返回,而redis服务端会处理完多条命令后会将多条命令的处理结果打包到一起返回给客户端: cat data.txt | redis-cli –pipe 在选择开源redis开发库时需要着重注意是否支持pipeline,常见的jedis可以支持. 在部署架构是网络多跳的时候需要注意使用pipeline提高处理效率. Redis开发运维实践指南 本文为<Redis开发运维实践指南>内容,

Redis开发运维实践开发者设计规范之典型使用场景参考

4.6 典型使用场景参考 下面是Redis适用的一些场景: 1. 取最新 N 个数据的操作 比如典型的取你网站的最新文章,通过下面方式,我们可以将最新的 5000条评论的ID放在Redis的List集合中,并将超出集合部分从数据库获取. 使用LPUSH latest.comments命令,向 list集合中插入数据 插入完成后再用 LTRIM latest.comments 0 5000 命令使其永远只保存最近5000个 ID 然后我们在客户端获取某一页评论时可以用下面的逻辑 FUNCTION

Redis开发运维实践上线部署规划之网卡rps设置

5.2 网卡RPS设置 RPS就是让网卡使用多核CPU的.传统方法就是网卡多队列(RSS,需要硬件和驱动支持),RPS则是在系统层实现了分发和均衡.如果对redis网络处理能力要求高或者在生产上发现cpu0的,可以在OS层面打开这个内核功能. 设置脚本: #!/bin/bash # Enable RPS (Receive Packet Steering) rfc=32768 cc=$(grep -c processor /proc/cpuinfo) rsfe=$(echo $cc*$rfc |

Redis开发运维实践数据操作之集合操作

2.4.1 添加元素 sadd key member 成功返回1,如果元素以及在集合中返回0,key对应的set不存在返回错误 2.4.2 移除元素 srem key member 成功返回1,如果member在集合中不存在或者key不存在返回0,如果key对应的不是set类型的值返回错误 2.4.3 删除并返回元素 spop key 如果set是空或者key不存在返回nil 2.4.4 随机返回一个元素 srandmember key 同spop,随机取set中的一个元素,但是不删除元素 2.

Redis开发运维实践上线部署规划之内存规划

5.1 内存.CPU规划 一定要设置最大内存maxmemory参数,否则物理内存用爆了就会大量使用Swap,写RDB文件时的速度很慢.注意这个参数指的是info中的used_memory,在一些不利于jmalloc的时候,内存碎片会很大. 多留55%内存是最安全的.重写AOF文件和RDB文件的进程(即使不做持久化,复制到Slave的时候也要写RDB)会fork出一条新进程来,采用了操作系统的Copy-On-Write策略(子进程与父进程共享Page.如果父进程的Page-每页4K有修改,父进程自

Redis开发运维实践数据操作之列表操作

2.3.1 添加元素 lpush key string 在key对应list的头部添加字符串元素,返回1表示成功,0表示key存在且不是list类型.注意:江湖规矩一般从左端Push,右端Pop,即LPush/RPop. lpushx 也是将一个或者多个value插入到key列表的表头,但是如果key不存在,那么就什么都不在,返回一个false[rpushx也是同样] rpush key string 同上,在尾部添加 linsert 在key对应list的特定位置之前或之后添加字符串元素 ,

Redis开发运维实践指南数据操作之key操作

数据操作 熟悉每个数据操作前一定要明白每个操作都是代价,以时间复杂度和对应查询集或者结果集大小为衡量.时间复杂度收敛状况如下: 2.1.1 列出key keys *user* keys * 有3个通配符 *, ? ,[] *: 通配任意多个字符 ?: 通配单个字符 []: 通配括号内的某1个字符 注:生产已经禁止.更安全的做法是采用scan,原理和操作如下: 针对Keys的改进,支持分页查询Key.在迭代过程中,Keys有增删时不会要锁定写操作,数据集完整度不做任何保证,同一条key可能会被返回