MySQL 分库分表及其平滑扩容方案
作者:王克锋 出处:https://kefeng.wang/2018/07/22/mysql-sharding/
众所周知,数据库很容易成为应用系统的瓶颈。单机数据库的资源和处理能力有限,在高并发的分布式系统中,可采用分库分表突破单机局限。本文总结了分库分表的相关概念、全局ID的生成策略、分片策略、平滑扩容方案、以及流行的方案。
1 分库分表概述
在业务量不大时,单库单表即可支撑。当数据量过大存储不下、或者并发量过大负荷不起时,就要考虑分库分表。
1.1 分库分表相关术语
- 读写分离: 不同的数据库,同步相同的数据,分别只负责数据的读和写;
- 分区: 指定分区列表达式,把记录拆分到不同的区域中(必须是同一服务器,可以是不同硬盘),应用看来还是同一张表,没有变化;
- 分库:一个系统的多张数据表,存储到多个数据库实例中;
- 分表: 对于一张多行(记录)多列(字段)的二维数据表,又分两种情形:(1) 垂直分表: 竖向切分,不同分表存储不同的字段,可以把不常用或者大容量、或者不同业务的字段拆分出去;(2) 水平分表(复杂): 横向切分,按照特定分片算法,不同分表存储不同的记录。
1.2 真的要采用分库分表?
需要注意的是,分库分表会为数据库维护和业务逻辑带来一系列复杂性和性能损耗,除非预估的业务量大到万不得已,切莫过度设计、过早优化
。规划期内的数据量和性能问题,尝试能否用下列方式解决:
- 当前数据量:如果没有达到几百万,通常无需分库分表;
- 数据量问题:增加磁盘、增加分库(不同的业务功能表,整表拆分至不同的数据库);
- 性能问题:升级CPU/内存、读写分离、优化数据库系统配置、优化数据表/索引、优化 SQL、分区、数据表的垂直切分;
- 如果仍未能奏效,才考虑复杂的方案:数据表的水平切分。
2 全局ID生成策略
2.1 自动增长列
优点:数据库自带功能,有序,性能佳。缺点:单库单表无妨,分库分表时如果没有规划,ID可能重复。解决方案:
2.1.1 设置自增偏移和步长
### 假设总共有 10 个分表### 级别可选: SESSION(会话级), GLOBAL(全局)SET @@SESSION.auto_increment_offset = 1; ### 起始值, 分别取值为 1~10SET @@SESSION.auto_increment_increment = 10; ### 步长增量