概述
在业务量不大时, 单库单表即可支撑. 当数据量过大存储不下, 或者并发量过大负荷不起时, 就要考虑分库分表.
相关术语
读写分离: 不同的数据库, 同步相同的数据, 分别只负责数据的读和写;
分区: 指定分区列表达式, 把记录拆分到不同的区域中(必须是同一服务器, 可以是不同硬盘), 应用看来还是同一张表, 没有变化;
分库: 一个系统的多张数据表, 存储到多个数据库实例中;
分表: 对于一张多行 (记录) 多列 (字段) 的二维数据表
分表又分两种情形:
垂直分表: 竖向切分, 不同分表存储不同的字段, 可以把不常用或者大容量, 或者不同业务的字段拆分出去;
水平分表(最复杂): 横向切分, 按照特定分片算法, 不同分表存储不同的记录.
是否一定要采用分库分表?
需要注意的是, 分库分表会为数据库维护和业务逻辑带来一系列复杂性和性能损耗, 除非预估的业务量大到万不得已, 切莫过度设计, 过早优化.
规划期内的数据量和性能问题, 尝试能否用下列方式解决:
当前数据量: 如果没有达到几百万, 通常无需分库分表;
数据量问题: 增加磁盘, 增加分库(不同的业务功能表, 整表拆分至不同的数据库);
性能问题: 升级 CPU / 内存, 读写分离, 优化数据库系统配置, 优化数据表 / 索引, 优化 SQL, 分区, 数据表的垂直切分;
如果仍未能奏效, 才考虑最复杂的方案: 数据表的水平切分.
分库分表方案
代理层方式
部署一台代理服务器伪装成 MySQL 服务器, 代理服务器负责与真实 MySQL 节点的对接, 应用程序只和代理服务器对接, 对应用程序是透明的. 比如 MyCAT.
MyCAT 后端可以支持 MySQL, SQL Server, Oracle, DB2, PostgreSQL 等主流数据库, 也支持 MongoDB 这种新型 NoSQL 方式的存储, 未来还会支持更多类型的存储.
MyCAT 不仅仅可以用作读写分离, 以及分表分库, 容灾管理, 而且可以用于多租户应用开发, 云平台基础设施, 让你的架构具备很强的适应性和灵活性.
应用层方式
处于业务层和 JDBC 层中间, 是以 JAR 包方式提供给应用调用, 对代码有侵入性. 主要方案有:
淘宝网的 TDDL: 已于 2012 年关闭了维护通道, 建议不要使用.
当当网的 Sharding-JDBC: 仍在活跃维护中.
Sharding-JDBC 定位为轻量 Java 框架, 使用客户端直连数据库, 无需额外部署, 无其他依赖, DBA 也无需改变原有的运维方式.
Sharding-JDBC 分片策略灵活, 可支持等号, between,in 等多维度分片, 也可支持多分片键. SQL 解析功能完善, 支持聚合, 分组, 排序, limit,or 等查询, 并支持 Binding Table 以及笛卡尔积表查询. Sharding-JDBC 直接封装 JDBC API, 可以理解为增强版的 JDBC 驱动, 旧代码迁移成本几乎为零:
可适用于任何基于 Java 的 ORM 框架, 如 JPA,Hibernate,Mybatis,Spring JDBC Template 或直接使用 JDBC.
可基于任何第三方的数据库连接池, 如 DBCP,C3P0, BoneCP,Druid 等.
理论上可支持任意实现 JDBC 规范的数据库. 虽然目前仅支持 MySQL, 但已有支持 Oracle,SQLServer 等数据库的计划.
分库分表引入的问题
分布式事务
分布式事务的解决方案: 由于两阶段 / 三阶段提交对性能损耗大, 可改用事务补偿机制.
跨节点 JOIN
对于单库 JOIN,MySQL 原生就支持; 对于多库, 出于性能考虑, 不建议使用 MySQL 自带的 JOIN, 可以用以下方案避免跨节点 JOIN:
全局表: 一些稳定的共用数据表, 在各个数据库中都保存一份;
字段冗余: 一些常用的共用字段, 在各个数据表中都保存一份;
应用组装: 应用获取数据后再组装.
另外, 某个 ID 的用户信息在哪个节点, 他的关联数据 (比如订单) 也在哪个节点, 可以避免分布式查询.
跨节点聚合
只能在应用程序端完成. 但对于分页查询, 每次大量聚合后再分页, 性能欠佳.
节点扩容
节点扩容后, 新的分片规则导致数据所属分片有变, 因而需要迁移数据.
来源: http://www.bubuko.com/infodetail-2955924.html