您的位置:首页 > 数据库 > Redis

redis知识盘点【肆】_主从复制和sentinel哨兵

2017-11-09 15:12 549 查看
上篇文章:redis知识盘点【叁】_持久化

在进入正题之前,我们先明确两个概念:集群和分布式。在移动互联网项目中这两个词语经常一起出现,不少人也认为其表达的一个意思,但是并不是的。按我的理解,集群就是一组服务器,每台服务器的内容或数据都是一致的;分布式也是一组服务器,但是每台服务器的内容或数据是按照业务或其他规则切分过的,所有服务器加起来的整体才拥有完整的内容或数据。

我想了个例子不知恰当与否,以《西游记》的场景为例,集群就像是孙悟空拔下猴毛吹出的千百只和他一模一样的猴子,其实孙悟空相当于主机(master),那些猴子相当于从机(slaves),他们的所有一切是一模一样的;而分布式相当于取经四人小团队,有负责挑担的有负责牵马的,有负责被妖怪抓(同样有意义,不然凑不够八十一难)也有负责打怪的,每个人各司其职,加起来的整体完成了取经的这个功能。

说回redis,在此系列的第一篇文章中也有提到,redis分别于2.8和3.0版本推出了sentinel(哨兵)和cluster(集群)功能。sentinel是解决HA问题的,即双机集群;而cluster是解决数据sharding问题的,即分布式缓存。这两个功能不重复,并且经常一起使用。sentinel哨兵功能是应用在redis主从复制基础之上的,这里先介绍下redis的主从复制功能。

在redis中我们可以通过在.conf中配置salveof参数,让一台redis服务器去复制(replicate)另一个redis服务器,此时前一台服务器为主服务器,后一台为从服务器。主服务器和从服务器的数据是完全一样的,一台主服务器可以有多台从服务器。redis对数据复制功能的实现在2.8版本之前和之后也是不一样的。

在redis 2.8版本之前,主从同步主要是通过从服务器向主服务器发送sync命令实现的:主服务器接收到sync命令后自动执行bgsave命令,生成一个RDB文件,并使用一个缓冲区保存从当前开始的所有写命令,生成完毕后将这个RDB文件发送给从服务器,从服务器接收并载入,将自己的数据库状态更新为主服务器执行bgsave命令时的数据库状态,之后再接收执行主服务器发送过来的缓冲区中保存的写命令,实现了和主服务器当前状态的一致。

2.8版本之前复制功能的缺陷:如果在复制过程中断线了,那么下次复制的时候会完全从头复制。因为生成RDB文件耗费主服务器的CPU、内存和磁盘资源;发送RDB文件也会占用大量的网络带宽,因此这样的做法是非常低效的。好在2.8版本之后redis做了优化,使用psync命令替代了sync命令,区别在于,psync支持完整重同步和部分重同步两种
模式。主要说部分重同步,redis服务器维护了复制积压缓冲区、复制偏移量和服务器运行id三个元素。当该服务器为主机时,复制积压缓冲区会保存最近的写命令,每条命令对应一个复制偏移量,当进行复制时,主服务器会将最新执行的命令的复制偏移量同步给从服务器,如果复制中断后再复制,从服务器可先根据服务器运行id找到当时复制的主服务器,再根据复制偏移量找到上次中断的命令,进行继续复制。

站在主从复制的基础上,下面说说sentinel哨兵的实现。

redis sentinel包含若干个sentinel节点和redis数据节点,每个sentinel节点会对数据节点和其余sentinel节点进行监控,当它发现节点不可达时,会对节点做下线标识。如果被标识的是主节点,它还会和其他sentinel节点进行"协商",当大多数sentinel节点都认为主节点不可达时,它们会选举出一个从节点来完成自动故障转移的工作,同时会将这个变化实时通知给redis应用方。后面如果已下线主节点恢复正常,会将其作为新主节点的从节点重新上线。整个过程完全是自动的,不需要人工来介入,所以这套方案很有效地解决了redis的高可用问题。

sentinel本质上只是一个运行在特殊模型下的redis服务器,初始化sentinel时不会载入RDB或AOF文件。sentinel会创建到主服务器的命令连接和订阅连接,默认以每十秒一次的频率通过命令连接向被监视的主服务器发送INFO命令,通过分析INFO命令的回复来获取主服务器的的所有从服务器信息。当sentinel发现主服务器有新的从服务器出现时,sentinel除了会为这个新的从服务器创建相应的实例结构外,还会创建连接到从服务器的命令连接和订阅连接。同主服务器一样,sentinel也会默认以每十秒一次的频率通过命令连接向从服务器发送INFO命令。

对于监视同一个主服务器和从服务器的多个sentinel来说,他们之间只建立命令连接,以2秒1次的频率通过向被监视服务器的_sentinel_:hello频道互相通信。

sentinel还会以每秒一次的频率向其他服务器实例(主服务器、从服务器和sentinel实例)发送ping命令,并根据回复判断实例是否在线,当超过一定时间没有回复则会同sentinel投票判断其认为下线,当超过指定票数则投票通过。生产环境中,建议redis sentinel的所有节点部署在不同物理机上,sentinel应该部署奇数个。

sentinel在.conf中的重要配置项:

sentinel monitor mymaster 127.0.0.1 6379 quorum:quorum为投票时通过的票数

sentinel auth-pass mymaster password:主机的认证密码

sentinel down-after-milliseconds mymaster 5000:ping,5000ms后认为宕机

sentinel parallel-syncs mymaster num:当mymaster挂了后,num台从机向新的主机复制操作

sentinel failover-timeout mymaster times:通常被解释成故障转移超时时间,但实际上它作用于故障转移的各个阶段:

    a)选出合适从节点。

    b)晋升选出的从节点为主节点。

    c)命令其余从节点复制新的主节点。

    d)等待原主节点恢复后命令它去复制新的主节点。

failover-timeout的作用具体体现在四个方面:

1)如果Redis sentinel对一个主节点故障转移失败,那么下次再对该主节点做故障转移的起始时间是failover-timeout的2倍。

2)在b)阶段时,如果sentinel节点向a)阶段选出来的从节点执行slaveof no one —直失败(例如该从节点此时出现故障),当此过程超过failover-timeout时,则故障转移失败。

3)在b)阶段如果执行成功,sentinel节点还会执行info命令来确认a)阶段选出来的节点确实晋升为主节点,如果此过程执行时间超过failover-timeout时,则故障转移失败。

4)如果c)阶段执行时间超过了failover-timeout(不包含复制时间),则故障转移失败注意及时超过了这个时间,sentinel节点也会最终配置从节点去同步最新的主节点。

sentinel功能的介绍先到这,下一篇文章介绍一下redis的cluster功能。

redis知识盘点【伍】_一致性哈希和cluster集群
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: