Redis主从复制
redis主从复制的一些概念理解
什么是主从复制
主从复制,是指将一台Redis服务器的数据,复制到其他的Redis服务器。前者称为主节点
(master/leader),后者称为从节点(slave/follower);数据的复制是单向的,只能由主节点到从节点。 Master以写为主,Slave 以读为主。默认情况下每一个redis服务器都是主节点,并且每一个主节点可以有多个从节点或者没有从节点,每一个从节点只能有一个主节点。
主从复制的作用
- 数据冗余:主从复制实现了数据的热备份,是持久化之外的一种数据冗余方式。
- 故障恢复:当主节点出现问题时,可以由从节点提供服务,实现快速的故障恢复;实际上是一种服务 的冗余。
- 负载均衡:在主从复制的基础上,配合读写分离,可以由主节点提供写服务,由从节点提供读服务 (即写Redis数据时应用连接主节点,读Redis数据时应用连接从节点),分担服务器负载;尤其是在写少读多的场景下,通过多个从节点分担读负载,可以大大提高Redis服务器的并发量。
- 高可用(集群)基石:除了上述作用以外,主从复制还是哨兵和集群能够实施的基础,因此说主从复 制是Redis高可用的基础。
项目应用
一般来说公司的redis不能只部署一台服务器,容易发生单点故障,接受所有请求负载(读多写少),压力较大。而且redis服务器的内存有限,一般最大为20G,所以单台机器肯定不够。通常公司中会以一主两从、读写分离的方式部署redis服务器。
详细配置步骤
- 先连一个redis客户端,看下服务器的信息
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:0
master_failover_state:no-failover
master_replid:74e8c8e47c171b686c177193ac386e3b84371d2b
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
可以看到如果不配置主从的话,默认情况下,每一台都是主节点,没有从节点
-
配置三台redis服务器
修改配置文件中的端口、pid名称、log文件名称、dump.rdb文件名称
[root@ecs-94482 bin]# ps -ef|grep redis
root 21717 1 0 15:02 ? 00:00:00 redis-server *:6379
root 21796 1 0 15:12 ? 00:00:00 redis-server *:6380
root 21802 1 0 15:12 ? 00:00:00 redis-server *:6381
root 21811 21506 0 15:13 pts/1 00:00:00 grep --color=auto redis
因为每一台默认都是主节点,所以主节点不用配置,我们选用默认端口作为主节点,下面来配置从节点
**注意**:配置从节点的命令为:(旧)slaveof ip port或者(新)replicaof ip port
- slave1配置
127.0.0.1:6381> 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:196 slave_repl_offset:196 slave_priority:100 slave_read_only:1 replica_announced:1 connected_slaves:0 master_failover_state:no-failover master_replid:5213e4f83b1b0f0d5e904b0436995e6a509aad08 master_replid2:0000000000000000000000000000000000000000 master_repl_offset:196 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:183 repl_backlog_histlen:14
- slave2配置
```bash
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:4
master_sync_in_progress:0
slave_read_repl_offset:112
slave_repl_offset:112
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:0
master_failover_state:no-failover
master_replid:5213e4f83b1b0f0d5e904b0436995e6a509aad08
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:112
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:112
- 主节点信息
127.0.0.1:6379> info replication # Replication role:master connected_slaves:2 slave0:ip=127.0.0.1,port=6380,state=online,offset=196,lag=0 slave1:ip=127.0.0.1,port=6381,state=online,offset=196,lag=1 master_failover_state:no-failover master_replid:5213e4f83b1b0f0d5e904b0436995e6a509aad08 master_replid2:0000000000000000000000000000000000000000 master_repl_offset:196 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1 repl_backlog_histlen:196
**注意**:
1. 上面的配置都是在命令行配置,服务器重启或者停止则失效
2. 从节点信息中`master_link_status:up`为up时表示工作正常
3. 如果主节点配置了密码,在从节点需要配置参数`masterauth`,主节点的密码
1. 测试
```bash
#主节点修改值
127.0.0.1:6379> get name
"sunt"
127.0.0.1:6379> set name suntong
OK
127.0.0.1:6379> get name
"suntong"
#从节点查看值
127.0.0.1:6380> get name
"suntong"
#从节点只能查看值,不能修改值
127.0.0.1:6380> get name
"suntong"
127.0.0.1:6380> set name sunt
(error) READONLY You can't write against a read only replica.
主从数据一致性
引用文章:redis核心篇(三)-高可用架构(一)之主从与哨兵 - 掘金 (juejin.cn)
如何保证主从节点数据一致,数据一致需要从主节点将数据同步到从节点,这个同步有几种方式:强一致性(同步)、弱一致性(异步)、最终一致性(消息队列)
- 强一致性:主从同步使用同步方式,保证数据一致性,但是没有高性能,即有高可靠,无高性能
- 弱一致性:主从同步使用异步方式,保证redis的高性能,但是可能会丢失数据,即有高性能,无高可靠
- 最终一致性:在主节点和从节点之间使用缓存区,消息队列,在高性能和高可靠之间折中,强调高一致性
主从同步原理
同步不仅仅是数据的同步,在数据同步的过程中,主节点继续产生的命令也需要同步,这就是命令同步。
主从复制分为
- 数据同步
- 首次连接到主节点,全量复制
- 断开重连,增量复制
- 命令同步
全量复制(sync)
在2.8版本之前只有全量复制
- 主从节点第一次连接时,从节点向主节点发送同步数据指令:psync ? -1,?号代表主服务器的id,-1代表偏移量,由于是第一次连接,这些信息还不知道,所以就用问号和-1代替。
- 主节点收到指令之后,返回信息给从节点:FULLRESYNC runID offset,告诉从节点主节点的id和偏移量,从节点保存信息。
- 主节点向从节点发送RDB文件,从节点加载RDB文件(第一次连接,从库收到RDB文件之后会清空数据库,再执行RDB文件)
- 主节点发送缓存区新写入的命令到从节点,从节点执行命令
这里的第四步就是命令复制,为什么需要这一步,因为主节点在生成RDB文件时是fork一个子线程去执行的,主节点没有阻塞,继续执行命令,这些命令也需要进行同步
断开重连(psync)
这是2.8版本之后新增的方式,通过偏移量进行增量复制,看下下面这幅图
在发生网络异常之后,主节点执行了一部分命令,但是从节点没有,这时候就需要psync
- [ ] 需要整理一下psync的流程
级联操作
主从复制,一个主节点可以有多个从节点,在进行复制时,需要给多个从节点进行复制,不管是全量复制还是增量复制,主节点fork子线程产生RDB文件时会有阻塞,给从节点传输RDB文件时会占用带宽,这个时候主从复制可以改成主从从模式,对从节点建立从节点,减轻主节点的压力,这叫做级联操作。
哨兵模式(自动选举master)
主从架构在可以用于读写分离,减轻单机压力,但是这样的高性能并不可靠,不能高可用,当主节点挂了之后,写能力就没有了,因此需要一种方式在主节点挂了之后,有其他的主节点替代,这就是哨兵,在哨兵模式出来之前,是通过手动的方式设置主节点,命令 slaveof no one
。哨兵是 Redis 的一种运行模式,它专注于对 Redis 实例的运行状态进行监控,并能够在主节点发生故障时通过一系列的机制实现选主及主从切换,实现故障转移,确保整个 Redis 系统的可用性;