概述
Redis有三种集群模式,分别是:主从模式、哨兵模式、Cluster模式
主从模式是三种模式中最简单的,在主从复制中分为主数据库(master)和从数据库(slave),若master出现宕机,需要手动配置slave转为master。
后来为了高可用提出来哨兵模式,可以选择出slave转为master,提升可用性,但不能动态扩充。
后来又有了cluster集群模式。
本文介绍主从模式,以及如何数据同步
主从复制
主从复制是数据同步方式,解决了单点故障的问题,但不能保证高可用(是高可用的基础)。主要用来实现 redis 数据的可靠性,防止主 redis 所在磁盘损坏,造成数据永久丢失。
主从之间采用异步复制的方式,以及采用读写分离的方式,主节点(master)可以进行读写操作,从节点(replica)一般是只读。也就是说,所有的数据修改只在主节点上进行,然后将最新的数据同步给节点,这样就使得主从服务器的数据是一致的。
命令:redis-server --replicaof 127.0.0.1 7001
执行该命令后,当前服务器得redis-server就会成为127.0.0.1 7001的从数据库了,使用从数据库可以使得数据更加安全。从数据库具有只读属性,不能写。
注意:
1)主从复制无法提供高可用和数据保护能力,因为主节点发生故障时,需要手动进行故障转移。
2)从节点主动向主节点建立连接,从节点主动同步主节点的数据。
数据同步方式
全量数据同步
- 从数据库连接到主数据库
- 从数据库发送ping命令,主数据库回复pong命令
发送ping主要是为了(相当于tcp的 keepalive 心跳包)检测主数据库是否有响应 - 从数据库发送一个同步命令,主数据库进行异步发送数据
无论主数据采用aof还是rdb的持久化方式,在主从复制的时候都以rdb的数据格式进行复制 - 从数据库根据rdb调整内存后,发送给主数据库完成同步命令
增量数据同步
在从数据库连接着主数据库情况下,由于网络原因,某些数据出现主从不一致的情况,这时候可以容忍数据不一致的情况,通过设置环形缓冲区,将网络抖动时候的数据先写入环形缓冲区,从数据库会记录一个偏移值,在主数据库发送数据前,从数据库先把偏移值发送给主数据库,看偏移值是否在环形缓冲区中,然后再将环形缓冲区中偏移值往后的数据发送到从数据库中。
主从复制的实现
服务器runid
RUNID用于构建主从的关系。无论主库还是从库都有自己的 RUN ID , RUN ID 启动时自动产生, RUN ID 由 40 个随机的十六进制字符组成。
当从库对主库初次复制时,主库将自身的 RUN ID 传送给从库,从库会将 RUN ID 保存。 当从库断线重连主库时,从库将向主库发送之前保存的 RUN ID :
- 从库 RUN ID 和主库 RUN ID 一致,说明从库断线前复制的就是当前的主库;主库尝试执行增量同步操作;
- 若不一致,说明从库断线前复制的主库并不时当前的主库,则主库将对从库执行全量同步操作。
复制偏移量
主从都会维护一个复制偏移量:
- 主库向从库发送 N 个字节的数据时,将自己的复制偏移量上加 N;
- 从库接收到主库发送的 N 个字节数据时,将自己的复制偏移量加上 N。
通过比较主从偏移量得知主从之间数据是否一致;偏移量相同,则数据一致;偏移量不同,则数据不一致。
环形缓冲区
本质:固定长度先进先出队列;
存储内容:如下图;
当因某些原因(网络抖动或从库宕机)从库与主库断开连接,避免重新连接后开始全量同步,在主库设置了一个环形缓冲区;该缓冲区会在从库失联期间累计主库的写操作;当从库重连,会发送自身的复制偏移量到主库,主库会比较主从的复制偏移量
- 若从库 offset 还在复制积压缓冲区中,则进行增量同步;
- 否则,主库将对从库执行全量同步。
配置
# redis.conf # 环形缓冲区的大小 为1mb repl-backlog-size 1mb # 如果所有从库断开连接 3600 秒后没有从库连接,则释放环形缓冲区 repl-backlog-ttl 3600
大小确定: disconnect_time * write_size_per_second
disconnect_time
:从库断线后重连主库所需的平均时间(以秒为单位);
write_size_per_second
:主库平均每秒产生的写命令数据量;
偏移量会出现环绕回去,变成0的情况吗?
偏移量最大为2^64,就算一天增加1个亿,也要好几千年,不会存在这种问题。