Redis发布-不重启转换-持久化-主从同步
redis发布订阅
应用场景
1、今日头条订阅号、微信订阅公众号、新浪微博关注、邮件订阅系统
2、即使通信系统
3、群聊部落系统(微信群)
使用方法:
# 发布者:
PUBLISH 频道 消息
# 订阅者:
SUBSCRIBE 频道
# 正则匹配:(订阅者订阅)
PSUBSCRIBE *频道 (例: *zhibo或zhibo*)
例子
redis-cli:
# 发布者:
> PUBLISH wang 123
redis-cli:
# 订阅者:
> SUBSCRIBE wang # 发布者发送123,这边就可以收到123
# 另一个订阅者:
> SUBSCRIBE wang # 一样可以收到123
redis-cli:
# 发布者:
> PUBLISH wangxx 123
redis-cli:
# 正则匹配:(订阅者订阅)
> PSUBSCRIBE wang* # 发布者发送123,这边就可以收到123
> PSUBSCRIBE *wang # 这个发布者收不到,只能接收xxwang等.消息
redis持久化
Redis是一种内存型数据库,一旦服务器进程退出,数据库的数据就会丢失,为了解决这个问题,Redis提供了两种RDB (Redis DataBase)和 AOF (Append Only File)持久化的方案,将内存中的数据保存到磁盘中,避免数据的丢失。
1. RDB持久化
(1) RDB持久化的作用
基于快照的持久化,速度更快,一般用作备份
RDB(持久化)
内存数据保存到磁盘
在指定的时间间隔内生成数据集的时间点快照(point-in-time snapshot)
优点:速度快,适合做备份,主从复制就是基于RDB持久化功能实现
rdb通过再redis中使用save命令触发 rdb
1.基于内存的数据快照
2.定期执行数据快照
3.手动触发数据快照
(2) 实现
# 1. 打开redis-6379.conf配置文件,添加以下配置
port 6379
daemonize yes
dir /data/6379 # 定义持久化文件存储位置,如没有该文件需要手动创建
pidfile /data/6379/redis.pid # redis进程pid文件
loglevel notice # 日志级别
logfile "/data/6379/redis.log" # redis日志log文件
protected-mode yes # 保护模式
#bind 10.0.0.10 127.0.0.1 # redis绑定地址
#requirepass redhat # redis登录密码
dbfilename dbmp.rdb # rdb持久化文件
save 900 1 # rdb机制 每900秒 有1个修改记录
save 300 10 # 每300秒 10个修改记录
save 60 10000 # 每60秒内 10000修改记录
# 2. 重启redis服务
pkill redis
redis-server /opt/redis_conf/redis-6379.conf
# 2. 手动触发(在我们添加好数据之后,使用命令save触发)
save
在日志文件下有一个dbmp.rdb
,它就是持久化文件
# 每次我们提交数据,都要save才会保存到给文件
# 写入数据
set name user
save
# 或者在设定的时间内才会帮我们自动保存
# save 900 1 # rdb机制 每900秒 有1个修改记录
# save 300 10 # 每300秒 10个修改记录
# save 60 10000 # 每60秒内 10000修改记录
AOF持久化
AOF(append-only log file)
记录服务器执行的所有变更操作命令(例如set del等),并在服务器启动时,通过重新执行这些命令来还原数据集
AOF 文件中的命令全部以redis协议的格式保存,新命令追加到文件末尾。
优点:最大程度保证数据不丢失 (比RDB要好,因为RDB有可能丢失数据)
缺点:日志记录非常大
实现:
# 配置文件:新增命令
appendonly yes # 唯一
appendfsync everysec # 同步
# 解释:AOF持久化配置,两条参数
appendonly yes
appendfsync always 总是修改类的操作
everysec 每秒做一次持久化
no 依赖于系统自带的缓存大小机制
1 修改配置文件/opt/redis_conf/redis-6379.conf
daemonize yes
port 6379
logfile /data/6379/redis.log
dir /data/6379
dbfilename dbmp.rdb
requirepass redhat
save 900 1
save 300 10
save 60 10000
appendonly yes
appendfsync everysec
# 重启redis服务
pkill redis
redis-server /opt/redis_conf/redis-6379.conf
# 登录redis-cli,写入数据,实时检查aof文件信息
tail -f appendonly.aof
# 新窗口登录
set name user
在日志文件下有.aof后缀的文件
它帮我们收集着每次操作的记录,即时保存起来
其实原来的配置不变,只是加上了最后两行配置,就实现了AOF持久化
redis不重启,切换RDB备份到AOF备份
(1) 先实现一个RDB的redis数据
(2) 两条命令实现从RDB切换到AOF
# 1. 备份这个rdb文件,保证数据安全
[root@pyyuc /data/6379 22:35:38]# cp dbmp.rdb dbmp.rdb.bak
# 2. 开启AOF功能
127.0.0.1:6379> CONFIG set appendonly yes #开启AOF功能
OK
# 3. 关闭RDB功能
127.0.0.1:6379> CONFIG SET save "" #关闭RDB功能
OK
RDB存在的优势
1). 一旦采用该方式,那么你的整个Redis数据库将只包含一个文件,这对于文件备份而言是非常完美的。比如,你可能打算每个小时归档一次最近24小时的数据,同时还要每天归档一次最近30天的数据。通过这样的备份策略,一旦系统出现灾难性故障,我们可以非常容易的进行恢复。
2). 对于灾难恢复而言,RDB是非常不错的选择。因为我们可以非常轻松的将一个单独的文件压缩后再转移到其它存储介质上。
3). 性能最大化。对于Redis的服务进程而言,在开始持久化时,它唯一需要做的只是fork出子进程,之后再由子进程完成这些持久化的工作,这样就可以极大的避免服务进程执行IO操作了。
4). 相比于AOF机制,如果数据集很大,RDB的启动效率会更高。
RDB存在的劣势
1). 该机制可以带来更高的数据安全性,即数据持久性。Redis中提供了3中同步策略,即每秒同步、每修改同步和不同步。事实上,每秒同步也是异步完成的,其效率也是非常高的,所差的是一旦系统出现宕机现象,那么这一秒钟之内修改的数据将会丢失。而每修改同步,我们可以将其视为同步持久化,即每次发生的数据变化都会被立即记录到磁盘中。可以预见,这种方式在效率上是最低的。至于无同步,无需多言,我想大家都能正确的理解它。
2). 由于该机制对日志文件的写入操作采用的是append模式,因此在写入过程中即使出现宕机现象,也不会破坏日志文件中已经存在的内容。然而如果我们本次操作只是写入了一半数据就出现了系统崩溃问题,不用担心,在Redis下一次启动之前,我们可以通过redis-check-aof工具来帮助我们解决数据一致性的问题。
3). 如果日志过大,Redis可以自动启用rewrite机制。即Redis以append模式不断的将修改数据写入到老的磁盘文件中,同时Redis还会创建一个新的文件用于记录此期间有哪些修改命令被执行。因此在进行rewrite切换时可以更好的保证数据安全性。
4). AOF包含一个格式清晰、易于理解的日志文件用于记录所有的修改操作。事实上,我们也可以通过该文件完成数据的重建。
AOF的优势
1). 该机制可以带来更高的数据安全性,即数据持久性。Redis中提供了3中同步策略,即每秒同步、每修改同步和不同步。事实上,每秒同步也是异步完成的,其效率也是非常高的,所差的是一旦系统出现宕机现象,那么这一秒钟之内修改的数据将会丢失。而每修改同步,我们可以将其视为同步持久化,即每次发生的数据变化都会被立即记录到磁盘中。可以预见,这种方式在效率上是最低的。至于无同步,无需多言,我想大家都能正确的理解它。
2). 由于该机制对日志文件的写入操作采用的是append模式,因此在写入过程中即使出现宕机现象,也不会破坏日志文件中已经存在的内容。然而如果我们本次操作只是写入了一半数据就出现了系统崩溃问题,不用担心,在Redis下一次启动之前,我们可以通过redis-check-aof工具来帮助我们解决数据一致性的问题。
3). 如果日志过大,Redis可以自动启用rewrite机制。即Redis以append模式不断的将修改数据写入到老的磁盘文件中,同时Redis还会创建一个新的文件用于记录此期间有哪些修改命令被执行。因此在进行rewrite切换时可以更好的保证数据安全性。
4). AOF包含一个格式清晰、易于理解的日志文件用于记录所有的修改操作。事实上,我们也可以通过该文件完成数据的重建。
总结
redis 持久化方式有哪些?有什么区别?
rdb:基于快照的持久化,速度更快,一般用作备份,主从复制也是依赖于rdb持久化功能
aof:以追加的方式记录redis操作日志的文件。可以最大程度的保证redis数据安全,类似于mysql的binlog
redis主从同步
原理:
- 从服务器向主服务器发送 SYNC 命令。
- 接到 SYNC 命令的主服务器会调用BGSAVE 命令,创建一个 RDB 文件,并使用缓冲区记录接下来执行的所有写命令。
- 当主服务器执行完 BGSAVE 命令时,它会向从服务器发送 RDB 文件,而从服务器则会接收并载入这个文件。
- 主服务器将缓冲区储存的所有写命令发送给从服务器执行。
1、在开启主从复制的时候,使用的是RDB方式的,同步主从数据的
2、同步开始之后,通过主库命令传播的方式,主动的复制方式实现
3、2.8以后实现PSYNC的机制,实现断线重连
redis主从同步实现
(1) 准备三个redis数据库,redis支持多实例
# 主服务器master: 6380
# 从服务器slave: 6381/6382
(2) 先配置主服务器master的配置文件
vim /opt/redis_conf/redis-6380.conf
添加以下配置(端口6380文件)
port 6380
daemonize yes
pidfile /data/6380/redis.pid
loglevel notice
logfile "/data/6380/redis.log"
dbfilename dump.rdb
dir /data/6380
protected-mode yes
# 暂定不能有redis密码
另外添加以下配置(端口6380分别换成81,82)
配置从同步有两个方法
# 第一种方法, 永久修改,修改6381和6382配置文件, 添加以下一行配置
slaveof 127.0.0.1 6380 #指明主的地址
# 第二种方法, 在6381/6382命令行
redis-cli -p 6381
SLAVEOF 127.0.0.1 6380 #指明主的地址
redis-cli -p 6382
SLAVEOF 127.0.0.1 6380 #指明主的地址
用sed命令快速重定向
sed "s/6380/6381/g" redis-6380.conf > redis-6381.conf
# 此命令的意思是将redis-6380.conf配置文件里面的6380替换成6381输出到redis-6381.conf文件中,但是不会更改redis-6380.conf配置文件
# 加上-i参数就会使redis-6380.conf文件自己生效,更改内容,同时创建一个空文件redis-6381.conf
配置后:
port 6381
daemonize yes
pidfile /data/6381/redis.pid
loglevel notice
logfile "/data/6381/redis.log"
dbfilename dump.rdb
dir /data/6381
protected-mode yes
slaveof 127.0.0.1 6380
(3) 创建数据存储文件
mkdir -p /data/638{0..2} 或 mkdir -p /data/{6380,6381,6382}
先启动三个数据库,查看数据库是否正常(可以把三个命令写入一个启动脚本vim test.sh
)
redis-server /opt/redis_conf/redis-6380.conf
redis-server /opt/redis_conf/redis-6381.conf
redis-server /opt/redis_conf/redis-6382.conf
配置主从(注意只需要在两个从库上配置即可)
# 配置文件要有添加这条:
slaveof 127.0.0.1 6380
重启redis服务
pkill redis
# 启动写入的脚本 或者上面的启动三个数据命令
tesh.sh
查看主从服务器的状态
redis-cli -p 6380 info replication
# 可以查看到6380的角色为master, 下面有两个从库,我们主要查看这两个从库的状态为online,说明主从同步配置成功
redis主从复制故障切换
手动进行主从复制故障切换
(1)手动结束掉6380的进程,模拟主库宕机
ps -ef | grep redis
# 找到进程,kill -9 xxx
(2) 在从库6381和6382上查看状态, 可以查看到master的状态为down
redis-cli -p 6381 info replication
redis-cli -p 6382 info replication
既然主库挂了,我想要在6381 6382之间选一个新的主库
1.关闭6381的从库身份
[root@db03 ~]# redis-cli -p 6381
127.0.0.1:6381> info replication
127.0.0.1:6381> slaveof no one
2.将6382设为6381的从库
6382连接到6381:
[root@db03 ~]# redis-cli -p 6382
127.0.0.1:6382> slaveof no one
127.0.0.1:6382> slaveof 127.0.0.1 6381
3.检查6382,6381的主从信息
6382的状态
6381的状态
4.修改完毕,还得修改配置文件,永久生效
# 按主从同步配置
vim /opt/redis_conf/redis-6381.conf # 把主的指定清除
vim /opt/redis_conf/redis-6382.conf # 把主的重新指定