参考:
https://blog.csdn.net/qq_41071876/category_11284995.html
https://blog.csdn.net/weixin_45821811/article/details/119421774
https://blog.csdn.net/weixin_43001336/article/details/122816402
Redis有三种模式,分别是:主从模式、兵模式、Cluster模式。Rdis最开始使用主从模式做集群,若master宕机需要手动配置slave转为master;后来为了高可用提出来哨兵模式,该模式下有一个哨兵监视master和slave,若master宕机可自动将slave转为master,但它也有一个问题,就是不能动态扩充;所以在3.x提出cluster集群模式。
主从模式
主从模式是三种模式中最简单的,在主从复制中,数据库分为两类:主数据库(master)和从数据库(slave)。
为了避免单点故障,通常的做法是将数据库复制多个副本以部署在不同的服务器上,这样即使有一台服务器出现故障,其他服务器依然可以继续提供服务。为此, Redis 提供了复制(replication)功能,可以实现当一台数据库中的数据更新后,自动将更新的数据同步到其他数据库上。
在复制的概念中,数据库分为两类,一类是主数据库(master),另一类是从数据库(slave)。主数据库可以进行读写操作,当写操作导致数据变化时会自动将数据同步给从数据库。而从数据库一般是只读的,并接受主数据库同步过来的数据。一个主数据库可以拥有多个从数据库,而一个从数据库只能拥有一个主数据库。一个master可以拥有多个slave,但是一个slave只能对应一个master。
原理
从数据库连接主数据库,发送SYNC命令;
主数据库接收到SYNC命令后,开始执行BGSAVE命令生成RDB文件并使用缓冲区记录此后执行的所有写命令;
主数据库BGSAVE执行完后,向所有从数据库发送快照文件,并在发送期间继续记录被执行的写命令;
从数据库收到快照文件后丢弃所有旧数据,载入收到的快照;
主数据库快照发送完毕后开始向从数据库发送缓冲区中的写命令;
从数据库完成对快照的载入,开始接收命令请求,并执行来自主数据库缓冲区的写命令;(从数据库初始化完成)
主数据库每执行一个写命令就会向从数据库发送相同的写命令,从数据库接收并执行收到的写命令(从数据库初始化完成后的操作)
出现断开重连后,2.8之后的版本会将断线期间的命令传给从数据库,增量复制。
主从刚刚连接的时候,进行全量同步;全同步结束后,进行增量同步。当然,如果有需要,slave 在任何时候都可以发起全量同步。Redis 的策略是,无论如何,首先会尝试进行增量同步,如不成功,要求从机进行全量同步。
优点
支持主从复制,主机会自动将数据同步到从机,可以进行读写分离;
为了分载Master的读操作压力,Slave服务器可以为客户端提供只读操作的服务,写服务仍然必须由Master来完成;
Slave同样可以接受其它Slaves的连接和同步请求,这样可以有效的分载Master的同步压力;
Master Server是以非阻塞的方式为Slaves提供服务。所以在Master-Slave同步期间,客户端仍然可以提交查询或修改请求;
Slave Server同样是以非阻塞的方式完成数据同步。在同步期间,如果有客户端提交查询请求,Redis则返回同步之前的数据;
缺点
不具备自动容错和恢复功能,主机从机的宕机都会导致前端部分读写请求失败,需要等待机器重启或者手动切换才能恢复;
主从模式下,如果主节点由于故障下线了,那么从节点因为没有主节点而同步中断,因而需要人工进行故障转移工作
果多个Slave断线了,需要重启的时候,尽量不要在同一时间段进行重启。因为只要Slave启动,就会发送sync请求和主机全量同步,当多个 Slave 重启的时候,可能会导致 Master IO剧增从而宕机。
无法实现动态扩容
哨兵模式
Sentinel(哨兵)是Redis的高可用性解决方案:由一个或多个Sentinel实例组成的Sentinel系统可以监视任意多个主服务器,以及这些主服务器属下的所有从服务器,并在被监视的主服务器进入下线状态时,自动将下线主服务器属下的某个从服务器升级为新的主服务器。
哨兵进程的作用
监控(Monitoring): 哨兵(sentinel) 会不断地检查你的Master和Slave是否运作正常。
提醒(Notification):当被监控的某个Redis节点出现问题时, 哨兵(sentinel) 可以通过 API 向管理员或者其他应用程序发送通知。
自动故障迁移(Automatic failover):当一个Master不能正常工作时,哨兵(sentinel) 会开始一次自动故障迁移操作。
它会将失效Master的其中一个Slave升级为新的Master, 并让失效Master的其他Slave改为复制新的Master;
当客户端试图连接失效的Master时,集群也会向客户端返回新Master的地址,使得集群可以使用现在的Master替换失效Master。
Master和Slave服务器切换后,Master的redis.conf、Slave的redis.conf和sentinel.conf的配置文件的内容都会发生相应的改变,即,Master主服务器的redis.conf配置文件中会多一行slaveof的配置,sentinel.conf的监控目标会随之调换。
原理
每个Sentinel(哨兵)进程以每秒钟一次的频率向整个集群中的Master主服务器,Slave从服务器以及其他Sentinel(哨兵)进程发送一个 PING 命令。
如果一个实例(instance)距离最后一次有效回复 PING 命令的时间超过 down-after-milliseconds 选项所指定的值, 则这个实例会被 Sentinel(哨兵)进程标记为主观下线(SDOWN)
如果一个Master主服务器被标记为主观下线(SDOWN),则正在监视这个Master主服务器的所有 Sentinel(哨兵)进程要以每秒一次的频率确认Master主服务器的确进入了主观下线状态
当有足够数量的 Sentinel(哨兵)进程(大于等于配置文件指定的值)在指定的时间范围内确认Master主服务器进入了主观下线状态(SDOWN), 则Master主服务器会被标记为客观下线(ODOWN)
在一般情况下, 每个 Sentinel(哨兵)进程会以每 10 秒一次的频率向集群中的所有Master主服务器、Slave从服务器发送 INFO 命令。
当Master主服务器被 Sentinel(哨兵)进程标记为客观下线(ODOWN)时,Sentinel(哨兵)进程向下线的 Master主服务器的所有 Slave从服务器发送 INFO 命令的频率会从 10 秒一次改为每秒一次。
若没有足够数量的 Sentinel(哨兵)进程同意 Master主服务器下线, Master主服务器的客观下线状态就会被移除。若 Master主服务器重新向 Sentinel(哨兵)进程发送 PING 命令返回有效回复,Master主服务器的主观下线状态就会被移除。
优点
哨兵模式是基于主从模式的,所有主从的优点,哨兵模式都具有。
主从可以自动切换,系统更健壮,可用性更高。
缺点
难支持在线扩容,在集群容量达到上限时在线扩容会变得很复杂。
如果是从节点下线了,sentinel是不会对其进行故障转移的,连接从节点的客户端也无法获取到新的可用从节点
cluster模式
哨兵模式基本已经可以实现高可用,读写分离 ,但是在这种模式下每台 Redis 服务器都存储相同的数据,很浪费内存,所以在redis3.0上加入了 Cluster 集群模式,实现了 Redis 的分布式存储,也就是说每台 Redis 节点上存储不同的内容。
在这个图中,每一个蓝色的圈都代表着一个redis的服务器节点。它们任何两个节点之间都是相互连通的。客户端可以与任何一个节点相连接,然后就可以访问集群中的任何一个节点。对其进行存取和其他操作。
一般集群建议搭建三主三从架构,三主提供服务,三从提供备份功能。
每一个节点都存有这个集群所有主节点以及从节点的信息。 所有的redis节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度和带宽。
原理
在 Redis 的每一个节点上,都有这么两个东西,一个是插槽(slot),它的的取值范围是:0-16383。还有一个就是cluster,可以理解为是一个集群管理的插件。当我们的存取的 Key到达的时候,Redis 会根据 crc16的算法得出一个结果,然后把结果对 16384 求余数,这样每个 key 都会对应一个编号在 0-16383 之间的哈希槽,通过这个值,去找到对应的插槽所对应的节点,然后直接自动跳转到这个对应的节点上进行存取操作。只有master节点会被分配槽位,slave节点不会分配槽位。
集群选举原理
当 slave 发现自己的 master 变为 fail 状态时,便尝试进行 FailOver,以期成为新的 master。由于挂掉的 master 有多个 slave,所以这些 slave 要去竞争成为 master 节点,过程如下:
slave1,slave2都 发现自己连接的 master 状态变为 Fail;
它们将自己记录的集群 currentEpoch(选举周期) 加1,并使用 gossip 协议去广播 FailOver_auth_request 信息;
其他节点接收到slave1、salve2的消息(只有master响应),判断请求的合法性,并给 slave1 或 slave2 发送 FailOver_auth_ack(对每个 epoch 只发一次ack); 在一个选举周期中,一个master只会响应第一个给它发消息的slave;
slave1 收集返回的 FailOver_auth_ack,它收到超过半数的 master 的 ack 后变成新 master; (这也是集群为什么至少需要3个master的原因,如果只有两个master,其中一个挂了之后,只剩下一个主节点是不能选举成功的)
新的master节点去广播 Pong 消息通知其他集群节点,不需要再去选举了。
什么情况下集群不可用?
如果某个主节点和所有从节点全部挂掉,我们集群就进入faill状态。
如果有一半以上的主节点宕机,那么我们集群同样进入faill状态。
优点
可实现动态扩容
自动故障转移、Slot迁移中数据可用
遇到单机内存,并发和流量瓶颈等问题时,可采用Cluster方案达到负载均衡的目的
客户端与 Redis 节点直连,不需要中间代理层.客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可。
缺点
架构比较新,最佳实践较少
为了性能提升,客户端需要缓存路由表信息
多键操作是不被支持的,多键的Redis事务是不被支持的,lua脚本不被支持。跨节点。