redis订阅发布模式


redis 可以做消息中间件(MQ =message queue),通常通过订阅发布模式来实现(消息订阅发布模式),还可以基本数据类型Lists实现(点到点模式,可以使用lpush,rpop 实现消息 先进先出)。


好处: 异步 ,解耦 , 削峰

redis订阅发布(生产/消费)模式具体实现:

启动redis服务端:

/usr/redis/bin/redis-server /usr/redis/bin/redis.conf

启动redis客户端:

/usr/redis/bin/redis-cli -h 192.168.170.31

模拟订阅者,订阅某一个或者多个管道(订阅2个频道(管道)):

192.168.170.31:6379> subscribe channela channelb

新建会话,再启动redis一个客户端:

/usr/redis/bin/redis-cli -h 192.168.170.31

模拟发布者,发布消息到一个管道:

192.168.170.31:6379> publish channela hello1

多个发布者和订阅者:

启动多个会话 模拟多个订阅者:

/usr/redis/bin/redis-cli -h 192.168.170.31 
 
 
192.168.170.31:6379> subscribe channela channelb 
 
 
/usr/redis/bin/redis-cli -h 192.168.170.31 
  192.168.170.31:6379> subscribe channela channelc 
 
 
/usr/redis/bin/redis-cli -h 192.168.170.31 
 
 
192.168.170.31:6379> subscribe channelb channeld

启动多个会话 模拟多个发布者:

/usr/redis/bin/redis-cli -h 192.168.170.31 
 
 
192.168.170.31:6379> publish channela hello1 
 
 
(integer) 1 
 
 
192.168.170.31:6379> publish channela hello2 
 
 
(integer) 1
 
 

 
 

/usr/redis/bin/redis-cli -h 192.168.170.31 
 
  
192.168.170.31:6379> publish channela hi1 
 
  
(integer) 2 
 
  
192.168.170.31:6379> publish channelb hi11 
 
  
(integer) 2 
 
  
192.168.170.31:6379> publish channelc hi111 
 
  
(integer) 1
 
  

 
  

/usr/redis/bin/redis-cli -h 192.168.170.31 
 
   
192.168.170.31:6379> publish channela helloqy14811 
 
   
(integer) 2 
 
   
192.168.170.31:6379> publish channelb helloqy14822 
 
   
(integer) 2 
 
   
192.168.170.31:6379> publish channelc helloqy14833 
 
   
(integer) 1 
 
   
192.168.170.31:6379> publish channeld helloqy14844




数据库(默认分为16个库)和作用域:

启动客户端:

/usr/redis/bin/redis-cli -h 192.168.170.31

切换数据库:

select 10

在第11库订阅频道:

192.168.170.31:6379[10]> subscribe channela

发布者使用第1库和第3库 发布消息:

192.168.170.31:6379> publish channela hello1111 
 
 
(integer) 2 
  192.168.170.31:6379> select 2 
 
 
OK 
 
 
192.168.170.31:6379[2]> publish channela hello2222 
 
 
(integer) 2

在第1库和第3库 发送的消息,在第11库订阅中都能看到

模糊匹配订阅:


客户端可以订阅全风格的模式以便接收所有来自能匹配到给定模式的频道的消息。


psubscribe p=pattern 模式


启动一个客户端,模拟订阅者:


/usr/redis/bin/redis-cli -h 192.168.170.31


使用psubscribe命令,订阅所有以news开头的频道(不具体订阅频道):


192.168.170.31:6379> psubscribe news.*


启动一个客户端,模拟发布者:


/usr/redis/bin/redis-cli -h 192.168.170.31


使用publish命令,向news开头的频道名称上发送消息:


192.168.170.31:6379[2]> publish news.a news111 
 
 
(integer) 1 
 
 
192.168.170.31:6379[2]> publish news.a news222 
 
 
(integer) 1 
 
 
192.168.170.31:6379[2]> publish news.b news333 
 
 
(integer) 1 
 
 
192.168.170.31:6379[2]> publish news.c news444 
 
 
(integer) 1 
 
 
192.168.170.31:6379[2]> publish news.d news555 
 
 
(integer) 1

持久化



具体实现:

RDB方式:

vim /usr/redis/bin/redis.conf


save 900 1 在900秒(15分钟)之内 内存中的所有数据有1个key发生变化 进行一次rdb


save 300 10 在300秒(5分钟)之内 内存中的所有数据有10个key发生变化 进行一次rdb


save 60 10000 在60秒(1分钟)之内 内存中的所有数据有10000个key发生变化 进行一次


rdb (redis性能非常好,每秒写的速度可以达到81000次/秒 1分钟 内理论上支持81000*60 =4860000 key发生变化的 )



rdb保存到磁盘文件名称为:


:253 dump.rdb


具体的磁盘位置, 是在执行redis命令时所处的目录 ,如果执行命令的目录是home那dump就生


成在home下。 如果要修改位置,可以修改#263的执行目录


使用单机版redis测试


/usr/redis/bin/redis-server /usr/redis/bin/redis.conf

AOF方式:

:699 appendonly yes 开启aof方式 默认没有开始,默认使用 rdb方式

:693 RDB和AOF方式可以同时开启,同时开启时,redis优先使用AOF方式。


aof保存到磁盘文件名称为:


