跳到主要内容

第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