我们说Redis是高可用的缓存,那么高可用(HA,High Availablity),是分布式系统架构设计中必须考虑的因素之一,它通常指的是,通过设计,减少系统不能提供服务的时间。
Redis高可用从哪里体现:

  • 主从复制;
  • 哨兵模式;
  • 集群模式。

    1、主从复制

    1.1 主从复制是什么及作用

    主从复制是什么:
    Redis为了避免单点故障,也需要部署多台机器,那么就会涉及到不同机器的数据同步问题。Redis提供了复制(replication)功能,当一台redis数据库中的数据发生了变化,这个变化会被自动同步到其他redis机器上。
    Redis主从复制就是指将一台Redis服务的数据,根据配置和策略,自动同步到其他Redis服务器上。前者称为主节点(master),后者称为从节点(salve)。
    数据的复制是单向的,只能从主节点到从节点。一般主节点可以进行读写操作,而从节点只能进行读操作。通常主节点以写为主,从节点上进行读取数据。默认情况下下,每一个Redis服务器都是主节点,一个主节点可以有多个主节点,也可以没有,但是一个从节点只能有一个主节点。
    image.png
    image.png
    主从复制能干什么:
  • 实现读写分离;
  • 当服务器宕机,数据丢失,可以进行容灾快速恢复;
  • 一台服务器的内存会达到峰值,也不可能无线升级,可以通过主从复制来达到扩展内存的效果。

    1.2 如何配置和使用主从复制

    配置主从复制:
    主节点配置:
    主节点按正常使用单体Redis的配置即可。
    从节点配置:
    默认情况下,启动的Redis服务器,都是主节点。想要让及其变成从节点,需要在配置文件上配置主从复制相关参数。

  • 在要作为从节点的Redis服务器的配置文件redis.conf中,指定主节点的信息:

(如果需要的话,可以配置主节点到登录密码、主从复制的相关参数等),各个从节点的配置是一样的:

配置主节点的ip和端口

slaveof 192.168.1.10 6379

从redis2.6开始,从节点默认是只读的

slave-read-only yes

假设主节点有登录密码,是123456

masterauth 123456

  • 也可以不使用配置文件,而是使用redis-server命令,在启动从节点时,通过参数-slaveof指定主节点是谁:

    ./redis-server —slaveof 192.168.1.10 6379、

  • 还有第三种方式,那就是正常启动redis及其,然后通过redis-cli命令执行slaveof 主节点ip 主节点端口 来指定主节点是谁

    redis-cli slaveof 192.168.1.10 6379

启动顺序:
先启动主节点,然后一台一台启动从节点。
主节点挂掉怎么办:
系统运行时,如果master挂掉了,可以在一个从节点上手动执行命令,slaveof no one,将这个从节点变成新的主节点;然后在另外的从节点上分别执行 slaveof 新的主节点ip 新的主节点端口号,把另外的从节点的主节点指向这个新的主节点。同时,挂掉的原本的主节点,在重新启动后,作为新的从节点,也指向新的主节点。
执行slaveof no noe 命令,可以关闭从节点的复制功能,同时原本同步所得的数据集不会被丢弃。

1.3 主从复制的机制(原理)

  1. 从节点连接到主节点,发送一个同步命令。
  2. 主节点接收到同步命令后,可以执行bgsave命令生成RDB文件,并使用缓冲区记录伺候执行的所有写指令。
  3. 主节点的bgsave命令执行完毕后,向所有从节点发送快照文件,并在发送期间继续记录被执行的写指令。
  4. 从节点收到快照文件后丢弃所有旧数据,载入收到的快照。
  5. 主节点快照发送完毕后,开始向从节点发送缓冲区中的写命令。
  6. 从节点完成对快照的载入,开始接收命令请求,并执行来自主节点缓冲区的写命令。(这一步从数据库初始化完成)
  7. 主节点每执行一个写命令就会向从节点发送相同的写命令,从节点接收并执行收到的写命令。(这一步是从节点初始化完成后的操作)
  8. 出现断开重连后,2.8之后低版本会将断线期间的命令传给从节点,增量复制。
  9. 主从刚刚连接到时候,进行全量同步;全量同步结束后,进行增量同步。当然,如果有需要,slave在任何时候都可以发起全量同步。Redis的策略是,无论如何,首先会尝试进行增量同步,如果不成功,要求从节点进行全量同步。

