Redis -- 13 -- Redis主从同步搭建
相关文章:
官方文档:Replication
Redis 主从同步是指将一台 Redis 服务器上的数据,同步到另一台或多台 Redis 服务器上,前者称为主节点 (Master),后者称为从节点 (Slave);一个主节点可以有多个从节点 (也可以没有),而一个从节点只能有一个主节点
一、Redis 主从同步介绍
-
Redis 默认使用异步复制,其特点是低延迟和高性能,是绝大多数 Redis 实例的自然复制模式,也就是说 Slave 会异步地确认从 Master 周期性接收到的数据
-
主从同步的运行依靠以下三个主要机制
-
当 Master 和 Slave 连接正常时,Master 会向 Slave 发送命令流来使 Slave 保持更新,以便将自身发生的数据集改变复制给 Slave,包括:客户端的写入、Key 的过期或删除或其他任何更改 Master 数据集的操作
-
当 Master 和 Slave 连接断开后,Slave 重新连接上 Master 时,会尝试对断开期间内丢失的命令流进行同步 (部分同步)
-
当无法进行部分同步时,Slave 会尝试进行全量同步,Master 会创建一个所有数据的快照,将其发送给 Slave,之后在数据集更改时,持续发送命令流到 Slave
-
-
主从同步作用
-
数据冗余
- 主从同步实现了数据的热备份,是持久化之外的一种数据冗余方式
-
故障恢复
- 当 Master 发生故障时,可以由 Slave 提供服务,实现了快速的故障恢复
-
读写分离
- Master 负责写操作,Slave 负责读操作,缓解了 Master 的读写压力,大大提高了数据库的读写性能
-
二、Redis 主从同步原理
-
每个 Master 都有一个 replication ID (复制 ID,这是一个较大的伪随机字符串,标记了一个给定的数据集)
-
每个 Master 都持有一个 offset (偏移量),Master 将自身产生的复制流发送给 Slave,发送多少个字节的数据,自身 offset 就会增加多少,目的是当有新的操作修改自身数据集时,Master 可以以此来更新 Slave 的状态
-
即使没有一个 Slave 连接到 Master,offset 也会增加,也就是说每一对给定的 replication ID 和 offset 都会标识一个 Master 数据集的确切版本
三、Redis 主从同步过程
-
增量同步
-
Slave 使用 PSYNC 命令发送其记录的旧的 replication ID 和至今为止处理的 offset 到 Master
-
Master 接收到 PSYNC 命令后,只需要发送 Slave 所需的增量部分即可
- 如果 Master 的积压缓冲区不足,或 Slave 引用的 replication ID 不可知,则会转换为全量同步,在这种情况下,Slave 会得到一个完整的数据集副本
-
-
全量同步
-
Slave 发送 PSYNC 命令到 Master
-
Master 启动一个后台进程,将 Redis 中的数据快照保存到 RDB 文件中 (即 bgsave 操作)
-
Master 会将保存快照期间接收到的写命令缓存起来 (即将增量数据缓存起来)
-
Master 在完成写文件 (RDB 文件) 的操作后,会将 RDB 文件发送给 Slave
-
Salve 接收到文件后,会将文件保存到磁盘上,然后将文件加载到内存中去恢复数据快照
-
当 Slave 完成数据快照的恢复后,Master 会将此期间收集到的增量写命令发送给 Slave 进行恢复
-
四、Redis 主从配置参数
-
replicaof <masterip> <masterport>
- 设置 Master IP + 端口号
-
masterauth <master-password>
- 设置 Master 密码
五、Redis 如何开启主从同步
-
修改配置文件
-
修改 Slave 配置文件
replicaof <masterip> <masterport>
-
如果 Master 有密码,则还需要修改
masterauth <master-password>
-
-
使用启动命令
- 使用
redis-server
命令启动时,加入--replicaof <masterip> <masterport>
参数
- 使用
-
使用客户端命令
- 当 Redis 服务启动后,通过
redis-cli
进入客户端执行命令replicaof <masterip> <masterport>
- 当 Redis 服务启动后,通过
六、搭建 Redis 主从同步
-
1、在服务器上搭建一个单机版的 Redis,具体流程参考 --> Redis – 02 – Linux上源码包安装Redis
-
2、在
/usr/local/
目录下新建redis-master-slave
目录,用于存放主 Slave-
cd /usr/local/
-
mkdir redis-master-slave
-
-
3、将第 1 步安装完的 Redis 的 bin 目录下的所有文件复制到
/usr/local/redis-master-slave/redis01/
目录下- cp -r /usr/local/redis/bin/ /usr/local/redis-master-slave/redis01/
-
4、修改
/usr/local/redis-master-slave/redis01/
目录下的 redis.conf 配置文件-
vim /usr/local/redis-master-slave/redis01/redis.conf
# 将 bind 127.0.0.1 一行注释掉 # bind 127.0.0.1 # 设置端口 port 6386 # 开启守护进程 daemonize yes # 设置 pid 文件 pidfile /var/run/redis-6386.pid # 设置 log 文件 logfile "./redis-6386.log" # 设置工作目录 dir ./ # 设置 Master 密码 masterauth 123456 # 设置密码 requirepass 123456
-
:wq
-
-
5、在
/usr/local/redis-master-slave/redis01/
目录下编写启动脚本-
vim /usr/local/redis-master-slave/redis01/start.sh
#!/bin/bash #实例路径 APP_NAME=/usr/local/redis-master-slave/redis01/redis-server #配置文件路径 APP_CONF=/usr/local/redis-master-slave/redis01/redis.conf #使用说明,用来提示输入参数 usage() { echo "Usage: run.sh {start|stop|restart|status}" exit 1 } #检查程序是否正在运行 is_running() { pid=`ps -ef|grep $APP_NAME|grep -v grep|awk '{print $2}'` #如果不存在则返回1,存在则返回0 if [ -z "${pid}" ]; then return 1 else return 0 fi } #启动 start() { is_running if [ $? -eq 0 ]; then echo "${APP_NAME} is already running, pid=${pid}" else ${APP_NAME} ${APP_CONF} fi } #停止 stop() { is_running if [ $? -eq 0 ]; then kill -9 $pid else echo "${APP_NAME} is not running" fi } #查看运行状态 status() { is_running if [ $? -eq 0 ]; then echo "${APP_NAME} is running, pid is ${pid}" else echo "${APP_NAME} is not running" fi } #重启 restart() { stop sleep 5 start } #根据输入的参数,选择对应的执行方法,不输入则执行使用说明 case "$1" in start) start ;; stop) stop ;; status) status ;; restart) restart ;; *) usage ;; esac
-
:wq
-
chmod +x /usr/local/redis-master-slave/redis01/start.sh
-
-
6、将
/usr/local/redis-master-slave/redis01/
目录下的所有文件复制 2 份到/usr/local/redis-master-slave/(redis02 - redis03)/
目录下-
cp -r /usr/local/redis-master-slave/redis01/ /usr/local/redis-master-slave/redis02/
-
cp -r /usr/local/redis-master-slave/redis01/ /usr/local/redis-master-slave/redis03/
-
在 redis02 - redis03 两个文件中,修改 redis.conf 配置文件和 start.sh 启动脚本
-
redis.conf 配置文件
-
将
port
分别改为6387 - 6388
-
将
pidfile
分别改为/var/run/redis-(6387 - 6388).pid
; -
将
logfile
分别改为./redis-(6387 - 6388).log
-
除此之外,还需要更改以下配置
# 设置 Master IP + 端口号 (用于主从同步) replicaof 127.0.0.1 6386
-
-
start.sh 启动脚本
- 将
redis01
分别改为redis02 - redis03
- 将
-
其中 redis01 作为主节点 (Master),redis02、redis03 作为从节点 (Slave)
-
-
-
7、在
/usr/local/redis-master-slave/
目录下编写总的启动脚本和总的关闭脚本-
vim /usr/local/redis-master-slave/start.sh
#!/bin/bash #项目路径 REDIS01_PATH=/usr/local/redis-master-slave/redis01 REDIS02_PATH=/usr/local/redis-master-slave/redis02 REDIS03_PATH=/usr/local/redis-master-slave/redis03 #使用说明,用来提示输入参数 usage() { echo "Usage: start.sh {all|redis01|redis02|redis03}" exit 1 } #启动所有 all() { cd ${REDIS01_PATH} ./start.sh start cd ${REDIS02_PATH} ./start.sh start cd ${REDIS03_PATH} ./start.sh start } #启动redis01 redis01() { cd ${REDIS01_PATH} ./start.sh start } #启动redis02 redis02() { cd ${REDIS02_PATH} ./start.sh start } #启动redis03 redis03() { cd ${REDIS03_PATH} ./start.sh start } #根据输入的参数,选择对应的执行方法,不输入则执行使用说明 case "$1" in all) all ;; redis01) redis01 ;; redis02) redis02 ;; redis03) redis03 ;; *) usage ;; esac
-
:wq
-
chmod +x /usr/local/redis-master-slave/start.sh
-
vim /usr/local/redis-master-slave/stop.sh
#!/bin/bash #项目路径 REDIS01_PATH=/usr/local/redis-master-slave/redis01 REDIS02_PATH=/usr/local/redis-master-slave/redis02 REDIS03_PATH=/usr/local/redis-master-slave/redis03 #使用说明,用来提示输入参数 usage() { echo "Usage: stop.sh {all|redis01|redis02|redis03}" exit 1 } #关闭所有 all() { cd ${REDIS01_PATH} ./start.sh stop cd ${REDIS02_PATH} ./start.sh stop cd ${REDIS03_PATH} ./start.sh stop } #关闭redis01 redis01() { cd ${REDIS01_PATH} ./start.sh stop } #关闭redis02 redis02() { cd ${REDIS02_PATH} ./start.sh stop } #关闭redis03 redis03() { cd ${REDIS03_PATH} ./start.sh stop } #根据输入的参数,选择对应的执行方法,不输入则执行使用说明 case "$1" in all) all ;; redis01) redis01 ;; redis02) redis02 ;; redis03) redis03 ;; *) usage ;; esac
-
:wq
-
chmod +x /usr/local/redis-master-slave/stop.sh
-
-
8、启动所有 Redis 实例
- /usr/local/redis-master-slave/start.sh all
-
9、查看 Reids 实例进程
-
ps -ef | grep redis
-
-
10、将第 1 步安装完的 Redis 的 bin 目录下的 redis-cli 文件复制到
/usr/local/redis-master-slave/
目录下- cp /usr/local/redis/bin/redis-cli /usr/local/redis-master-slave/
-
11、查看节点主从情况
-
/usr/local/redis-master-slave/redis-cli -a 123456 -p 6386
-
/usr/local/redis-master-slave/redis-cli -a 123456 -p 6387
-
/usr/local/redis-master-slave/redis-cli -a 123456 -p 6388
-
-
12、至此,Redis 主从同步就搭建成功了
七、Redis 主从同步测试
-
Master 测试
-
连接 Redis 集群 Master
- /usr/local/redis-master-slave/redis-cli -a 123456 -p 6386
-
进行测试
-
测试结果
-
由测试结果可知,在 Master 中写入数据会自动同步到 Slave
-
-
Slave 测试
-
连接 Redis 集群 Slave
- /usr/local/redis-master-slave/redis-cli -a 123456 -p 6387
-
进行测试
-
测试结果
- 由测试结果可知,在 Slave 中无法写入数据
-
八、参考资料
推荐阅读
-
【十七】redis之主从复制概述及部署
-
Redis -- 13 -- Redis主从同步搭建
-
十八、Redis主从同步原理-PSYNC
-
linux安装redis主备安装配置 博客分类: redis linuxredis主从配置
-
Redis-Cluster实战--13.redis Cluster故障转移(failover) 博客分类: redis-clusterredis failover故障转移redis cluster
-
oa信用盘源码搭建修复 安全地使用redis的pop命令 redis
-
redis的使用 redis主从集群
-
【缓存中间件】Redis主从复制演示
-
Redis的Cluster集群搭建(几个文章网址) 博客分类: NoSql---Redis redisclusternosql分布式数据库
-
PHP实现的redis主从数据库状态检测功能示例