一、写在前面
从这篇文章你可以学习到分布式架构中常见的数据存储架构模式以及Mysql的常见架构模式
原创不易,如果对您有帮助麻烦点赞+关注 谢谢~
二、分布式存储架构模式
单体
主备
主从(读写分离)
分区(分库分表)
存储架构一般都是上面4个,单体和主备没有讨论的必要,实现比较简单,这里主要讨论主从和分区
三、主从(读写分离)
1. 理论
1.1. 架构设计
1.2. 数据复制(一致性)
同步复制
异步复制
异步复制会存在一致性的问题,可以选择同步复制或者指定主节点读取
1.3. 选举机制
选举算法有Raft,Zab,这里只讨论Raft
- 初始状态
集群刚启动,所有节点处于初始化阶段 - 选举过程
● 每个阶段升级成候选者
● 节点之间相互投票
● 获得半数以上的节点升级主节点(如果得票数一样,重新选举) - 健康检测
主节点定期向从节点发送心跳请求,如果因为网络问题或者主节点挂掉,从节点没有收到心跳请求,从节点升级候选者,进行新一轮的投票
2. Mysql实践
- 读写分离通过Mycat的sql解析器实现
- 同步操作是异步化的,通过io线程把binlog的增量数据同步到从库
- 选举机制并不是用raft算法,如果主节点挂掉了,随机选择一个节点作为主节点
四、分区(分库分表)
分库分表分为垂直和水平,垂直是按照业务为维度拆分多个数据库,但是仍然会存在单表数据量过大的问题,这里只讨论水平的架构设计
1. 理论
1.1. 架构设计
1.2. 数据复制(一致性)
如上1.1.2
1.3. 选举机制
如上1.1.3
1.4. 分区策略
- 范围分区
- hash分区
● hash取模:算法简单,但是后期扩容需要迁移旧数据
● 一致性hash:可以避免扩容带来的旧数据迁移问题
2. Mysql实践
- 分库分表带来的问题
● 事务问题:数据存储在不同的数据库没办法通过acid保证数据一致性,可以考虑用分布式事务组件seata
● left join问题:可以在表中冗余字段,也可以在业务系统封装
● 主键id:普通自增主键会有冲突,uuid占用空间多,一般采用雪花id(时间戳+机器id+序列号);由于时间戳是在高位,整体是递增趋势
● 排序/函数等问题:如果排序的字段是非分区字段,需要在业务系统中封装