哨兵模式
基本概念和详细流程见《Redis设计与实现》、《Redis5设计与源码分析》,只说下自己的理解。
下图是一个基本的主从复制的哨兵系统:
主要有三种角色:哨兵、主服务器,从服务器。
- 哨兵:一种特殊的redis服务端,使用哨兵专用命令。用来监控主从状态,执行故障转移等。
- 主服务器:执行客户端请求,同步自身数据到从服务器。
- 从服务器:从主服务器同步数据。 系统的重要逻辑点有:
- 哨兵读入用户指定的配置文件,对每个要被监视的主服务器建立一个示例结构,然后创建连向主服务器的命令连接和订阅连接,命令用来向主服务器发送命令请求,订阅用来接受指定频道的消息。
- 哨兵向服务器发送INFO命令来获得主服务器及所有从服务器的地址信息,然后创建对应的实例。
- 哨兵每10s向主服务器和从服务器方发送INFO命令,如果判定主服务器下线,或者正在执行故障转移,频率增大到1s一次。
- 哨兵会对和自己同时监视主服务器的哨兵每2s通信一次(通信通过服务器的__sentinel__:hello中转传播),表示自己存在,同时也会接受其他哨兵的消息。
- 哨兵之间只有命令连接,哨兵和服务器之间有命令和订阅连接。
- 哨兵1s一次向主服务器,从服务器,哨兵节点发PING命令,根据回复判断在线状态,如果收到无效回复或没有回复,就判断此节点为主观下线。
- 判断主观下线之后,向其他哨兵询问,如果超过半数确认则判定为客观下线。
- 哨兵通过raft一致性算法选举出头哨兵,头哨兵执行故障转移操作。
- 故障转移通过在下线的主服务器的从服务器列表中来选择,选择状态良好,和主服务器通信时间最新,复制偏移量更大,ID更小的节点。
- 将此从服务器置为主服务器,原主服务器若上线则置为从服务器。
集群
基本概念和详细流程见《Redis设计与实现》、《Redis5设计与源码分析》,只说下自己的理解。
只阐述下主要流程:
- 节点之间通过两两握手来讲其他节点添加到自己的集群中。其实就是在自己的数据结构上初始化节点结构体。
- 集群中的16384个槽分派给节点(为什么是16384个节点)。
- 节点接受到一个命令请求,会使用CRC16(key) % 16384 来确定槽,如果不是自己负责,会自动重定向到正确的节点(怎么重定向?其实就是有一个数据,记录了每个槽对应的节点指针)。
- 重新分片的原理:见《Redis设计与实现》p266.
- 集群中的节点通过gossip协议通信,常见的消息有MEET,PING,PONG,PUBLISH,FAIL等。
单机模式,主从模式,哨兵模式,集群模式优缺点:
- 单机模式
- 优点:
- 架构简单,部署方便
- 性价比高
- 性能高
- 缺点:
- 不保证数据可靠性
- 在缓存使用,进程重启之后容易丢失数据,不能解决缓存预热问题。(ps:缓存预热:新的缓存系统没有任何缓存数据,在缓存重建数据的过程中,系统性能和数据库负载都不太好,所以最好是在系统上线之前就把要缓存的热点数据加载到缓存中,这种缓存预加载手段就是预热。)
- 主从模式
- 优点:
- 高可靠行:能够在主库主张自动切换从库
- 读写分离:从节点扩展读数据库的压力,只有主节点才能写
- 缺点:
- 故障恢复复杂,主节点出现异常,需要手动将从节点配置为主节点
- 主节点写能力有限,大量写容易宕机
- 主机单机存储有限
- 原生复制弊端(早期版本):如:Redis 复制中断后,Slave 会发起 psync,此时如果同步不成功,则会进行全量同步,主库执行全量备份的同时可能会造成毫秒或秒级的卡顿;又由于 COW 机制,导致极端情况下的主库内存溢出,程序异常退出或宕机;主库节点生成备份文件导致服务器磁盘 IO 和 CPU(压缩)资源消耗;发送数 GB 大小的备份文件导致服务器出口带宽暴增,阻塞请求,建议升级到最新版本。
- 哨兵模式:
优点:
- Redis Sentinel 集群部署简单。
- 能够解决 Redis 主从模式下的高可用切换问题。
- 很方便实现 Redis 数据节点的线形扩展,轻松突破 Redis 自身单线程瓶颈,可极大满足 Redis 大容量或高性能的业务需求。
- 可以实现一套 Sentinel 监控一组 Redis 数据节点或多组数据节点。
缺点:
- 是一种中心化的集群实现方案:始终只有一个Redis主机来接收和处理写请求,写操作受单机瓶颈影响。
- 集群里所有节点保存的都是全量数据,浪费内存空间,没有真正实现分布式存储。数据量过大时,主从同步严重影响master的性能。
- Redis主机宕机后,哨兵模式正在投票选举的情况之外,因为投票选举结束之前,谁也不知道主机和从机是谁,此时Redis也会开启保护机制,禁止写操作,直到选举出了新的Redis主机。
- 集群模式
优点:
- 无中心架构。数据按照 slot 存储分布在多个节点,节点间数据共享,可动态调整数据分布。
- 可扩展性:可线性扩展到 1000 多个节点,节点可动态添加或删除。
- 高可用性:部分节点不可用时,集群仍可用。通过增加 Slave 做 standby 数据副本,能够实现故障自动 failover,节点之间通过 gossip 协议交换状态信息,用投票机制完成 Slave 到 Master 的角色提升。
缺点:
- Key 事务操作支持有限,只支持多 key 在同一节点上的事务操作,当多个 Key 分布于不同的节点上时无法使用事务功能。
- Key 作为数据分区的最小粒度,不能将一个很大的键值对象如 hash、list 等映射到不同的节点。
- 不支持多数据库空间,单机下的 redis 可以支持到 16 个数据库,集群模式下只能使用 1 个数据库空间,即 db 0。