主从复制
- 随着项目访问量的增加,对Redis服务器的操作也越加频繁,虽然Redis读写速度都很快,但是一定程度上也会造成一定的延时,那么为了解决访问量大的问题,通常会采取的一种方式是主从架构Master/Slave,Master 以写为主,Slave 以读为主。
(1)原理
-
Redis 一般是使用一个 Master 节点来进行写操作,而若干个 Slave 节点进行读操作,Master 和 Slave 分别代表了一个个不同的 Redis Server 实例。
-
另外定期的数据备份操作也是单独选择一个 Slave 去完成,这样可以最大程度发挥 Redis 的性能,为的是保证数据的弱一致性和最终一致性。
-
另外,Master 和 Slave 的数据不是一定要即时同步的,但是在一段时间后 Master 和 Slave 的数据是趋于同步的,这就是最终一致性。
全同步过程如下:
- Slave 发送 Sync 命令到 Master。
- Master 启动一个后台进程,将 Redis 中的数据快照保存到文件中。
- Master 将保存数据快照期间接收到的写命令缓存起来。
- Master 完成写文件操作后,将该文件发送给 Slave。
- 使用新的 RDB 或 AOF 文件替换掉旧的 RDB 或 AOF 文件。
- Master 将这期间收集的增量写命令发送给 Slave 端。
增量同步过程如下:
- Master 接收到用户的操作指令,判断是否需要传播到 Slave。
- 将操作记录追加到 AOF 文件。
- 将操作传播到其他 Slave:对齐主从库;往响应缓存写入指令。
- 将缓存中的数据发送给 Slave。
(2)配置
展示配置文件
[root@db ~]# ls -l /etc/redis.conf
-rw-r--r--. 1 root root 107553 Jul 21 08:55 /etc/redis.conf
复制文件
[root@db ~]# cp /etc/redis.conf /etc/redis-6380.conf
[root@db ~]# cp /etc/redis.conf /etc/redis-6381.conf
改配置
[root@db ~]# vim /etc/redis-6380.conf
port=6380
[root@db ~]# vim /etc/redis-6381.conf
port=6381
启动服务
[root@db ~]# redis-server /etc/redis.conf
[root@db ~]# redis-server /etc/redis-6380.conf
[root@db ~]# redis-server /etc/redis-6381.conf
查看启动的服务
[root@db ~]# ps -ef |grep redis
root 2762 1 0 15:17 ? 00:00:00 redis-server 127.0.0.1:6379
root 2768 1 0 15:18 ? 00:00:00 redis-server 127.0.0.1:6380
root 2774 1 0 15:18 ? 00:00:00 redis-server 127.0.0.1:6381
root 2780 2293 0 15:18 pts/0 00:00:00 grep --color=auto redis
分别三个会话,开启redis数据库
[root@db ~]# redis-cli -p 6379
[root@db ~]# redis-cli -p 6380
[root@db ~]# redis-cli -p 6381
实现一主二从
6379(主)
查看状态信息
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:0
master_failover_state:no-failover
master_replid:a03df1e3196bc990841820946a7c40b56cfea797
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
设置完成后看状态
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=127.0.0.1,port=6380,state=online,offset=42,lag=0
slave1:ip=127.0.0.1,port=6381,state=online,offset=42,lag=0
master_failover_state:no-failover
master_replid:9f6a7cecb3b093a3b4dc9453e1ae676ea0038727
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:42
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:42
6380(从)
查看状态信息
127.0.0.1:6380> info replication
# Replication
role:master
connected_slaves:0
master_failover_state:no-failover
master_replid:1074a837af6a76cf03794baa64d8f223d8d71994
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
设置主从
127.0.0.1:6380> SLAVEOF 127.0.0.1 6379
OK
显示信息
127.0.0.1:6380> info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6379
master_link_status:up
master_last_io_seconds_ago:3
master_sync_in_progress:0
slave_read_repl_offset:56
slave_repl_offset:56
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:0
master_failover_state:no-failover
master_replid:9f6a7cecb3b093a3b4dc9453e1ae676ea0038727
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:56
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:15
repl_backlog_histlen:42
6381(从)
查看状态信息
127.0.0.1:6381> info replication
# Replication
role:master
connected_slaves:0
master_failover_state:no-failover
master_replid:699210b4ab00bc0a1e353461624161235513ce91
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
设置主从
127.0.0.1:6381> SLAVEOF 127.0.0.1 6379
OK
127.0.0.1:6381> info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6379
master_link_status:down
master_last_io_seconds_ago:-1
master_sync_in_progress:0
slave_read_repl_offset:0
slave_repl_offset:0
master_link_down_since_seconds:-1
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:0
master_failover_state:no-failover
master_replid:699210b4ab00bc0a1e353461624161235513ce91
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
测试实现结果
6379写入信息
127.0.0.1:6379> set k4 v4
OK
127.0.0.1:6379> set k5 v5
OK
(增量同步)
6380得到信息
127.0.0.1:6380> get k4
"v4"
127.0.0.1:6380> get k5
"v5"
6381得到信息
127.0.0.1:6381> get k4
"v4"
127.0.0.1:6381> get k5
"v5"
场景:主服务器宕机(6379)
6379宕机
127.0.0.1:6379> shutdown
not connected> exit
6380和6381的状态(还是从)
127.0.0.1:6380> info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6379
master_link_status:down
master_last_io_seconds_ago:-1
master_sync_in_progress:0
slave_read_repl_offset:683
slave_repl_offset:683
master_link_down_since_seconds:6
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:0
master_failover_state:no-failover
master_replid:9f6a7cecb3b093a3b4dc9453e1ae676ea0038727
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:683
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:15
repl_backlog_histlen:669
手动i切换从为主
6380
127.0.0.1:6380> SLAVEOF no one
OK
127.0.0.1:6380> info replication
# Replication
role:master
connected_slaves:0
master_failover_state:no-failover
master_replid:d3920414629d249811a9b7a685ef0a7362af095a
master_replid2:9f6a7cecb3b093a3b4dc9453e1ae676ea0038727
master_repl_offset:683
second_repl_offset:684
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:15
repl_backlog_histlen:669
6381
127.0.0.1:6381> SLAVEOF 127.0.0.1 6380
OK
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:2
master_sync_in_progress:0
slave_read_repl_offset:683
slave_repl_offset:683
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:0
master_failover_state:no-failover
master_replid:d3920414629d249811a9b7a685ef0a7362af095a
master_replid2:9f6a7cecb3b093a3b4dc9453e1ae676ea0038727
master_repl_offset:683
second_repl_offset:684
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:43
repl_backlog_histlen:641
这样手动配置并不理想,因此需要另一种方式
(3)哨兵模式
- 哨兵也叫 sentinel,它的作用是能够在后台监控主机是否故障,如果故障了根据投票数自动将从库转换为主库
配置
(1)首先实现一主两从(上面设置过。这里不多赘述)
(2)设置哨兵模式
编辑配置文件
[root@db ~]# vim /usr/local/redis-stable/sentinel.conf
只是一主两从,所以设置为1,1代表的是同意的哨兵数量
sentinel monitor mymaster 127.0.0.1 6379 1
复制文件到之前使用的redis服务文件的位置
[root@db ~]# cp /usr/local/redis-stable/sentinel.conf /etc/
[root@db ~]# ls -l /etc/sentinel.conf
-rw-r--r--. 1 root root 14744 Jul 21 16:00 /etc/sentinel.conf
启动哨兵模式
[root@db ~]# redis-sentinel /etc/sentinel.conf
完成
2987:X 21 Jul 2024 16:02:05.749 * Sentinel new configuration saved on disk
2987:X 21 Jul 2024 16:02:05.749 * Sentinel ID is 70cc26ad4ee55999c9fcf4e0ffbf4fde7cdc2a5a
2987:X 21 Jul 2024 16:02:05.749 # +monitor master mymaster 127.0.0.1 6379 quorum 1
2987:X 21 Jul 2024 16:02:05.750 * +slave slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6379
2987:X 21 Jul 2024 16:02:05.751 * Sentinel new configuration saved on disk
2987:X 21 Jul 2024 16:02:05.751 * +slave slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 6379
2987:X 21 Jul 2024 16:02:05.751 * Sentinel new configuration saved on disk
测试
宕掉6379
127.0.0.1:6379> info replication
Error: Server closed the connection
刷新的时候会报错一下,第二次就没事了
127.0.0.1:6380> info replication
Error: Broken pipe
not connected> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=127.0.0.1,port=6381,state=online,offset=32836,lag=0
slave1:ip=127.0.0.1,port=6379,state=online,offset=32969,lag=0
master_failover_state:no-failover
master_replid:f5acfdbf7416845d1a2bdf6f6dde8d9a57142604
master_replid2:6b4227927765c859a8fc8c8aae06160f836c306c
master_repl_offset:32969
second_repl_offset:10650
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:15
repl_backlog_histlen:32955
测试成功
集群(后续会补充)