Redis–主从同步
和Mysql主从复制的原因一样,Redis虽然读取写入的速度都特别快,但是也会产生读压力特别大的情况。为了分担读压力,Redis支持主从复制,Redis的主从结构可以采用一主多从或者级联结构,Redis主从复制可以根据是否是全量分为全量同步和增量同步。
主从同步
为什么要主从同步?
读写分离:通过主从复制的方式来同步数据,然后通过读写分离提高数据库并发处理能力,提高数据库的吞吐量。
数据备份:我们通过主从复制将主库上的数据复制到了从库上,相当于是一种热备份机制,也就是在主库正常运行的情况下进行的备份,不会影响到服务。
高可用性:数据备份实际上是一种冗余的机制,通过这种冗余的方式可以换取数据库的高可用性,也就是当服务器出现故障或宕机的情况下,可以切换到从服务器上,保证服务的正常运行。
全量同步过程
Redis全量复制一般发生在Slave初始化阶段,这时Slave需要将Master上的所有数据都复制一份。具体步骤如下:
- 从服务器连接主服务器,发送SYNC命令;
- 主服务器接收到SYNC命名后,开始执行BGSAVE命令生成RDB文件并使用缓冲区记录此后执行的所有写命令;
- 主服务器BGSAVE执行完后,向所有从服务器发送快照文件,并在发送期间继续记录被执行的写命令;
- 从服务器收到快照文件后丢弃所有旧数据,载入收到的快照;
- 主服务器快照发送完毕后开始向从服务器发送缓冲区中的写命令;
- 从服务器完成对快照的载入,开始接收命令请求,并执行来自主服务器缓冲区的写命令;
完成上面几个步骤后就完成了从服务器数据初始化的所有操作,从服务器此时可以接收来自用户的读请求。
增量同步
增量同步出现在Redis的2.8版本之后,在2.8版本之前,每次的同步都是全量同步
Redis增量复制是指Slave初始化后开始正常工作时主服务器发生的写操作同步到从服务器的过程。
增量复制的过程主要是主服务器每执行一个写命令就会向从服务器发送相同的写命令,从服务器接收并执行收到的写命令
Redis主从同步策略
主从刚刚连接的时候,进行全量同步;全同步结束后,进行增量同步。当然,如果有需要,slave 在任何时候都可以发起全量同步。redis 策略是,无论如何,首先会尝试进行增量同步,如不成功,要求从机进行全量同步。
注意点
如果多个Slave断线了,需要重启的时候,因为只要Slave启动,就会发送sync请求和主机全量同步,当多个同时出现的时候,可能会导致Master IO剧增宕机。
主从复制的特点
1)采用异步复制;
2)一个主redis可以含有多个从redis;
3)每个从redis可以接收来自其他从redis服务器的连接;
4)主从复制对于主redis服务器来说是非阻塞的,这意味着当从服务器在进行主从复制同步过程中,主redis仍然可以处理外界的访问请求;
5)主从复制对于从redis服务器来说也是非阻塞的,这意味着,即使从redis在进行主从复制过程中也可以接受外界的查询请求,只不过这时候从redis返回的是以前老的数据,如果你不想这样,那么在启动redis时,可以在配置文件中进行设置,那么从redis在复制同步过程中来自外界的查询请求都会返回错误给客户端;(虽然说主从复制过程中对于从redis是非阻塞的,但是当从redis从主redis同步过来最新的数据后还需要将新数据加载到内存中,在加载到内存的过程中是阻塞的,在这段时间内的请求将会被阻,但是即使对于大数据集,加载到内存的时间也是比较多的);
6)主从复制提高了redis服务的扩展性,避免单个redis服务器的读写访问压力过大的问题,同时也可以给为数据备份及冗余提供一种解决方案;
7)为了编码主redis服务器写磁盘压力带来的开销,可以配置让主redis不在将数据持久化到磁盘,而是通过连接让一个配置的从redis服务器及时的将相关数据持久化到磁盘,不过这样会存在一个问题,就是主redis服务器一旦重启,因为主redis服务器数据为空,这时候通过主从同步可能导致从redis服务器上的数据也被清空;
Redis的异步复制过程
主节点不但负责数据读写,还负责把写命令同步给从节点,写命令的发送过程是异步完成,也就是说主节点处理完写命令后立即返回客户端,并不等待从节点复制完成。
异步复制的步骤很简单,如下:
1. 主节点接受处理命令。
2. 主节点处理完后返回响应结果 。
3. 对于修改命令,异步发送给从节点,从节点在主线程中执行复制的命令。
Redis主从同步的实现
1.主服务器
注意:主服务器必须设置密码,否则会失败
vim redis.conf
daemonize yes #允许后台运行
dir /usr/local/redis/data #设置数据的存放位置
requirepass 1234 #注意:主服务器必须设置密码,否则会失败
bind 127.0.0.1 192.168.4.112 #设置master的监听地址,或者将bind注释掉
logfile "/usr/local/redis/log" #设置日志文件
2.从服务器
#Redis的5.x版本以下 在主从同步的时候使用
从:slaveof <masterip> <masterport> #Redis的主从同步,<masterip>主服务器ip,<masterport>主服务器密码
masterauth <master-password> #设定主服务器的密码,<master-password>代表密码
#Redis5.x版本以上
从:replicaof <masterip> <msterport> #主服务器的IP和端口
masterauth <masterpass> #主服务器的密码(主服务器要设置好密码)
vim redis.conf
daemonize yes #允许后台运行
logfile "/usr/local/redis/log" #设置日志文件
dir /usr/local/redis/data #设置数据的存放位置
slaveof 192.168.4.112 6379 #开启主从同步,master的IP和port
masterauth 1234 #master的密码
3.查看主从是否连接
登录slave
[root@localhost redis]# ./bin/redis-cli
127.0.0.1:6379> info #登录slave后执行info命令,查询主从同步情况
# Replication
role:slave #从服务器
master_host:192.168.4.112 #主服务器IP
master_port:6379 #主服务器port
master_link_status:up #主服务器连接状态,up表示正常连接,down表示连接失败
登录master
[root@localhost redis]# ./bin/redis-cli
127.0.0.1:6379> auth 1234
OK
127.0.0.1:6379> info #登录slave后执行info命令,查询主从同步情况
# Replication
role:master #主服务器
connected_slaves:1 #当前有一个从服务器连接成功
slave0:ip=192.168.4.113,port=6379,state=online,offset=71,lag=0 #从服务器信息