Redis事务

事务

redis的事务是一组命令的集合。事务同命令一样都是redis的最小执行单元,一个事务中的命令要么执行要么都不执行。

首先需要multi命令来开始事务,用exec命令来执行事务。

127.0.0.1:6379> multi
OK
127.0.0.1:6379> hset user:1 name xiaoming
QUEUED
127.0.0.1:6379> hset user:1 name daxiong
QUEUED
127.0.0.1:6379> exec
1) (integer) 0
2) (integer) 0
127.0.0.1:6379> hgetall user:1
1) "name"
2) "daxiong"
3) "score"
4) "61"

multi代表事务的开始,返回ok表示成功;

exec代表事务的执行,返回各个命令的执行结果;

在multi和exec中间添加需要执行的命令。

在multi开始后,所有命令都不会执行,而是全部暂时保存起来,在执行exec命令后会按照命令保存的顺序依次执行各个命令。

如果事务执行过程中存在失败的情况下(某一个命令执行失败后其他命令会继续执行),需要开发人员自行处理后果。

注意:redis不支持回滚操作,导致redis的错误异常需要开发人员处理。

watch

watch命令可以监控一个或多个键值的变化,一旦其中一个键被改变,之后的事务就不会执行,而且监控会一直持续到exec命令。

127.0.0.1:6379> set key 1
OK
127.0.0.1:6379> watch key
OK
127.0.0.1:6379> set key 2
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set key 3
QUEUED
127.0.0.1:6379> exec
(nil)
127.0.0.1:6379> get key
"2"

生存时间

(1)设置key的超时时间,超时后redis会自动删除给key值,类似于memcache中的超时时间。

expire     key     seconds
//设置成功返回1,失败返回0

127.0.0.1:6379> set session:aabb uid1122
OK
127.0.0.1:6379> expire session:aabb 300
(integer) 1
127.0.0.1:6379> del session:aabb
(integer) 1
127.0.0.1:6379> expire session:aabb 300
(integer) 0

127.0.0.1:6379> expire session:aabb 300
(integer) 1
127.0.0.1:6379> ttl session:aabb
(integer) 290

(2)查询剩余超时时间

ttl     key
127.0.0.1:6379> expire session:aabb 300
(integer) 1
127.0.0.1:6379> ttl session:aabb
(integer) 290

(3)取消超时时间

127.0.0.1:6379> get session:aabb
"300"
127.0.0.1:6379> ttl session:aabb
(integer) 280
127.0.0.1:6379> persist session:aabb
(integer) 1
127.0.0.1:6379> ttl session:aabb
(integer) -1

(4)如果使用设置相关的命令,会取消该键的超时间

缓存数据

在某些情况下,需要缓存一部分网站数据,而网站数据由需要持续的更新(假如需要两个小时更新一次),那么可以采用redis进行缓存这部分数据,设置数据的超时时间为2小时,每当有请求访问的时候首先到redis中查找该数据是否存在,如果存在直接读取,如果不存在的话重新从数据库中读取该数据加载到redis中。

在缓存数据的时候需要考虑到被缓存数据的大小,如果缓存数据较大,会占用过多的内存资源,有必要在配置文件中限制内存的使用大小(maxmemory)。

当超过maxmemory的限制后,redis会根据maxmemory-policy参数指定的策略(包括LRU等算法)来删除不需要的键。

排序

sort命令支持对集合类型、类表类型、有序集合类型进行排序。

127.0.0.1:6379> lpush list 1 2 6 3 4 9 8
(integer) 7
127.0.0.1:6379> sort list
1) "1"
2) "2"
3) "3"
4) "4"
5) "6"
6) "8"
7) "9"

可以对有序集合的值进行排序:

127.0.0.1:6379> zadd set 50 2 40 3 20 1 60 5
(integer) 4
127.0.0.1:6379> sort set
1) "1"
2) "2"
3) "3"
4) "5"

sort命令可以添加desc来实现倒序排序

127.0.0.1:6379> sort set desc
1) "5"
2) "3"
3) "2"
4) "1"

BY参数

很多时候我们需要根据ID对应的对象的某一个属性进行排序,那么如何才能把多个不同的数据进行关联查询呢?

(1)首先,向userids中添加三个用户id

127.0.0.1:6379> lpush userids 1 2 3
(integer) 3

(2)其次,分别对三个用户添加分数

127.0.0.1:6379> set user_score_1 50
OK
127.0.0.1:6379> set user_score_2 30
OK
127.0.0.1:6379> set user_score_3 70
OK

(3)最后,使用sort、by命令来对对用户按照默认情况以及分数的递增和递减进行排序。