简略版:

  1. 从节点启动成功,连接到主节点后会发送一个同步命令。
  2. 主节点接收到同步命令后,启动后台的存盘进程,同时收集所有接收到的用于修改数据集的命令,在后台进程执行完毕之后,主节点将传送整个存盘下来的数据文件到从节点,完成一次全量同步。
  3. 全量同步:从节点在接收到数据文件后,将其存盘并加载到内存中。
  4. 增量同步:主节点继续将新的所有收集到的修改命令一次传给从机,完成同步。
  5. 只要是重新连接主节点,就会执行一次全量同步。

    1.4 主从复制的优缺点

    优点:

    • 支持主从复制的话,主节点会自动将数据同步到从节点,可以进行读写分离。
    • 为了分担主节点读操作的压力,从节点可以为客户端提供只读操作的服务,写服务依然必须由主节点完成。
    • 从节点同样可以接受其他从节点的连接和同步请求,这样有效的分担主节点到同步压力。
    • 主节点是以非阻塞的方式为从节点提供服务的,所以主从同步期间,客户端仍然可以提交查询或者修改请求。
    • 从节点也是以非阻塞的方式完成数据同步。在同步期间,如果有客户端提交查询请求,redis返回同步之前的数据。

缺点:

  • Redis不具备自动容错和恢复功能,主节点和从节点的宕机都会导致部分读写请求失败,需要等待及其重启或者手动切换连接到ip才能恢复。
  • 主机宕机时,宕机前有部分数据未能及时同步到从机,切换ip后还会引起数据不一致的问题,降低系统的可用性。
  • 如果多个从节点断线了,需要重启的时候,尽量不要再统一时间段重启。因为只要从节点启动,就会发送同步请求和主机全量同步,当多个从节点重启的时候,可能会导致主节点IO剧增,从而宕机。
  • Redis较难支持在线扩容,当集群容量达到上限时,在线扩容会变得很复杂。
  • Redis的主节点和从节点中数据时一样的,降低了内存的可用性。

2、哨兵模式

2.1 哨兵模式是什么及作用

什么是哨兵模式:
首先要明确,哨兵模式是基于主从复制的。
在主从复制的情况下,当主节点宕机后,需要手动把一台从节点切换为主节点,这需要人工干预,还会造成一端时间内服务不可用。所以这种方式不推荐,在实际生产中,我们优先考虑哨兵模式。
在哨兵模式下,主节点宕机,哨兵会在从节点中自动选举主节点,并将其他的从节点指向新的主节点。
基于主从复制,redis提供了哨兵命令redis-sentinel。
哨兵是一个独立的进程,作为进程,它会独立运行。哨兵可以有多个,一般为了便于决策选举,使用奇数个哨兵。哨兵可以和redis及其部署在一起,也可以部署在其他机器上。多个哨兵构成一个哨兵集群,哨兵之间也会相互通信,检查哨兵是否正常运行;同时发现主节点宕机,哨兵之间会进行决策选举新的主节点。
image.png
image.png
这里我们将哨兵进程和redis分别部署在不同的机器上,避免因为redis宕机导致sentinel进程不可用。
哨兵也是一台redis服务器,只是不做数据服务,而是只作为哨兵服务。

哨兵模式的作用:

  • 监控主节点和从节点的状态。通过发送命令,让Redis服务器返回响应,以此来监控其运行状态。
  • 重新选举出主节点。当哨兵检测到主节点宕机,会自动将从节点切换为主节点。
  • 切换了主节点后,进行通知。切换了主节点后,通过 发布订阅模式 通知其他的从服务器,让其他从服务器切换新的主机。
  • 一个哨兵对redis进行监控,也可能会出现问题,为此可以使用多个哨兵进行监控。哨兵之间还会进行监控,这样就形成了多哨兵模式。

2.2 如何配置哨兵模式

