Mysql分库分表实战(一)——一文搞懂Mysql数据库分库分表

数据拆分的方式

  • 垂直拆分
    • 根据业务的维度,将原本一个库中的表拆分多个表,每个库中表与原有的结构不同
  • 水平拆分
    • 根据分片算法,将一个库拆分成多个库,每个库依旧保留原有的结构

分库分表方案

客户端分片

客户端分片方式

在应用层直接实现

这是一种非常通用的解决方案,直接在应用层读取分片规则,解析分片规则,根据分片规则实现切分的路由逻辑,从应用层直接决定每次操作应该使用哪个数据库实例中的对应的数据库

优点:

  • 实现简单
  • 切片逻辑使自己开发的,遇到问题可以快速定位

缺点:

  • 代码具有一定侵入性
  • 代码耦合度比较高
  • 数据库保持的连接会比较多
通过定制JDBC协议实现

解决方案一中的代码耦合,通过定制JDBC协议来实现(主要是针对业务逻辑层提供与JDBC一致的接口),让分库分表在JDBC的内部实现

目前当当网开源的框架:Sharding JDBC 就是使用这种解决方案来实现的

通过定制ORM框架实现

通过定制ORM框架来实现分库分表方案,常见的有基于Mybatis的分库分表方案的解决

<select id="selectUser" parameterType="java.util.Map" resultType="User">
select user_id as userId,user_name as userName
from user_#{index}
where user_id = #{userId}
</select>

代理端分片

代理分片就是在应用层和数据库层之间添加一个代理层,把分片的路由规则配置在代理层,代理层对外提供与JDBC兼容的接口给应用层,在业务实现之后,在代理层配置路由规则即可;

优点:

  • 开发人员专注业务逻辑实现,分库分表配置留给代理层处理

缺点:

  • 增加代理层,数据库操作多了一层网络传输,一定的性能影响
  • 维护代理层,增加硬件成本
  • 线上环境出现问题,不能及时定位,需要一定技术专家处理

支持事务的分布式数据库

支持分布式事务的框架,目前有OceanBase、TiDB框架,这些框架将可伸缩特定和分布式事务的实现包装到了分布式数据库内部实现,对使用者透明,使用者不需要直接控制这些特性,但是对事务的支持不如关系型数据,适合大数据日志系统、统计系统、查询系统、社交网站等

分库分表架构设计

拆分方式优点缺点
垂直拆分1. 拆分后业务清晰,拆分规则明确
2. 系统之间进行整合或扩展容易
3. 按照成本、应用等级、应用的类型等将表放到不同的机器上,便于管理
4. 便于实现动静分离、冷热分离的数据库表的设计模式
5. 数据维护简单
1. 部分业务表无法进行关联、只能通过接口的方式来解决,提高了系统的复杂度
2. 受每种业务不同的限制,存在单库性能瓶颈,对数据扩展和性能提升不友好
3. 事务处理复杂
水平拆分1. 单库单表的数据保持一定的量级,有助于性能的提高
2. 切分的表的结构相同,应用层改造较少,只需要增加路由规则即可
3. 提高了系统的稳定性和负载能力
1. 切分后数据是分散的,很难利用数据库的关联查询,跨库查询性能较差
2. 拆分规则难以抽象
3. 分片数据的一致性难以解决
4. 数据扩容的难度和维护量极大

垂直拆分和水平拆分具有共同点

  • 存在分布式事务问题
  • 存在跨节点join的问题
  • 存在跨节点合并排序、分页的问题
  • 存在多数据源管理的问题

垂直拆分更偏向于业务拆分的过程,在技术上我们更倾向于水平切分的方案;

TODO