业务发展的三个阶段
单库多表-->单库多表的复合-->多库多表。
经验数据书,单表数量过千万,开始考虑分库分表,mysql一般5000万到性能瓶颈。
分库分表的算法核心
分治(联想一下:归并排序)
分治思路 和 优缺点
按拆分方式:垂直拆分(拆分业务) & 水平拆分(拆分数据)
垂直
优点:
- 业务清晰
- 适合领域建模,业务容易横向扩展,便于应用管理
- 数据维护简单
- 适合冷热数据分离
缺点:
- 无法join
- 数据分布不均,可能存在单库瓶颈,比如某个应用数据特别多,其他应用数据少。
- 事务复杂度很高,多个子表子库存在事务性
水平
优点:
- 一般不需要重构业务路基,数据能做到均分
- 提高了系统的负载能力
缺点:
- 切分后数据是分散的,很难利用join操作,垮库join性能较差
- 拆分规则难以抽象
- 分片事务的一致性难以解决
- 数据扩容难度和维护量极大
综上,共同要解决的难点有:
1 分布式事务
2 垮节点join
3 跨节点合并排序,分页问题
4 多数据源管理问题,比如数据库连接数量
水平切面的实现方案
1 ID路由 or 数据hash后路由
缺点: 查询需要聚合数据
2 按照时间切片路由
特定逻辑下的查询有利
3 分布式事务处理:
- 两阶段提交协议(缺点:性能差且阻塞)
- 先准备数据,各方准备成功,锁定资源
- 再提交数据,各方提交并释放资源
- 最大努力保障模式
- 所有的资源提交放到最后一刻(网络问题拖慢)
- 事务补偿机制
- 遇到问题记录环境,做事务补偿
分库分表带来的问题:
1 集群扩容和迁移
- 一般是双倍扩容,然后新旧集群
- 双写时间差,导致数据不一致需要清洗
- 清晰如果不能全量对比,最好能抽样对比
- 最好数据库中数据本身有动静分离
2 关联查询,范围查询的跨库跨表问题 - 建立查询表,冗余存储
- 使用搜索引擎
- 使用大数据技术聚合数据再提供查询
3 跨库事务实现难度较大 - 尽量避免同一个业务分到两个库,就是垂直划分考虑的问题
常用解决方案
方案一:应用层修改
-
dbsplit
在应用层路由,找到对应的表和数据库,然后应用层组装,会造成业务入侵,但是定位问题比较简单。 -
ORM的时候分片分表
eg:在Mybatis中配置表索引 -
Sharding JDBC(当当开源)
定制JDBC协议,不用入侵业务,实现难度会比较大- 支持分表事务,
- 逻辑问题导致的跨库事务,支持
- 网络和硬件问题导致的跨库事务不支持
- 不支持UNION,HAVING,OR,批量INSERT,DISTINCT,多子查询嵌套不支持
方案二:增加代理层
在应用层和数据库之间增加一个代理层,应用层访问代理,代理完成上述分库分表逻辑。
开源方案是:Cobar和Mycat
Mycat 支持的分表方案:
- 枚举
- 固定分片hash
- 范围约定
- 求模
- 日期列分区法
- 通配取模(范围 + 取模)
- Ascii 求模通配
- 编程指定
- 截取数字hash解析
- 一致性hash
方案三:支持事物的分布式数据库
eg:OceanBase 和 TiDB
TiDB对外提供了类似JDBC的接口,可以让应用像使用传统Mysql一样去使用TiDB
金融和支付公司,通常使用对于事务支持比较好的关系型数据库。
网友评论