Redis主从复制的基本概念
一般,系统的高可用都是通过部署多台机器实现的。redis为了避免单点故障,也需要部署多台机器。因为部署了多台机器,所以就会涉及到不同机器的的数据同步问题。为此,redis提供了Redis提供了复制(replication)功能,当一台redis数据库中的数据发生了变化,这个变化会被自动的同步到其他的redis机器上去。redis多机器部署时,这些机器节点会被分成两类,一类是主节点(master节点),一类是从节点(slave节点)。一般主节点可以进行读、写操作,而从节点只能进行读操作。同时由于主节点可以写,数据会发生变化,当主节点的数据发生变化时,会将变化的数据同步给从节点,这样从节点的数据就可以和主节点的数据保持一致了。一个主节点可以有多个从节点,但是一个从节点会只会有一个主节点,也就是所谓的一主多从结构。
Redis主从复制能干嘛&怎么玩
下面我们看看Redis主从复制怎么玩
下面说一下这个权限细节,到底是怎么回事
- master如果配置了requirepass参数,需要密码登陆
- slave就要配置masterauth来设置校验密码否则的话master会拒绝slave的访问请求。
基本操作命令:
下面解释一下上面这些命令的含义:
- info replication: 可以查看复制节点的主从关系和配置信息
- replicaof IP Port:拜谁的码头,其实就是去寻找你的大哥从他哪里拷贝数据
- slaveof IP Port: 改换门庭,重新拜大哥了。
- slaveof no one:使当前数据库停止与其他数据库的同步,转成主数据库,自立为王
配置Redis主从复制&redis主从问题探究
在配置Redis主从复制之前,说一下我们需要配置那些东西。说完之后我们在来看看这个如何配置这个从主复制。
这两个需要将其修改一下,保护模式将其关闭。
在从机这里我们需要添加主机的ip和port和这个密码。
下面我们看一下我们本次的架构图
配置完成之后我们可以通过info replication命令来查看这个每台机器的状态信息.
然后我们在看一下这个6381这台从机
最后我们在看一下主机6379
现在我们已经将这个主从搭建好了。重点需要注意这个从机的这个master_link_status需要检查一下是否链接成功。
下面我们探究一下这几个问题
首先我们从这个从机能执行写命令吗?可能很多人第一反应可定不能写。那到底是不是这样的了下面我们在6380这台机器上执行一下这个写命令
我们发现这个执行成功了,很多网上直接说是不能的。 Redis之所以将从服务器默认设置为只读服务器,是为了确保从服务器 只能通过与主服务器进行数据同步来得到更新,从而保证主从服务器之间的数据一致性。
但在某些情况下,我们可能想要将一些不太重要或者临时性的数据存储 在从服务器中,或者不得不在从服务器中执行一些带有写性质的命令 (比如ZINTERSTORE命令,它只能将计算结果存储在数据库中,不能 直接返回计算结果)。这时我们可以通过将replica-read-only配置选项的 值设置为no来打开从服务器的写功能:
由于博主这个将其设置了为no所以这个从机也能写入数据。如果我们将这个no改为这个yes那么从机就不能写入数据了。
注意:修改配置文件之后我们需要将redis重启
2.下面我们看第二个问题从机切入问题
slave是从头开始复制还是从切入点开始复制? master启动,写到k3 slave1跟着master同时启动,跟着写到k3 slave2写到k3后才启动,那之前的是否也可以复制?
下面我们将6381这机器给shutdown然后了。然后我们主机写一条数据我们看这个6381这台机器他是否有这条记录。
我们发现这个数据是有的。首次连接进行全量复制,后续跟随,master写,slave跟。
3.主机宕机了,从机会自动上位吗?
下面我们将这个主机shutdow,然后查看这个从机的状态。
我们发现这个从机依然是从机,连接断了。原地待命等待主机复活王者归来。
3.主机宕机之后,重新恢复主从关系是否还能恢复。
下面我们将主机重启,再次查看这个主从复制关系是否还在是否依然能够复制数据。
我们发现这个主从复制的关系恢复了。
5.某台从机down后,master继续,从机重启后它能跟上大部队吗?
这个答案是当然肯定能够跟上,这个由于这个上面已经演示过了在这里就不重复演示了。
下面我们在看一下这个一些手动执行指令。
1.如果我们将这个redis.conf当中的replicaof 这一行给删除掉,然后我们重启服务。那么这个每台机器就都是这个主机了。在这里就不在演示了。
2.我们可以使用这个slave of Ip port 重新拜这个码头,也就是重新认主机。但是注意我们使用这个命令执行指定的重新认主机,当服务器重新启动之后这个关系将会消失。
3.slaveof no one 使当前数据库停止与其他数据库的同步,转成主数据库同样的服务器重启之后效果也会消失。
复制的原理&工作流程
复制的主要流程主要如下:
下面解释一下上面这些东西:
- slave启动,成功连接到master之后会发送一个sync命令,slave首次全新连接master,一次完全同步(全量复制)将被自动执行,slave自身原有数据会被master数据覆盖清除。
- master节点收到sync命令后会开始在后台保存快照(即RDB持久化,主从复制时会触发RDB),同时收集所有接收到的用于修改数据集命令缓存起来,master节点执行RDB持久化完后,master将rdb快照文件和所有缓存的命令发送到所有slave,以完成一次完全同步。而slave服务在接收到数据库文件数据后,将其存盘并加载到内存中,从而完成复制初始化
- Master继续将新的所有收集到的修改命令自动依次传给slave,完成同步。
- master会检查backlog里面的offset,master和slave都会保存一个复制的offset还有一个masterId,offset是保存在backlog中的。Master只会把已经复制的offset后面的数据复制给Slave,类似断点续传。
复制的缺点:
由于所有的写操作都是先在Master上操作,然后同步更新到Slave上,所以从Master同步到Slave机器有一定的延迟,当系统很繁忙的时候,延迟问题会更加严重,Slave机器数量的增加也会使这个问题更加严重。
那要是master挂了?怎么办?难道用户的写请求不接受了吗?默认情况下,不会在slave节点中自动重选一个master。那每次都要人工干预?无人值守安装变成刚需。
Redis哨兵
Redis Sentinel为Redis提供了高可用解决方案。吹哨人巡查监控后台master主机是否故障,如果故障了根据投票数自动将某一个从库转换为新主库,继续对外服务。
哨兵有那些作用:
- 监控redis运行状态,包括master和slave。
- 当master down机,能自动将slave切换成新master。
下面我们看一下我们怎么玩这个哨兵。天上飞的理念重要有落地的实现。在这里先给出本次实验的架构图:
在这里我们的架构是这个:
- 3个哨兵自动监控和维护集群,不存放数据,只是吹哨人。
- 1主2从用于数据读取和存放。
如何使用哨兵下面我们打开Redis当中的sentinel.conf配置文件。前面讲过的就不在配置这里重复了。
下面我们看看配置文件当中新的
行尾最后的quorum代表什么意思呢?quorum:确认客观下线的最少的哨兵数量。
我们知道,网络是不可靠的,有时候一个sentinel会因为网络堵塞而误以为一个master redis已经死掉了,在sentinel集群环境下需要多个sentinel互相沟通来确认某个master是否真的死了,quorum这个参数是进行客观下线的一个依据,意思是至少有quorum个sentinel认为这个master有故障,才会对这个master进行下线以及故障转移。因为有的时候,某个sentinel节点可能因为自身网络原因,导致无法连接master,而此时master并没有出现故障,所以,这就需要多个sentinel都一致认为该master有问题,才可以进行下一步操作,这就保证了公平性和高可用。
下面我们在mysredis下面建好三个文件
文件里面的内容如下:
bind 0.0.0.0
daemonize yes
protected-mode no
port 26379
logfile "./myredis/sentinel26379.log"
pidfile /var/run/redis-sentinel26379.pid
dir ./myredis
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel auth-pass mymaster 1234
主要不同文件需要吧这个端口改掉。然后我们将这个主从复制启动,然后我们将哨兵启动。
上面这个哨兵就已经启动成功了。下面我们看看这个哨兵的配置文件看看有没有多了什么东西
我们发现这个这个配置文件多了一些东西。然后我们将这个6379这台服务器给宕机了。我们看这个哨兵是否能够进行这个故障转移。当我们将主机shutdown之后我们在从机上使用info replication命令我们发现什么鬼怎么从机也宕机了。
什么是这个broken pipe?pipe是管道的意思,管道里面是数据流,通常是从文件或网络套接字读取的数据。当该管道从另一端突然关闭时,会发生数据突然中断,即是broken,对于socket来说,可能是网络被拔出或另一端的进程崩溃。其实当该异常产生的时候,对于服务端来说,并没有多少影响。因为可能是某个客户端突然中止了进程导致了该错误。这个异常是客户端读取超时关闭了连接,这时候服务器端再向客户端已经断开的连接写数据时就发生了broken pipe异常!
我们等一下我们就可以正常的使用redis了我们再用info replication命令我们可以发现这个6381这台从机变成了这个主机
出现上面的原因,主要是master宕机了整体的主体架构发生了变化,连接是会被改写的和重置。组织关系被打乱需要需要时间。
下面我们思考一下假如这个6379这台机器回来之后这个会不会变成主机了?答案是肯定不会我们可以通过哨兵的日志判断
通过日志我们发现这个6379这台机器已经拜6381这台机器做老大了,现在的主机是6381而不是这个6379.下面我们将6379这台机器重启看到底是不是这样的
下面我们看看这个redis6379.conf这个配置文件:
我们发现这个哨兵改动了这个6379.conf这个配置文件。Master-Slave切换后,master_redis.conf、slave_redis.conf和sentinel.conf的内容都会发生改变,即master_redis.conf中会多一行slaveof的配置,sentinel.conf的监控目标会随之调换。
3.哨兵如何进行故障转移
哨兵会每隔 1 秒给所有主从节点发送 PING 命令,当主从节点收到 PING 命令后,会发送一个响应命令给哨兵,这样就可以判断它们是否在正常运行。
如果主节点或者从节点没有在规定的时间内响应哨兵的 PING 命令,哨兵就会将它们标记为「主观下线」。这个「规定的时间」是配置项 down-after-milliseconds 参数设定的,单位是毫秒。
当然有这个也有客观下线,一个哨兵没有在规定时间内收到主机的回复。并不代表着主机真的就已经挂了,可能是因为这个网络延时或者是这个但是主机的压力太大没有在规定时间内回复哨兵。
所以,为了减少误判的情况,哨兵在部署的时候不会只部署一个节点,而是用多个节点部署成哨兵集群(最少需要三台机器来部署哨兵集群),通过多个哨兵节点一起判断,就可以就可以避免单个哨兵因为自身网络状况不好,而误判主节点下线的情况。同时,多个哨兵的网络同时不稳定的概率较小,由它们一起做决策,误判率也能降低。
我们当时在配置文件当中配置哨兵的时候我们配置了一个法定投票数,当一个哨兵在规定时间内没有收到主机的恢复,他就会向其他哨兵发送命令询问他们有没有收到主机恢复的消息。然后投票,如果票数达到了我们在配置文件当中的法定票数,那么这个时候主节点就会被该哨兵标记为客观下线了。
当哨兵判断主节点客观下线之后哨兵就会从剩下的主节点当中,选举出一个节点作为新的主节点。进行故障转移。
那么由那个哨兵来进行故障转移了?
由那个哨兵进行故障转移这个也是通过这个选举来进行的,会在哨兵集群里面选举一个出一个哨兵来进行故障转移。
可能有老铁就要问了那么谁来当候选者了?当然是那个判断主节点主观下线的那个哨兵作为这个后选者。每个哨兵只有一次投票机会,如果用完后就不能参与投票了,可以投给自己或投给别人,但是只有候选者才能把票投给自己。
在投票的过程当中任何一个候选者都必须满足一下两个条件
- 第一,拿到半数以上的赞成票;
- 第二,拿到的票数同时还需要大于等于哨兵配置文件中的 quorum 值。
主从故障过程到底是怎么样的?
主从故障转移主要是一下几个步骤:
- 第一步:在已下线主节点(旧主节点)属下的所有「从节点」里面,挑选出一个从节点,并将其转换为主节点。
- 第二步:让已下线主节点属下的所有「从节点」修改复制目标,修改为复制「新主节点」;
- 第三步:将新主节点的 IP 地址和信息,通过「发布者/订阅者机制」通知给客户端。
- 第四步:继续监视旧主节点,当这个旧主节点重新上线时,将它设置为新主节点的从节点;
那么问题就来了这个从剩下的从节点当中选举出一个节点作为主节点。这个有没有这个选举标准了?
我们首先要把网络状态不好的从节点给过滤掉。首先把已经下线的从节点过滤掉,然后把以往网络连接状态不好的从节点也给过滤掉。Redis 有个叫 down-after-milliseconds * 10 配置项,其down-after-milliseconds 是主从节点断连的最大连接超时时间。如果在 down-after-milliseconds 毫秒内,主从节点都没有通过网络联系上,我们就可以认为主从节点断连了。如果发生断连的次数超过了 10 次,就说明这个从节点的网络状况不好,不适合作为新主节点。
将网络不好的从节点排除之后我们从剩下的从节点当中先按照这个优先级来进行选举。Redis 有个叫 replica-priority配置项,可以给从节点设置优先级。
每一台从节点的服务器配置不一定是相同的,我们可以根据服务器性能配置来设置从节点的优先级。比如说某一台机器的配置更好内存更大我们可以将他的优先级设置为最高。
注意:数字越小代表这个优先级越高
如果优先级一样我们再看这个复制的偏移量,什么是复制的偏移量?主从架构中,主节点会将写操作同步给从节点,在这个过程中,主节点会用 master_repl_offset 记录当前的最新写操作在 repl_backlog_buffer 中的位置。
如果这个复制的偏移量也一样,那么就看这个id,选这个id最小的做为新的master.
发现有两个从节点优先级和复制进度都是一样的,那么就会进行第三轮考察,比较两个从节点的 ID 号,ID 号小的从节点胜出。么是 ID 号?每个从节点都有一个编号,这个编号就是 ID 号,是用来唯一标识从节点的。如果用一张图来表示那么应该是:
当选举好某个从节点作为新的master之后,哨兵 leader 向被选中的从节点 server2 发送 SLAVEOF no one 命令,将该从节点升级为新主节点。
在发送完slaveof no one 命令之后哨兵 leader 会以每秒一次的频率向被升级的从节点发送 INFO 命令(没进行故障转移之前,INFO 命令的频率是每十秒一次),并观察命令回复中的角色信息,当被升级节点的角色信息从原来的 slave 变为 master 时,哨兵 leader 就知道被选中的从节点已经顺利升级为主节点了。
然后哨兵 leader 向所有从节点(server3和server4)发送 SLAVEOF ,让它们成为新主节点的从节点即更改复制的目标。
完成之后
最后需要继续监视刚才宕机的主节点,等到他恢复之后将其变成新主节点的从节点。
总结一下就是: