Redis 单点架构有以下问题
在从节点开启主从复制,有 3 种方式:
首先下载一个单机redis服务器,然后复制两份 redis-6380.conf和redis-6381.conf文件,分别更改以下相关配置从节点:
port 6380 # 从节点6380 (下同)
replicaof 192.168.0.60 6379 # 配置从节点访问主节点(下同)
slave-read-only yes # 配置从节点只读操作(下同)
port 6381
replicaof 192.168.0.60 6379
slave-read-only yes
在控制台执行 redis‐server redis-6379.conf、redis‐server redis-6380.conf、redis‐server redis-6381.conf。命令启动redis一主二从服务。
启动成功后,测试一下在主节点添加数据,从节点是否会同步主节点数据。
往从节点添加数据是否会插入成功。
看上图,往主节点set数据后,在从节点能get到数据。往从节点set数据会提示read only。
至此搭建完成了。
当slave与master再次断开链接后,slave能自动重连master,如果master收到了多个slave并发连接请求,那它也只会持久化一次,而不是一个连接持久化一次,再把这个持久化文件发送给其他slave。
slave 做复制的时候,不会 block maste的正常工作;
slave在做复制的时候,也不会 block 对自己的查询操作,它会用旧的数据集来提供服务;但是复制完成的时候,需要删除旧数据集,加载新数据集,这个时候就会暂停对外服务了
Redis在2.8.18版本开始实现了无磁盘复制功能
master 在内存中直接创建 RDB,然后发送给 slave,不会在自己本地落地磁盘了。
只需要在配置文件中开启 repl-diskless-sync yes 即可。
repl-diskless-sync yes
当有客户端的写命令请求到主节点后,主节点会将写命令写入到复制积压缓冲区。
复制积压缓冲区:其实就是一个有界队列,保存着最近传播的写命令,而队列里面的每个字节都有一个偏移量标识。
复制积压缓冲区有几个特点:
如下图所示,每一个字节对应一个偏移量。
节点重新连上主节点后,会发送 psync 命令,携带着偏移量 offset。比如 offset = 125,然后主节点拿着这个 125 去复制积压缓冲区找,125 正好在里面,然后就会执行部分复制的操作,将 125 以后的缓冲数据发送给从节点。
如果 offset =10,主节点拿着这个 10 去复制积压缓冲区找,发现队列中最早的 offset 是 100,所以 100 之前的字节都被覆盖了,那么子节点就不能通过复制积压缓冲区拿到完整数据,所以只能通过全量复制的方式来同步。这个时候主节点就会发送一个 FULLRESYNC的命令给子节点,告诉子节点,兄弟,你来得太晚了,只能使用全量同步的方式了。
不管是全量复制还是部分复制,最开始都会发送一个 psync 命令给主节点,那么主节点会根据这个命令携带的参数 runId 和 offset,来决定如何响应。
全量复制过程总共可以分为 9 步:
psync 命令格式如下:
psync {runId} {offset}
runId 是 每个 Redis 实例启动时随机生成的一个 ID,用来唯一标记这台 Redis 实例。由于第一次复制时,刚启动时会随机生成 runId,只有自己知道,外人是不知道的,所以从节点是不知道主节点的 runId 的,这个时候发送 psync 命令时 runId 就是一个问号。第一次复制时,offset 默认为 -1。也就是全量复制
由上面的几个步骤可以看出,全量复制是非常耗时的,可能比较大的时间开销如下:
第四步,主节点 fork 出子进程执行 bgsave 时,fork 操作耗时。
第五步,RDB 文件的网络传输时间。
第七步,从节点清空数据花时间。
第八步,从节点加载 RDB 的时间。
第九步,AOF 的重写时间。
所以除了第一次需要采用全量复制外,其他场景应该避免全量复制的发生。下面介绍另外一种复制方式,可以极大提高复制的效率。
Redis 主从的增量复制就是指当主从之间的网络故障等原因造成持续复制中断了,当从节点再次连上主节点后,主节点就补发数据给从节点,避免了全量复制的过高开销。补发数据的来源就是复制积压缓冲的数据。
如果有很多slave,那为了缓解主从复制风暴(多个slave同时复制master数据,导致master压力过大),可以做下列架构,让部分slave与slave进行同步数据。
① Slave 宕机
在Redis中,从库重新启动会自动加入到主从架构中,自动完成同步数据
Redis 2.8之后,在从库有做持久化的前提下,如果从库在断开的期间,主库的变化不大,从库再次启动后,主库不会将已有的数据进行RDB操作,而是进行增量复制。
② Master 宕机
一 : 在Slave中执行SLAVEOF NO ONE 命令,断开主从关系并且提升为主库继续服务;
二 : 将主库重新启动后,执行 SLAVEOF命令,将其设置为其他Redis的从库,这个时候数据就同步回来了;
原因:
哨兵是Redis的一种运行模式,它专注于对Redis实例(主节点、从节点)运行状态的监控,并能够在主节点发生故障时通过一系列的机制实现选主及主从切换,实现故障转移,确保整个Redis系统的可用性。
一般情况下,哨兵节点每隔10秒(故障转移时每隔1秒)向主从节点发送INFO命令,以此获取主从节点的信息。第一次执行时,哨兵仅知道我们给出的主节点信息,通过对主节点执行INFO命令就可以获取其从节点列表。如此周期性执行,就可以不断发现新加入的节点。
哨兵模式的监控配置信息,是通过配置从数据库的 sentinel monitor master-name ip redis-port quorum 来指定的,比如:
// mymaster 表示给master数据库定义了一个名字,后面的是master的ip和端口,1表示至少需要一个Sentinel进程同意才能将master判断为失效,如果不满足这个条件,则自动故障转移(failover)不会执行
sentinel monitor mymaster 127.0.0.1 6379 1
当哨兵启动后,会与master建立一条连接,用于订阅master的 sentinel:hello 频道。
该频道用于获取监控该master的其它哨兵的信息。并且还会建立一条定时向master发送INFO命令获取master信息的连接。
「当哨兵与master建立连接后,定期会向(10秒一次)master和slave发送INFO命令,若是master被标记为主观下线,频率就会变为1秒一次。」
并且,定期向 sentinel:hello 频道发送自己的信息,以便其它的哨兵能够订阅获取自己的信息。
以及,「定期的向master、slave和其它哨兵发送PING命令(每秒一次),以便检测对象是否存活」,若是对方接收到了PING命令,无故障情况下,会回复PONG命令。
所以,哨兵通过建立这两条连接、通过定期发送INFO、PING命令来实现哨兵与哨兵、哨兵与master之间的通信。
当master被认为客观下线后,又是怎么进行故障恢复的呢?原来哨兵中首先选举出一个老大哨兵来进行故障恢复,选举老大哨兵的算法叫做「Raft算法」:
选出大佬哨兵后,大佬哨兵就会对故障进行自动回复,从slave中选出一名slave作为主数据库,选举的规则如下所示:
通过以上的层层筛选最终实现故障恢复,当选的slave晋升为master,其它的slave会向新的master复制数据,若是down掉的master重新上线,会被当作slave角色运行。
同时创建一个文件夹用于存放三个哨兵的配置文件:
mkdir /root/redis-4.0.6/sentinel.conf /root/redis/sentinel/sentinel1.conf
mkdir /root/redis-4.0.6/sentinel.conf /root/redis/sentinel/sentinel2.conf
mkdir /root/redis-4.0.6/sentinel.conf /root/redis/sentinel/sentinel3.conf
分别在这三个文件中添加如下配置:
daemonize yes # 在后台运行
sentinel monitor mymaster 127.0.0.1 6379 1 # 给master起一个名字mymaster,并且配置master的ip和端口
sentinel auth-pass mymaster 123456 # master的密码
port 26379 #另外两个配置36379,46379端口
sentinel down-after-milliseconds mymaster 3000 # 3s未回复PING就认为master主观下线
sentinel parallel-syncs mymaster 2 # 执行故障转移时,最多可以有2个slave实例在同步新的master实例
sentinel failover-timeout mymaster 100000 # 如果在10s内未能完成故障转移操作认为故障转移失败
配置完后分别启动三台哨兵:
./redis-server sentinel1.conf --sentinel
./redis-server sentinel2.conf --sentinel
./redis-server sentinel3.conf --sentinel