第4章 Redis主从复制
1. Redis主从复制介绍
虽然持久化可以确保数据最大限度不丢失,但如果服务器宕机,单台 Redis 无法继续提供服务。为解决数据单点问题,Redis 提供了多种高可用方案:主从复制、哨兵模式和集群模式。
Redis 的主从复制部署简单,是哨兵模式和集群模式的基础,理解主从复制流程对掌握后续集群实验十分重要。
2. 主从复制搭建部署
节点规划
以单机多实例方式部署:
- 主节点:10.0.0.51:6379
- 从节点:10.0.0.51:6380
创建第二个实例
1)创建目录:
[root@db-51 ~]# mkdir -p /opt/redis_6380/{conf,logs,pid}
[root@db-51 ~]# mkdir -p /data/redis_6380
2)创建配置文件:
[root@db-51 ~]# cat /opt/redis_6380/conf/redis.conf
daemonize yes
bind 127.0.0.1 10.0.0.51
port 6380
pidfile /opt/redis_6380/pid/redis.pid
logfile /opt/redis_6380/logs/redis.log
dir /data/redis_6380
dbfilename redis.rdb
启动实例
启动命令:
[root@db-51 ~]# redis-server /opt/redis_6380/conf/redis.conf
检查服务:
[root@db-51 ~]# netstat -lntup|grep redis
tcp 0 0 127.0.0.1:6379 0.0.0.0:* LISTEN 3040/redis-server 1
tcp 0 0 10.0.0.51:6379 0.0.0.0:* LISTEN 3040/redis-server 1
tcp 0 0 127.0.0.1:6380 0.0.0.0:* LISTEN 3338/redis-server 1
tcp 0 0 10.0.0.51:6380 0.0.0.0:* LISTEN 3338/redis-server 1
配置主从关系
配置复制只需一条命令:
slaveof {masterHost} {masterPort}
操作步骤:
[root@db-51 ~]# redis-cli -p 6380
127.0.0.1:6380> SLAVEOF 10.0.0.51 6379
OK
持久化配置:
127.0.0.1:6380> CONFIG REWRITE
OK
配置文件会自动添加:
# Generated by CONFIG REWRITE
replicaof 10.0.0.51 6379
3. 主从复制测试
主节点写入测试
[root@db-51 ~]# redis-cli -p 6379
127.0.0.1:6379> set db-51 db-51
OK
127.0.0.1:6379> get db-51
"db-51"
从节点验证同步
[root@db-51 ~]# redis-cli -p 6380
127.0.0.1:6380> get db-51
"db-51"
从节点写入测试
127.0.0.1:6380> set db-52 db-52
(error) READONLY You can't write against a read only replica.
💡 测试结论
- 从库可以正常同步主库数据
- 从库只读不可写
4. 断开复制关系
使用 slaveof no one
命令可主动断开复制关系,从节点升级为主节点。
断开复制步骤
1)主库写入数据:
[root@db-51 ~]# redis-cli -p 6379
127.0.0.1:6379> set k1 v1
OK
2)从库验证数据:
[root@db-51 ~]# redis-cli -p 6380
127.0.0.1:6380> get k1
"v1"
3)从库断开复制:
127.0.0.1:6380> SLAVEOF no one
OK
4)主库继续写入:
127.0.0.1:6379> set k2 v2
OK
5)从库验证不再同步:
127.0.0.1:6380> keys *
1) "k1"
断开后,已同步的数据会保留,但不再接收新数据。
5. 主从复制流程分析
通过分析日志可以让我们更清晰的理解主从复制的流程,我们将主库和从库的日志过按照时间线的顺序简化后排列如下:
1)从库发送复制请求
19:54:03.778 * Connecting to MASTER 10.0.0.51:6379
19:54:03.778 * MASTER <-> REPLICA sync started
19:54:03.778 * Non blocking connect for SYNC fired the event.
2)主库接收到从库的复制请求后开始持久化数据
19:54:03.779 * Replica 127.0.0.1:6380 asks for synchronization
19:54:03.779 * Starting BGSAVE for SYNC with target: disk
19:54:03.778 * Connecting to MASTER 10.0.0.51:6379
19:54:03.778 * MASTER <-> REPLICA sync started
19:54:03.778 * Non blocking connect for SYNC fired the event.
3)主库将持久化后的RDB文件发给从库
19:54:03.784 * DB saved on disk
19:54:03.785 * RDB: 4 MB of memory used by copy-on-write
19:54:03.880 * Background saving terminated with success
19:54:03.880 * Synchronization with replica 127.0.0.1:6380 succeeded
4)从库接收到主库发来的RDB文件后做了2件事
清空自己的旧数据:
19:54:03.880 * MASTER <-> REPLICA sync: receiving 208 bytes from master
19:54:03.880 * MASTER <-> REPLICA sync: Flushing old data
载入主库的发送过来的数据:
19:54:03.881 * MASTER <-> REPLICA sync: Loading DB in memory
19:54:03.881 * MASTER <-> REPLICA sync: Finished with success
5)复制关系建立成功,后续主库的命令都会被同步到从库上
2020 19:54:03.880 * Background saving terminated with success
2020 19:54:03.880 * Synchronization with replica 127.0.0.1:6380 succeeded
6. 注意事项
⚠️ 主从复制注意事项
- 主库意外宕机后从库不会主动切换,需要人工介入
- 从库建立复制时会清空当前所有数据
- 从库只读不可写,不能分担写入压力
- 从库断开复制后会保留已有数据
- 如果主库有密码认证,从库需配置:
masterauth 主库密码
7. 复制信息说明
使用 INFO replication
查看复制信息,主要字段含义:
role: 表明当前服务器的角色,这里是slave,即从节点。
master_host: 主节点的IP地址,这里是10.0.0.51。
master_port: 主节点的端口号,这里是6379。
master_link_status: 从节点与主节点的连接状态,up表示当前正常连接。
master_last_io_seconds_ago: 上一次从主节点接收数据的时间,单位是秒,这里是8秒前。
master_sync_in_progress: 是否有正在进行的同步操作,0表示没有同步正在进行。
slave_repl_offset: 从节点的复制偏移量,标识从节点复制数据的进度,这里是389046。
slave_priority: 从节点的优先级,用于故障转移决策。数值越小,优先级越高,这里是100。
slave_read_only: 从节点是否只读,1表示只读。
connected_slaves: 连接到当前从节点的其他从节点数量,这里是0。
master_replid: 主节点的复制ID,这是一个唯一标识符,用于追踪复制进程,这里是4a50f7c2ab74042671208a6390de746d76361dc7。
master_replid2: 第二个复制ID,用于在主节点故障恢复后保持复制连续性,这里显示为全0,表示当前未使用。
master_repl_offset: 主节点的复制偏移量,与从节点的slave_repl_offset应当相匹配,这里也是389046。
second_repl_offset: 第二个复制偏移量,通常用于故障恢复,这里是-1,表示未使用。
repl_backlog_active: 复制积压缓冲区是否激活,1表示激活。
repl_backlog_size: 复制积压缓冲区的大小,这里是1048576字节。
repl_backlog_first_byte_offset: 复制积压缓冲区中的第一个字节的偏移量,这里是388613。
repl_backlog_histlen: 复制积压缓冲区中数据的长度,这里是434字节。
💡 最佳实践
主从复制是 Redis 高可用的基础,生产环境建议结合哨兵模式或集群模式使用,实现自动故障转移。
更新: 2024-07-30 11:36:55