127.0.0.1:6379> sort userids
1) "1"
2) "2"
3) "3"
127.0.0.1:6379> sort userids by user_score_*
1) "2"
2) "1"
3) "3"
127.0.0.1:6379> sort userids by user_score_* desc
1) "3"
2) "1"
3) "2"

GET参数

get参数并不影响排序,它的作用是使sort命令返回的结果不再是元素自身的值,而是get参数中指定的键值,同by参数一样,支持字符串类型和散列类型的键。

127.0.0.1:6379> sort userids by user_score_* get user_name_*
1) "xiaoming"
2) "daxiong"
3) "xiaohong"
127.0.0.1:6379> sort userids by user_score_* desc get user_name_*
1) "xiaohong"
2) "daxiong"
3) "xiaoming"

STORE参数

store参数用于结果保存。

sort命令是redis的复杂命令之一,使用不好会造成性能的瓶颈。

sort命令的时间复杂度是O(n+mlog(m)),其中n是排序列表(集合和有序集合)中元素的个数,m是返回元素的个数。Redis在排序前会建立一个长度为n的的容器来存储待排序元素,虽然是一个临时的过程,但是多个较大数据的排序操作则会严重影响系统的性能。

因此,在开发中需要注意:

(1)尽可能减少排序键中的元素个数,降低n

(2)使用Limit参数只获取需要的数据,降低n

(3)如果要排序的数据量较大,尽可能使用store名来缓存结果。

任务队列

任务队列一般适用于生产者和消费者之间通信的,那么在redis中很容易想到使用列表类型来实现任务队列,具体方法是创建一个任务队列,生产者主动lpush数据,而消费者去rpop数据,保持一个先进先出的循序。

但是这样存在一个问题,消费者需要主动去请求数据,周期性的请求会造成资源的浪费,因此,redis提供了一个brpop的命令来解决这个问题。

BRPOP     key     timeout

brpop命令接收两个参数,第一个参数key为键值,第二个参数timeout为超时时间。BRPOP命令取数据时候,如果暂时不存在数据,该命令会一直阻塞直到达到超时时间。如果timeout设置为0,那么就会无限等待下去。

优先级队列

基于任务队列,如何实现优先级队列呢?

那么可以选择多个任务队列,而每个任务队列的任务优先级是不同的。

redis提供了下面的命令,会从左边第一个key开始读下去知道返回一个数据。

brpop key [key...] timetout

发布/订阅模式

redis提供了rabitmq类似的发布订阅模式,通过生产者使用下面的命令来发布消息,

PUBLISH     CHANNEL     MESSAGE

消费者通过下面的消息来订阅消息,

SUBSCRIBE     CHANNEL     MESSAGE

生产者:

#向channel.test发布消息
127.0.0.1:6379> publish channel.test hello
(integer) 0 #返回0表明订阅者为0,没有发布消息
127.0.0.1:6379> publish channel.test hello
(integer) 1 #返回n表明订阅者为n,成功发布给1个消费者

消费者:

#订阅channel.test消息
127.0.0.1:6379> subscribe channel.test
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "channel.test"
3) (integer) 1
#接收到来自channel.test的消息
1) "message"
2) "channel.test"
3) "hello"

管道

redis的底层通信协议对管道提供了支持。通过管道可以一次性发送多条命令并在执行完后一次性将结果返回,当一组命令中每条命令都不依赖之前命令的执行结果时就可以将这组命令一起通过管道发出。管道通过减少客户端与redis的通信次数来实现降低往返实验累计值的目的。

节省空间

(1)精简键名和键值

(2)redis为每种数据类型提供了两种内部编码。例如散列类型的存储是通过散列表来实现的,redis会根据数据的多少来选择编码类型,当数据较少的时候会采用紧凑但性能稍差的内部编码方式,而数据变多时会把编码方式改为散列表。

时间: 2024-12-17 00:52:42

Redis事务的相关文章

Redis系列六 Redis事务

Redis事务 1.介绍 在Redis事务中可以一次执行多个命令,本质是一组命令的集合.一个事务中的所有命令都会序列化,按顺序地串行化执行而不会被其它命令插入,不许加塞. 2.事务的作用 一个队列中,一次性.顺序性.排他性的执行一系列命令. 3.事物执行五中情况 case1:正常执行 执行exec全部成功 Case2:放弃事务 执行Discard Case3:全体连坐 在向事物队列中添加命令的时候报错,然后执行Exec会全部失败. Case4:冤头债主 在向事物队列中添加命令的时候没有报错,但在

redis事务(转载)