首先,是基于主从模式的,redis.conf的配置和主从模式的配置一样,不许改变。

  1. 新建哨兵的配置文件sentinel.conf。 这个名字不能错,三台机器的哨兵配置是一样的。
  2. 配置文件中写入内容:

    禁止保护模式

    protected-mode no

    配置监听的主服务器,这里sentinel monitor代表监控,mymaster代表服务器的名称,可以自定义,

    192.168.1.10代表监控的主服务器,6379代表端口,2代表只有两个或两个以上的哨兵认为主服务器不可用的时候,才会进行failover操作。

    sentinel monitor mymaster 192.168.1.10 6379 2

    sentinel author-pass定义服务的密码,mymaster是服务名称,123456是Redis服务器密码

    sentinel auth-pass mymaster 123456

  3. 启动哨兵 使用redis-sentinel sentinel.conf命令

2.3 哨兵模式的工作机制(原理)

  1. 每个sentinel(哨兵)进程以每秒钟一次的频率,想整个集群中的master(主节点)、slave(从节点)以及其他sentinel(哨兵)进程发送一个PING命令,以此来检测他们是否仍在正常运行。
  2. 如果一个instance(实例)没有在规定时间内响应PING命令(这个规定时间设down-after-milliosencodes选项指定的值),这个实例会被哨兵进程标记为主观下线状态(SDOWN)。
  3. 如果一个master(主节点)被标记为主观下线(SDOWN),那么正在监视这个主节点到所有哨兵进程要以每秒一次的频率确认主节点的确进入了主观下线状态。
  4. 当有足够数量的哨兵进程(足够数量是指:大于等于配置文件指定的值)在指定时间范围内确认主节点进入了主观下线状态,则主节点会被标记为客观下线(ODOWN)。
  5. 一般情况下,每个哨兵进程会以每10秒一次的频率向急群众所有主节点、从节点发送INFO命令。
  6. 当主节点被哨兵进程标记为客观下线(ODOWN)时,哨兵进程向下线的主节点到所有从节点发送INFO命令的频率会从10秒一次改为每秒一次。
  7. 如果没有足够数量的哨兵统同意主节点下线,那么主节点的客观下线状态就会被移除。如果主节点重新向哨兵进程发送PING命令返回有效回复,主节点的主观下线状态就会被移除。

或者单哨兵时这么理解:
哨兵在运行到时候,周期性的给所有主从库发送PING命令,检测他们是否仍然在线运行。如果仓库没有在规定时间相应哨兵的PING命令,哨兵就会把仓库标记为下线状态,同理,如果主库没有在规定的时间响应哨兵的PING命令,哨兵就会判定主库下线,然后开始自动切换主库的流程。

切换主库的流程:
哨兵会从从节点中,按照一定规则选择一个从节点实例,把它作为一个新的主节点。这一步完成后,现在就有了新的主节点。然后哨兵会把新的主节点连接信息发送给其他从节点,让他们执行replicaof命令,和新的主库连接,并进行数据的复制。同时,哨兵会把新的主节点连接信息通知给客户端,让他们把请求发送到新的主库上。

2.4 哨兵模式的优缺点

优点:

  • 哨兵模式是基于主从模式的,所有主从模式的有点,哨兵模式都具有。
  • 使用哨兵模式,可以实现主从节点自动切换,系统更加健壮,可用性更高。

缺点:

  • 具有主从模式的缺点,每台机器上数据是一样的,内存可用性低。
  • Redis较难支持在线扩容,当集群容量达到上限时,在线扩容会变得很复杂。

3、Redis集群(cluster)

3.1 Redis集群是什么

我们通过Redis哨兵模式,基本上已经可以实现高可用、读写分离。但是这种模式下,每台Redis服务器存储的都是相同的数据,很浪费内存。Redis3.0版本之后加入了Cluster集群模式,实现了Redis的分布式存储,对数据进行分片。集群模式下,每台Redis节点上存储不同的内容:
image.pngimage.png
这里面的六台redis两两之间不是独立的。每个节点都会通过集群总线(clustaer bus),与其他节点进行通信。通信时使用特殊的端口号,及堆外服务的端口号加1000。例如某个节点端口号是6379,那么它与其他节点通信的端口号是16379。节点之间的通信采用特殊的二进制协议。
对于客户端来说 ,整个cluster(集群)被看作一个整体,客户端可以连接任意一个节点进行操作,就像操作单一Redis实例一样。当客户端操作的key没有分配到需要的节点上时,Redis会返回转向指令,指向正确的节点,有点像浏览器页面的redirect跳转。
根据官方推荐,集群部署至少要三台以上的主节点,最好使用三主三从,共六个节点的模式。