:703 appendonly.aof


:709

Redis supports three different modes: 
 
 

# no: don't fsync, just let the OS flush the data when it wants. Faster. 
 
  
从来不执行文件同步 只有当系统主动刷新数据才会。速度最快,最不安全的 
 
  
# always: fsync after every write to the append only log. Slow, Safest. 
 
  
每次写命令执行完毕都会追加命令到文件中。速度最慢,最安全的。 
 
  
# everysec: fsync only one time every second. Compromise. 
 
  
一秒钟执行一次文件同步。速度适中,安全性适中。 
 
  
:728-730 
 
  
# appendfsync always 
 
  
appendfsync everysec 
 
  
# appendfsync no 
 
  
默认方式为 一秒钟同步一次



使用单机版 redis 测试


  /usr/redis/bin/redis-server /usr/redis/bin/redis.conf

查看当前所在目录

pwd

redis 事务


将一组命令放在同一个事务中进行处理。


事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务


在执行的过程中,不会被其他客户端发送来的命令请求所打断。


事务是一个原子操作:事务中的命令要么全部被执行,要么全部都不执行。


Redis事务具体命令及用法

Multi: 开启事务

Exec (execute): 提交事务

Discard: 回滚事务


Watch:


redis使用关键字实现乐观锁(check-and-set)。被 WATCH 的键会被监视,并会发觉这些键 是否被改动过了。 如果有至少一个被监视的键在 EXEC 执行之前被修改了, 那么整个事务都会 被取消, EXEC 返回nil-reply来表示事务已经失败。


具体用法:


启动redis服务端:


/usr/redis/bin/redis-server /usr/redis/bin/redis.conf


启动redis客户端:


/usr/redis/bin/redis-cli -h 192.168.170.31

multi和exec用法:

192.168.170.31:6379> flushdb 
 
 
OK 
 
 
192.168.170.31:6379> set aaa 111 
 
 
OK 
 
 
192.168.170.31:6379> set bbb 222 
 
 
OK 
 
 
192.168.170.31:6379> set ccc 333 
 
 
OK 
 
 
192.168.170.31:6379> keys * 
 
 
1) "aaa" 
 
 
2) "bbb" 
 
 
3) "ccc" 
 
 
开启一个事务(相当于数据库事务中的begin trasication),总是返回O 
  K 
 
 
192.168.170.31:6379> multi 
 
 
OK 
 
 
这些命令不会立即被执行, 而是被放到一个队列中 
 
 
192.168.170.31:6379> incr aaa 
 
 
QUEUED 
 
 
192.168.170.31:6379> incr bbb 
 
 
QUEUED 
 
 
192.168.170.31:6379> incr ccc 
 
 
QUEUED 
 
 
43  
  # 
  提交事务 
 
 
44  
  commit; 
  当 EXEC命令被调用时, 所有队列中的命令才会被执行 
 
 
192.168.170.31:6379> exec 
 
 
1) (integer) 112 
 
 
2) (integer) 223 
 
 
3) (integer) 334 
 
 
192.168.170.31:6379> mget aaa bbb ccc 
 
 
1) "112" 
 
 
2) "223" 
 
 
3) "334" 
 
 
192.168.170.31:6379>


multi和discard用法:


192.168.170.31:6379> mget aaa bbb ccc 
 
 
1) "112" 
 
 
2) "223" 
 
 
3) "334" 
 
 
开启一个事务 
 
 
192.168.170.31:6379> multi 
 
 
OK 
 
 
这些命令不会立即被执行, 而是被放到一个队列中 
 
 
192.168.170.31:6379> decr aaa 
 
 
QUEUED 
 
 
192.168.170.31:6379> decr bbb 
 
 
QUEUED 
 
 
192.168.170.31:6379> decr ccc 
 
 
QUEUED 
 
 
事务会被放弃, 事务队列会被清空 
 
 
192.168.170.31:6379> discard 
 
 
OK 
 
 
查看数据,没有被修改 
 
 
192.168.170.31:6379> mget aaa bbb ccc 
 
 
1) "112" 
 
 
2) "223" 
 
 
3) "334" 
 
 
事务的特殊情况演示(事务中出现错误操作): 
 
 
192.168.170.31:6379> set ddd 'ddd' 
 
 
OK 
 
 
192.168.170.31:6379> mget aaa bbb ccc ddd 
 
 
1) "112" 
 
 
2) "223" 
 
 
3) "334" 
 
 
4) "ddd" 
 
 
开启一个事务 
 
 
192.168.170.31:6379> multi 
 
 
OK 
 
 
这些命令不会立即被执行, 而是被放到一个队列中 
 
 
192.168.170.31:6379> decr aaa 
 
 
QUEUED 
 
 
192.168.170.31:6379> decr bbb 
 
 
QUEUED 
  192.168.170.31:6379> decr ddd 
 
 
QUEUED 
 
 
192.168.170.31:6379> decr ccc 
 
 
QUEUED 
 
 
当 EXEC命令被调用时, 所有队列中的命令才会被执行 
 
 
192.168.170.31:6379> exec 
 
 
1) (integer) 111 
 
 
2) (integer) 222 
 
 
3) (error) ERR value is not an integer or out of range 
 
 
4) (integer) 333