事务
简介
redis的事务(transaction)是一组命令的集合。
原理:先将属于一个事务的命令发给Redis,然后再让Redis执行这些命令。例如:
注意:redis的运行错误是不支持回滚功能的,运行错误是指在命令执行时出现的错误
命令
1.创建事务
multi //指明事务的开始
...... //事务中的命令
exec //事务的结束
2.watch命令
watch key [key ....] //监控一个或多个键,一旦其中一个键被修改或删除,之后的事务 就不会执行
生存时间
命令
1.设置一个键的生存时间
expire key seconds //seconds表示键的生存时间,单位是秒
pexpire key millisecond //millisecond键的生存时间,单位是毫秒
//成功返回1,设置失败或键不存在则返回0
2.查看一个键还有多长时间会被删除
ttl key //当键不存在返回-2,没有为键设置生存时间时返回-1,
3.取消键的生存时间设置(即将键恢复成永久)
persist key
//使用set等命令为键赋值时同时也会清除键的生存时间,其它只对键值操作的命令(如incr,lpush,hset,zrem)均不会影响键的生存时间
缓存
1.设置Redis最大可用内存(单位字节),超出则会依据不同的策略删除不需要的键
配置文件:maxmemory
2.设置超出内存的删除策略
配置文件:maxmemory-policy
排序
1.sort
可以对列表类型、集合和有序集合类型的键进行排序,并且可以完成关系数据库中连接查询相关类似的任务
sort key [BY pattern] [LIMIT offset count] [GET pattern [GET pat
例:
降序:sort key desc
- by参数:通过关联外部键值进行排序,外部键可以是字符串类型也可以是散列类型,语法(键名->字段名),一个sort命令中只有一个by参数
例:
其中 * 是对每一个元素使用元素的值替换参考键的字段名
==注意的是,sort不会对参考键为常量的值进行排序,而判断参考键是否为常量的依据是参考键中是否有"*" == - GET参数:get参数不影响排序,它作用是使用sort命令的放回结果不再是元素自身的值,而是GET参数中的指定值,支持字符串类型和散列类型,使用 * 作为占位符,一个sort命令中可以有多个get参数
例1:
例2:
get # 表示放回元素本身的值 - store参数:sort是直接返回排序结果,store参数可以把结果保存到指定键中,键的类型是list
例:
任务队列
使用Redis的列表类型,使用LPUSH命令加入队列,使用BRPOP命令取出队列中的任务,与RPOP命名不同的是,当列表中没有元素时BRPOP命令会一直阻塞连接,直到有新元素加入。
BRPOP命令接受两个参数,第一个键名,第二个超时时间(单位秒),如果超时时间设置为“0”,表示一直等待,在超过设置时间后还没获取新元素则返回nil。
BLPOP与BRPOP的区别在与从队列的左边取值。
队列优先级
BRPOP命令的完整格式为:BRPOP key [key …] timeout;
意义是同时检测多个键,如果所有键都没有元素则阻塞,如果其中一个键有元素则从该键中弹出元素,当key1、key2…keyn同时有值是,则优先弹出左边键的值
“发布/订阅”模式
该模式下有三种角色:发布者(publish)、订阅者(subscribe)、主题(channel)
订阅者可以订阅多个主题(channel),发布者可以向指定主题(channel)发送消息;所有订阅此主题的订阅者都会收到此消息;
- 发布者发送消息到主题(channel)
publish channel message //channel主题名 message消息内容,返回值为订阅该主题的订阅者数量
注意:发出去的消息不会持久化,所以订阅者只能收到后续发布的主题消息,之前的接受不到;
- 订阅者接受主题的消息
subscribe channel //主题名
进入订阅状态后客户端可能收到三种类型的回复。每种类型的回复都包含3个值,第一个
值是消息的类型,根据消息类型的不同,第二、三个值的含义也不同。消息类型可能的取值有:
(1)Subscribe。表示订阅成功的反馈信息。第二个值是订阅成功的频道名称,第三个值是
当前客户端订阅的频道数量。
(2)message。这个类型的回复是我们最关心的,它表示接收到的消息。第二个值表示产生
消息的频道名称,第三个值是消息的内容。
(3)unsubscribe。表示成功取消订阅某个频道。第二个值是对应的频道名称,第三个值是当
前客户端订阅的频道数量,当此值为0时客户端会退出订阅状态,之后就可以执行其他非“发
布/订阅”模式的命令了。
- 取消订阅的主题
unsubscribe [channel [channel ...]]
管道-pipeline
本部分来自:https://www.cnblogs.com/xiaoxiongcanguan/p/9954254.html
介绍
redis采用的是CS架构,客户端与服务器端通过tcp协议进行连接通信,因此无论是发出请求还是接收响应,都必须经过网络传输。在tcp连接过程中,客户端和服务器端是通过阻塞式的一问一答方式进行通信的,即客户端必须接收到服务端完整的响应,才能进行后续请求。
有时我们会在短时间内发送大量互不依赖的命令(例如:后执行的命令不需要使用前面返回的结果)。由于网络传输不可避免的会造成一定的延迟,特别是在跨机器远程访问redis的时候,如果使用常规的方式,一条命令对应一次请求和响应的话,大量命令累计的延迟会显得很高。redis的设计者考虑到这一点,在底层的通信协议上,通过支持"管道(pipeline)"来解决这一问题。
简单示例:
普通命令:3次请求/响应
client:INCR num001;
server:1;
client:INCR num001;
server:2;
client:INCR num001;
server:3;
管道命令:1次请求/响应
client:INCR num001;
client:INCR num001;
client:INCR num001;
server:1;
server:2;
server:3;
redis管道可以在一次tcp的请求中同时发送多条命令,并且将响应结果一次性的返回给客户端。对于既定数量的命令请求,redis管道通过减少客户端和服务器端的通信次数,来达到减少通信传输中往返时间的目的,提高效率。
注意事项
1.由于redis的管道要求服务器一次性的将请求返回,因此redis服务端只能将靠前命令处理的结果暂时缓存起来。如果管道一次响应的数据量过多(大规模查询之类的),可能会对redis服务器的内存造成较大的压力。因此,管道批量处理的命令数量并不是越多越好,需要结合实际需求,合理的决定一次管道批处理命令的数量。
2.redis的管道在客户端通常会设置一个命令缓冲区来存储即将被批量发送的命令,当缓冲区被填满时,才会一次性的将缓冲区的命令发送。这里需要注意的一点是:当业务上的同一批命令使用管道进行请求时,如果最后剩余的命令无法填满缓冲区,如果不使用相应的flush操作,这些命令将不会被发送出去,而是保留在命令缓冲区等待新的命令来填满缓冲区。
总结
redis的管道可以将多个命令打包,一次性的发送给服务器端处理,当命令之间不存在依赖关系时,相比于一条命令一次请求的普通操作方式,管道的操作几乎是对使用者透明的。
和redis的事务类似,redis管道能完成的操作也能够被更加灵活的redis脚本实现,但是脚本的可读性不强、可维护性差。个人认为,如果批量处理的命令之间不存在依赖关系时,优先使用管道;反之,则只能使用脚本了。