标签:redis
第1章 消息模式:1. 队列模式
2. 发布订阅模式
a) 任务队列:就是传递消息的队列,与任务队列进行交互的实体有两类,一类是生产者,另一类是消费者,生产者将需要处理的任务放在任务队里中,而消费者不断的从任务独立中读入任务消息并执行
任务队列的好处:松耦合,生产者和消费者只需按照约定的任务描述格式,进行编写代码
易于扩展,多消费者模式下,消费者可以分布在多个不通过额服务器中,由此降低单台服务器的负载
? Subscriber:收音机,可以收到多个频道,并以队列方式显示
? Publisher:电台,可以往不同的FM频道中发消息
? Channel:不同频率的FM频道
从pub/sub的机制来看,他更像是一个广播系统,多个sub可以订阅多个channel,多个pub可以往多个channel中发布消息
一个pub,多个sub模型 : 主要应用为通知,公告
多个pub,一个sub模型:
可以将pub做成独立的http接口,个应用程序作为pub想channel中发送消息,sub端收到消息后执行相应的业务逻辑,比如写数据库,显示等,主要应用 : 排行榜,投票,计数
多个pub,多个sub模型:
就是可以向不同的channel中发送消息,由不同的sub接受,主要应用 : 群聊,聊天
发布订阅命令:
命令 | 描述 |
PUBLISH channel msg | 将信息 message 发送到指定的频道 channel |
SUBSCRIBE channel [channel ...] | 订阅频道,可以同时订阅多个频道 |
UNSUBSCRIBE [channel ...] | 取消订阅指定的频道, 如果不指定频道,则会取消订阅所有频道 |
PSUBSCRIBE pattern [pattern ...] | 订阅一个或多个符合给定模式的频道,每个模式以 * 作为匹配符,比如 it* 匹配所有以 it 开头的频道( it.news 、 it.blog 、 it.tweets 等等), news.* 匹配所有以 news. 开头的频道( news.it 、news.global.today 等等),诸如此类 |
PUNSUBSCRIBE [pattern [pattern ...]] | 退订指定的规则, 如果没有参数则会退订所有规则 |
PUBSUB subcommand [argument [argument ...]] | 查看订阅与发布系统状态 |
127.0.0.1:6381> SUBSCRIBE fm
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "fm"
3) (integer) 1
127.0.0.1:6381> PUBLISH fm hello
(integer) 1
1) "message"
2) "fm"
3) "hello"
客户端在执行订阅命令之后进入了订阅状态,只能接收 SUBSCRIBE 、PSUBSCRIBE、 UNSUBSCRIBE 、PUNSUBSCRIBE 四个命令。
开启的订阅客户端,无法收到该频道之前的消息,因为 Redis 不会对发布的消息进行持久化。
和很多专业的消息队列系统(例如Kafka、RocketMQ)相比,Redis的发布订阅略显粗糙,例如无法实现消息堆积和回溯。但胜在足够简单,如果当前场景可以容忍的这些缺点,也不失为一个不错的选择。
redis中的事务跟关系型数据库中的事务是一个相似的概念,但是有不同之处
关系型数据库事务执行失败后面的sql语句不在执行,而redis中的一条命令执行失败,其余的命令照常执行,redis中开启一个事务使用multi,相当于begin,exec用来提交事务,discard用来取消队列
MySQL | Redis | |
开启 | start transaction/begin | multi |
语句 | 普通SQL | 普通命令 |
失败 | rollback 回滚 | discard 取消(不叫回滚,是队列里面的命令不执行,队列里面的任务根本就没有执行。而不是执行了也可以撤回来) |
成功 | commit | exec |
命令 | 描述 |
DISCARD | 取消事务,放弃执行事务块内的所有命令。 |
EXEC | 执行所有事务块内的命令。 |
MULTI | 标记一个事务块的开始。 |
UNWATCH | 取消 WATCH 命令对所有 key 的监视。 |
WATCH key [key ...] | 监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动 那么事务将被打断。 |
127.0.0.1:6381> multi
OK
127.0.0.1:6381> set jiang 7
QUEUED
127.0.0.1:6381> exec
1) (empty list or set)
2) OK
127.0.0.1:6381> get jiang
"7"
举例:我正在买票 Ticket -1 , money -100
而票只有1张, 如果在我multi之后,和exec之前, 票被别人买了,即ticket变成0了。
我该如何观察这种情景,并不再提交:
悲观的想法:
世界充满危险,肯定有人和我抢, 给 ticket上锁, 只有我能操作. [悲观锁]
乐观的想法:
没有那么人和我抢,因此,我只需要注意,有没有人更改ticket的值就可以了 [乐观锁]
Redis的事务中,启用的是乐观锁,只负责监测key没有被改动.
命令 | 描述 |
BGREWRITEAOF | 异步执行一个 AOF(AppendOnly File) 文件重写操作 |
BGSAVE | 在后台异步保存当前数据库的数据到磁盘 |
CLIENT KILL [ip:port] [ID client-id] | 关闭客户端连接 |
CLIENT LIST | 获取连接到服务器的客户端连接列表 |
CLIENT GETNAME | 获取连接的名称 |
CLIENT PAUSE timeout | 在指定时间内终止运行来自客户端的命令 |
CLIENT SETNAME connection-name | 设置当前连接的名称 |
CLUSTER SLOTS | 获取集群节点的映射数组 |
COMMAND | 获取 Redis 命令详情数组 |
COMMAND COUNT | 获取 Redis 命令总数 |
COMMAND GETKEYS | 获取给定命令的所有键 |
TIME | 返回当前服务器时间 |
COMMAND INFO command-name [command-name ...] | 获取指定 Redis 命令描述的数组 |
CONFIG GET parameter | 获取指定配置参数的值 |
CONFIG REWRITE | 对启动 Redis 服务器时所指定的 redis.conf 配置文件进行改写 |
CONFIG SET parameter value | 修改 redis 配置参数,无需重启 |
CONFIG RESETSTAT | 重置 INFO 命令中的某些统计数据 |
DBSIZE | 返回当前数据库的 key 的数量 |
DEBUG OBJECT key | 获取 key 的调试信息 |
DEBUG SEGFAULT | 让 Redis 服务崩溃 |
FLUSHALL | 删除所有数据库的所有key |
FLUSHDB | 删除当前数据库的所有key |
INFO [section] | 获取 Redis 服务器的各种信息和统计数值 |
LASTSAVE | 返回最近一次 Redis 成功将数据保存到磁盘上的时间,以 UNIX 时间戳格式表示 |
MONITOR | 实时打印出 Redis 服务器接收到的命令,调试用 |
ROLE | 返回主从实例所属的角色 |
SAVE | 异步保存数据到硬盘 |
SHUTDOWN [NOSAVE] [SAVE] | 异步保存数据到硬盘,并关闭服务器 |
SLAVEOF host port | 将当前服务器转变为指定服务器的从属服务器(slave server) |
SLOWLOG subcommand [argument] | 管理 redis 的慢日志 |
SYNC | 用于复制功能(replication)的内部命令 |
基于RDB持久化的功能来实现主从复制的功能
1. 使用异步复制
2. 一个主服务器可以有多个从服务器
3. 从服务器也可以有自己的从服务器
4. 复制功能不会阻塞主服务器
5. 可以通过复制功能来让主服务器免于执行持久化操作,由从服务器执行持久化操作即可
1. 从服务器向主服务器发送sync命令
2. 接到sync命令的主服务器会调用bgsave命令,创建一个RDB文件,并使用缓冲区记录接下来执行的所有命令
3. 当主服务器执行完bgsave命令时,它会向从服务器发送RDB文件,而从服务器则会接受并载入这个文件
4. 主服务器将缓冲区存储的所有写命令发送给从服务器
从Redis2.8版本之后,redis使用psync代替sync命令,psync比起sync最大的改进在于实现了部分重同步的特性,即在服务器断线重新连接的时候,只要条件允许,psync可以让主服务器指向从服务器同步断线期间确实的数据,而不用重新向从服务器同步整个数据库
在读写分离环境下,客户端向主服务器发送写命令 SET n 10086,主服务器在执行这个写命令之后,向客户端返回回复,并将这个写命令传播给从服务器。
接到回复的客户端继续向从服务器发送读命令 GET n ,并且因为网络状态的原因,客户端的 GET命令比主服务器传播的 SET 命令更快到达了从服务器。
因为从服务器键 n 的值还未被更新,所以客户端在从服务器读取到的将是一个错误(过期)的 n值。
主服务器只在有至少 N 个从服务器的情况下,才执行写操作从 Redis 2.8 开始, 为了保证数据的安全性, 可以通过配置, 让主服务器只在有至少 N 个当前已连接从服务器的情况下, 才执行写命令。
不过, 因为 Redis 使用异步复制, 所以主服务器发送的写数据并不一定会被从服务器接收到, 因此, 数据丢失的可能性仍然是存在的。
在主服务器可以通过这两个参数来控制安全性,这两个参数的值都满足的情况下,主服务器将不会执行写操作
min-slaves-to-write <number of slaves> 几个从
min-slaves-max-lag <number of seconds> 最大延时的lag值
[root@gitlab data]# ll
total 0
drwxr-xr-x 2 root root 6 Apr 17 00:05 6380
drwxr-xr-x 2 root root 6 Apr 17 00:05 6381
drwxr-xr-x 2 root root 6 Apr 17 00:05 6382
除端口不同,其余都相同
port 6380
daemonize yes
pidfile /data/6380/redis.pid
loglevel notice
logfile "/data/6380/redis.log"
dbfilename dump.rdb
dir /data/6380
protected-mode no
for i in {0..2};do redis-server /data/638${i}/redis.conf ; done
主库为6380,从库为6381,6382
[root@gitlab ~]# redis-cli -p 6381
127.0.0.1:6381> SLAVEOF 127.0.0.1 6380
OK
[root@gitlab ~]# redis-cli -p 6382
127.0.0.1:6382> SLAVEOF 127.0.0.1 6380
OK
127.0.0.1:6380> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=127.0.0.1,port=6381,state=online,offset=85,lag=0
slave1:ip=127.0.0.1,port=6382,state=online,offset=85,lag=0
master_repl_offset:85
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:84
127.0.0.1:6381> info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6380
master_link_status:up
master_last_io_seconds_ago:4
master_sync_in_progress:0
slave_repl_offset:141
slave_priority:100
slave_read_only:1
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
127.0.0.1:6382> info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6380
master_link_status:up
master_last_io_seconds_ago:10
master_sync_in_progress:0
slave_repl_offset:169
slave_priority:100
slave_read_only:1
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
宕掉主库:
127.0.0.1:6380> shutdown
主从切换:
slaveof no one
标签:redis
原文地址:http://blog.51cto.com/13520772/2109400