KV型内存数据库Redis(6)

WATCH的监视到EXEC开始执行事务为止,因此WATCH不会阻止在事务中修改被监视的键。

127.0.0.1:6379> WATCH lock OK 127.0.0.1:6379> MULTI OK 127.0.0.1:6379> SET lock 1 QUEUED 127.0.0.1:6379> GET lock QUEUED 127.0.0.1:6379> EXEC 1) OK 2) "1"

WATCH命令主要用于保证事务开始执行时的状态正确,典型的"秒杀"应用中,多个客户端首先使用WATCH命令监视锁,随后执行购买事务。

在WATCH命令和事务执行之间若有其它客户端成功执行事务,使得锁发生变化则当前客户端无法执行事务,即抢购失败。

示例(伪代码):

> SET remains 100 > SET empty 0 > WATCH empty # 此时可能已有其它客户端抢先执行事务 > MULTI > DECR remains > if (remains == 0): SET empty 1 # 修改锁,阻止其它客户端抢购 # 此处还应有写购买记录和修改余额等操作 > EXEC

UNWATCH命令用于取消WATCH命令对所有key的监视。

pipeline

Redis采用请求/响应式协议进行与服务端的交互,通常情况下一次请求只包含一条指令。

pipeline模式可以一次请求执行多条指令,减少IO的开销。

这里给出一个Python客户端使用pipeline的示例:

>>> connect = redis.Redis(host='127.0.0.1', port=6379) >>> pipe = connect.pipeline(transaction=False) >>> pipe.set("x", "1") Pipeline<ConnectionPool<Connection<host=127.0.0.1,port=6379,db=0>>> >>> pipe.set("y", "2") Pipeline<ConnectionPool<Connection<host=127.0.0.1,port=6379,db=0>>> >>> pipe.execute() [True, True]

pipeline不是原子性的,执行过程中可能会有来自其他客户端的指令执行。不要使用pipeline发送多条SET/GET指令代替MSET/MGET。

pipeline会占据整个连接,在完成前无法执行其它指令。客户端应配置好连接池防止被pipeline阻塞。

发布订阅

Redis的发布订阅模式允许客户端监听某些频道,发布者在该频道上发布消息后,消息会被推送到订阅了该频道的客户端。

发布订阅模式允许服务端主动通知客户端,无需客户端轮询状态变化,因此Redis可以实现消息队列的功能。

首先打开一个客户端订阅chat频道:

SUBSCRIBE chat

打开另一个客户端发布一条消息:

127.0.0.1:6379> PUBLISH chat "Hi there" (integer) 1

PUBLISH命令的返回值是接收到该消息的订阅者的数量。

订阅了该频道的客户端会受到消息推送:

127.0.0.1:6379> SUBSCRIBE chat Reading messages... (press Ctrl-C to quit) 1) "subscribe" 2) "chat" 3) (integer) 1 1) "message" 2) "chat" 3) "Hi there"

UNSUBSCRIBE命令用于取消订阅的频道:

UNSUBSCRIBE [channel [channel ...]]

PSUBSCRIBE和PUNSUBSCRIBE可以使用模式匹配来订阅和取消订阅频道。

PSUBSCRIBE pattern [pattern ...] PUNSUBSCRIBE [pattern [pattern ...]] SCAN

KEYS命令处理大数据库或者SMEMBERS命令处理大集合时可能阻塞数据库数秒之久,这在生产环境下是无法介绍的。

SCAN和SSCAN命令可用分页迭代的方式遍历大数据集,每次迭代仅返回少量数据不会阻塞服务器:

SCAN cursor [MATCH pattern] [COUNT count] 127.0.0.1:6379> SCAN 0 1) "20" 2) 1) "1125677473485562817" 2) "5537448729649573447" 3) "2854796168938416843" 4) "7439346733403784473" 5) "-6333572342266574627" 6) "-9080851294203022766" 7) "1125677473485562817" 8) "820904952218043889" 9) "1125677473485562827" 10) "1125677473485562837" 127.0.0.1:6379> SCAN 20 1) "0" 2) 1) "1125677473485562817" 2) "-1053519331922297522" 3) "7439346733403784473" 4) "-2594669955628668552" 5) "-4053026386633294784" 6) "7439346733403784473" 7) "-1053519331922297522" 8) "2649406091729268560" 9) "7439346733403784473" 10) "1053519331903186673"

SCAN命令的返回值包含两部分,第一部分为下次迭代的游标,第二部分为本次迭代取得的键。

SCAN cursor MATCH pattern可以像KEYS命令一样使用通配符筛选需要迭代的键。SCAN cursor COUNT count可以设置每次迭代返回键的数量。

使用0作为游标表示开始一次新的迭代,当SCAN命令返回的游标为0时表示本次迭代已经结束。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/e09f70bdc9085347e509b9c215eb523f.html