3.2 如何开启集群模式

修改redis.conf配置文件:

开启redis的集群模式

cluster-enabled yes

配置集群模式下的配置文件名称和位置,redis-cluster.conf这个文件是集群启动后自动生成的,不需要手动配置。

cluster-config-file redis-cluster.conf

这6个Redis服务分别启动成功之后,这时虽然配置了集群开启,但是六台机器还是独立的,要使用集群管理命令,将六台机器添加到一个集群中。

借助redis-tri.rb工具可以快速部署集群。
执行:

redis-trib.rb create —replicas 1 192.168.1.11:6379 192.168.1.21:6379 192.168.1.12:6379 192.168.1.22:6379 192.168.1.13:6379 192.168.1.23:6379

就可以成功创建集群。
创建完成后会有响应日志,还会自动生成配置的redis-cluster.conf文件。

登录集群:

redis-cli -c -h 192.168.1.11 -p 6379 -a 123456 # -c,使用集群方式登录

查看集群信息:

CLUSTER INFO #集群状态。

列出节点信息:

CLUSTER NODES #列出节点信息。

3.3 集群运行机制

Redis的每一个节点上,都有两个东西,分别是slot(插槽)和cluster。
插槽slot的取值范围是0-16383,cluster可以理解为是一个集群管理的插件,类似的哨兵。
当我们存取的key到达的时候,redis会根据crc16的算法对计算后得出一个结果,然后把结果和16384求余数,这样每个key都会对应一个编号在0-16383之间的哈希槽。通过这个值,去找对应的插槽所对应的节点,然后自动跳转到这个对应的节点进行存取操作。
当数据写入到对应的主节点后,这个数据会同步给这个主节点对应的所有从节点。
为了保证高可用,redis集群引入了主从模式,一个主节点对应一个或者多个从节点。当其他主节点ping主节点1时,如果半数以上的主节点与主节点1同心超市,那么会人为主节点1宕机了,会启用主节点1的从节点作为新的主节点,继续提供服务。
如果主节点1和他的从节点1都宕机了,整个集群就会进入失败状态,因为集群的slot映射不完整。
如果集群有超过半数以上的主节点挂掉,无论是否有从节点,集群都会进入失败状态。
redis集群采用去中心化思想,没有中心节点的说法,客户端与redis节点直连,不需要中间代理层,客户端不需要连接集群所有节点,连集群中任何一个可用节点即可。

3.4 集群扩容和缩容

image.png

3.5 集群模式的优缺点

优点:

  • 采用去中心化思想,数据按照slot存储分布在多个节点,节点间数据共享,可动态调整数据分布。
  • 具有可扩展性,可线性扩展到一千多个节点,节点可动态添加或者删除。
  • 高可用性,部分节点不可用时,集群仍然可用。通过增加从机作为数据副本,能够实现故障自动failoverm,节点之间通过gossip协议交换状态信息,用投票机制完成从节点到主节点的角色提升。
  • 降低运维成本,提高系统的扩展性和可用性。

缺点:

  • redis集群是无中心节点的集群架构,依靠gossip协议修复集群的状态,但是gossip有消息延时和消息冗余的问题。集群节点数量过多的时候,节点之间需要不断进行PING/PANG通讯,占用大量网络资源。
  • 数据迁移存在问题,redis集群可以动态扩容缩容,但是处于半自动状态,需要人工介入,扩缩容时需要进行数据迁移。而Redis为了保证迁移的一致性,迁移的所有操作都是同步操作,执行迁移时,两端的redis均会进去时长不等的阻塞状态。对于小key,该时间可以忽略不计,但是如果key的内存使用过大,严重的时候会触发集群内的故障转移。