存储高可用,一般采用复制架构,复制架构,需要关注故障架构和状态决策2个要点
复制架构通用关注点
数据复制
复制格式
格式 | 优点 | 缺点 | 举例 |
---|---|---|---|
命令 | 数据量小 | 可能存在数据不一致 | Mysql 的statement同步方式,按commit顺序同步,可能存在数据不一致 |
Redis 的 AOF,每个操作室幂等的。 | |||
MongoDB的oplog ,oplog中每个操作室幂等的 | |||
数据 | 保证数据一致性 | 数据量大 | Mysql的row模式 |
文件 | 保证生成文件时数据一致性 | 数据量大 | Redis的RDB |
复制的时候,数据可能有变化 |
复制方式
同步方式 | 特点 | 适用场景 |
---|---|---|
同步 | 最强一致性 | 主备,主从架构 |
故障容忍度低 | ||
写入性能低 | ||
异步 | 会出现,数据不一致 | 数据存储集群 |
故障容忍度高 | ||
写入性能高 | ||
半同步 | 同步,异步的折中方案 | 数据存储集群 |
多数同步 | 数据一致性强 | 例如要求,分布式一致性 |
故障容忍度高 | 例如:OceanBase | |
写入性能低,实现复制 | ||
最强高可用 |
状态决策
决策方式 | 特点 | 适用场景 |
---|---|---|
依靠决策者(利用zookeepr等) | 决策简单 | 大多数业务 |
数据一致性中等 | ||
决策者本身高可用复杂 | ||
协商式 | 一般采用双通道,心跳机制 | 内部系统,网络设备 |
数据一致性弱 | ||
标准算法式 | 决策过程复杂,一般采用标准算法 Raft,ZAB,Paxos等 | 余额,库存,或金融场景 |
数据一致性最强 | ||
可用性最高,一般使用quorum 防止脑裂 |
Redis Sentinel 分析
下图,是Redis,Sentinel 的架构图图:
Sentinel 是决策者, master 是主库,follow 是从库,下面按照数据复制,状态决策2个角度进行分析
数据复制
复制格式
AOF 命令
redis是先写内存,后写AOF日志,不阻塞写操作
同步到磁盘的策略
- Always同步写盘, 性能差, 可靠性高,数据基本不丢失。
- Everysec每秒写盘,性能适中,宕机损失1秒数据
- no操作系统控制写盘,性能高,宕机损失数据多
AOF 重写 针对AOF文件大,redis优化方式
- 后台fork子进程 bgrewriteaof 来完成,不会阻塞主线程
- 使用AOF缓冲,AOF 重写缓冲,保证在重写过程中,新写入的数据不会丢失
- 内存页表越大,fork阻塞时间越久
复制方式
- 异步
- wait命令 实现半同步,
注:
Redis的WAIT命令,可确保指定数量的Redis副本已确认
在故障切换期间,已确认的写入可能会丢失,取决于Redis持久性的配置
状态决策,决策者:sentinel
Sentinel 作用
监控
- 周期性的给所有主从库发送PING命令,检查它们是否仍然在线运行
- 主观下线,一个哨兵判断主库下线
- 客观下线,大于等于quorum(降低集群网络压力大,主库压力大造成的误判的概率),都判断主库已经主观下线了,主库才被标记客观下线,开启主从切换
选主(筛选+3轮打分)
筛选
down-after-milliseconds * 10 以内的作为候选主库
down-after-milliseconds 主从库断连的最大连接超时时间。超过10倍,认为该候选库网络不好,剔除
打分
- 从库优先级,slave-priority配置
- 从库复制进度,
slave_repl_offset
越接近master_repl_offset
得分越高
master_repl_offset
,master写入的点位
slave_repl_offset
从库复制的点位
- 从库的ID号,号小的得分高
通知
让从库执行replicaof,与新主库同步
通知client 连接新的主库
Sentinel Leader 选举流程
Raft 协议的实现,大致流程如下:
- 哨兵给其他哨兵发送命令,表明希望由自己成为leader,并让所有其他哨兵进行投票
- 每个哨兵选自己,并且根据先到先得的规则,接受/拒绝其他哨兵成为leader的请求
- 作为Leader的2个条件 拿到半数以上的赞成票 ,拿到的票数还要大于等于quorum
注意:每个哨兵的quorum 和 down-after-milliseconds 必须一样