原文地址:http://blog.csdn.net/hechurui/article/details/49508749 Redis事务 首先,Redis本身是单线程的. redis中的事务(transaction)是一组命令的集合.事务同命令一样都是Redis最小的执行单位,一个事务中的命令要么都执行,要么都不执行.Redis事务的实现需要用到 MULTI 和 EXEC 两个命令,事务开始的时候先向Redis服务器发送 MULTI 命令,然后依次发送需要在本次事务中处理的命令,最后再发送 EXE

Redis 事务

Redis 事务可以一次执行多个命令, 并且带有以下两个重要的保证: 事务是一个单独的隔离操作:事务中的所有命令都会序列化.按顺序地执行.事务在执行的过程中,不会被其他客户端发送来的命令请求所打断. 事务是一个原子操作:事务中的命令要么全部被执行,要么全部都不执行. 一个事务从开始到执行会经历以下三个阶段: 开始事务. 命令入队. 执行事务. 实例 以下是一个事务的例子, 它先以 MULTI 开始一个事务, 然后将多个命令入队到事务中, 最后由 EXEC 命令触发事务, 一并执行事务中的所有命令

Redis学习笔记(4) Redis事务、生存时间及排序

1. Redis事务 Redis中的事务(transaction)是一组命令的集合,一个事务中的命令要么都执行,要么都不执行.事务的原理是先将属于一个事务的命令发送给Redis,然后再让Redis依次执行这些命令. 127.0.0.1:6379> multi OK 127.0.0.1:6379> sadd user:1:following 2 QUEUED 127.0.0.1:6379> sadd user:2:followers 1 QUEUED 127.0.0.1:6379>

(6)redis 事务

redis对事务的支持目前还比较简单.redis只能保证一个client发起的事务中的命令可以连续的执行,而中间不会插入其他client的命令. 由于redis是单线程来处理所有client的请求的所以做到这点是很容易的.一般情况下redis在接受到一个client发来的命令后会立即处理并 返回处理结果,但是当一个client在一个连接中发出multi命令有,这个连接会进入一个事务上下文,该连接后续的命令并不是立即执行,而是先放到一 个队列中.当从此连接受到exec命令后,redis会顺序的执行

redis学习之——Redis事务(transactions)

Redis事务:可以一次执行多个命令,本质是一组命令的集合.一个事务中的,所有命令都会序列化,按顺序地串行化执行而不会被其它命令插入,不许加塞. 常用命令:MULTI  开启事务  EXEC 提交事务. DISCARD  放弃事务  WATCH  监控事务  UNWATCH   取消监控事务 case1:正常执行                                                   case2:放弃事务 case3:全体连坐                     

Redis事务使用方法

Redis事务 Redis事务是一组命令的集合,也是Redis的最小执行单位之一.一个事务的所有命令,要么都执行,要么都不执行.Redis能保证事务执行期间不会有其他命令插入. 相关命令 命令 格式 说明 DISCARD DISCARD 取消事务 EXEC EXEC 执行事务中的命令 MULTI MULTI 标记一个事务的开始 UNWATCH UNWATCH 取消对key的监视 WATCH WATCH key [key ...] 监视一个或多个key 执行MULTI后,在EXEC或DISCARD

Redis事务的分析及改进

Redis事务的分析及改进 Redis的事务特性 数据ACID特性满足了几条? 为了保持简单,redis事务保证了其中的一致性和隔离性: 不满足原子性和持久性: 原子性 redis事务在执行的中途遇到错误,不会回滚,而是继续执行后续命令:(违反原子性) 事务可以理解为一个打包的批量执行脚本,但批量指令并非原子化的操作: 中间某条指令的失败不会导致前面已做指令的回滚,也不会造成后续的指令不做: 比如: redis 127.0.0.1:7000> multi OK redis 127.0.0.1:7

Redis订阅和发布模式和Redis事务

-------------------Redis订阅和发布模式------------------- 1.概念 Redis 发布订阅(pub/sub)是一种消息通信模式: 发送者(pub)发送消息, 订阅者(sub)接收消息. Redis 客户端可以订阅任意数量的频道. 2.subscribe channel:订阅个指定频道的信息 3.publish channel message:将信息message 发送到指定的频道channel 4.应用场景 1.今日头条订阅号.微信订阅公众号.新浪微博关

REDIS 事务机制

基本事务操作: 任何数据库都必须要保证一种原子执行操作:最基本的原子执行操作肯定是需要提供: 举一个例子来说明: 当对某个Key 做一个统计: 可能不同的Client做它那部分的统计,一段时间后,服务器端需要得出那个key的具体值 Client1: GET number number = number +N1; SET number number+N1; Client2: GET number number = number +N2; SET number number+N2; 原本来讲 ,期望