一 简介:分库分表的理解
二 具体: 1 当由于单台DB业务增长导致的服务器压力时,就必须横向进行扩展
2 本文仅从中间层观点进行分析
三 现有方案
方案1 sharding家族
-
Sharding-JDBC是一款轻量级的Java框架,在JDBC层提供上述核心功能,使用方式与正常的JDBC方式如出一辙,面向Java开发的用户。
-
Sharding-Proxy是一款实现了MySQL二进制协议的服务器端版本,大家可以把它当成升级版的MySQL数据库使用。独立部署后,即可按照正常MySQL操作方式来使用上述所有的核心功能。
-
Sharding-Sidecar从Service Mesh的理念中应用而生,面向于云原生架构
设计 在程序端利用sharding家族进行设计控制,根据计算出的路由指定数据库节点.
特点 sharding优势
1 程序端进行控制,非常方便.利用代码计算分片字段,控制分片规则.不会产生性能损耗
2 程序能够封装面对不同种类数据库
sharding问题
1 不支持分布式事务,需要利用路由进行事务操作
2 不支持分布式事务,全局DDL需要到每个分片进行执行
3 不支持动态扩容
4 不具有通用性,因为是根据业务进行设计的
过程 通过对片键的换算绝对分片节点,再通过片键的换算定位分表,达到分片分表目的
方案 2 中间件家族
设计 采用开源界的开源中间件进行设计控制,路由规则和分片都配置在中间件,然后指定后端机器
特点 1 开源中间件分为两种
一种是支持分布式事务,比如cetus mycat
一种是不支持分布式事务,比如kingshard
2 开源中间件的优势
1 中间件具有通用性,定义好的分片方法和路由规则,可以应用到多种业务场景
2 中间件大多拥有读写分离特性,可以直接应用
3 开源中间件可能存在的问题
1 中间件本身hang住,导致业务不可用
2 中间件本身发生崩溃或者OOM占用很高,导致业务不可用
3 中间件本身的性能损耗问题,是否可以接受
4 中间件如果上线,程序还是得做一定程度的浅改造
5 中间件本身也不支持动态扩容
6 中间件是否还在开源界维护
7 中间件维护和备份数据等问题
四 存在的普遍问题
1 全局事务控制的问题,即便是支持全局事务控制的中间件,也极度依赖mysql自身的XA事务.但是mysql xa 到了5.7后续版本才逐渐完善
2 全局事务DDL的一致性和代价问题,这也是一个针对多分片非常头疼的问题,不论对于哪种场景下
3 一旦采用分片,后续的查询限制问题,需要改造业务
4 分片集群的扩容问题,这是一个非常麻烦的事情,可以摆放在分片方案的首位
5 分片集群的备份数据一致性问题
五 分片集群的普通扩容方案思路
准备条件
1 完全一倍的硬件替换环境
2 需要在分片时准备足够多的桶
方案1
1 利用备份工具备份各个分片的数据,并记录下此时的主库binlog相关信息
2 利用备份恢复到新建立的集群中,一式两份.
3 利用修改好的新算法程序并行进行每个节点多余数据的删除
4 利用主库binlog相关信息搭配canal进行每个节点的同步
5 停止业务,保证新旧集群的数据一致
6 流量进行切换
7 旧集群进行下线处理
方案2
1 准备好相应的新程序,硬件环境,一个超级账户
2 新程序接入线上从库,通过超级账户执行两件事
1 停止复制进程
2 记录此时的同步binlog信息
3 新程序开始进行操作
1 读取从库数据,以新的算法进行录入新集群
2 对录入的数据进行校验,校验成功后对从库进行删除操作
4 当执行完时,从库就没有数据了,数据都在新集群了
5 利用从库同步的binlog信息进行canal消费
6 当canal消费追上主库后停止业务
7 流量进行切换
8 就集群进行下线处理
9 注意:确保mysql主库必须保留足够时间的binlog文件
六 分片集群主键的规划
目的 保证集群本身各个节点的主键不唯一
分类
1 uuid 最原始(不建议用这个),保证唯一
2 业务组合数字串(time+产品ID+用户ID)类似标记唯一,而且还能进行利用
3 通过雪花算法生成(需要时钟校验,否则可能产生冲突)
我们强烈推荐第二种方案,具有业务意义的主键才是我们需要的,我们本身也采用第二种
七 分片集群的查询
1 实时跨分片的业务尽量改造或者避免,效率很低
2 非实时查询业务我强烈建议采用canal+es方式,es汇总集群所有数据进行后台查询
八 总结
几个关键点
1 在哪个阶段进行分片,是否具有通用性
2 是否需要支持分布式事务
3 集群的分片扩容和查询问题
4 集群的全局事务ID规划
九 补充点
找到适合业务具体的方案,稳定适合才是重要的,具体问题具体分析.本篇文章只是个人观点.