一、传统项目结构
1.数据库性能瓶颈
-
数据库连接数有限 MySQL数据库默认100个连接、单机最大1500连接。
-
表数据量 单机表数量千级 单表数据千万级别 查询问题,索引命中率问题,索引存磁盘,占空间
-
硬件问题
2.数据库性能优化
-
1、参数优化
-
2、缓存、索引
-
3、读写分离
-
4、分库分表 (最终方案)
二、分库分表介绍
1 使用背景
当【表的数量】达到了几百上千张表时,众多的业务模块都访问这个数据库,压力会比较大,考虑对其进行分库; 当【表的数据】达到了几千万级别,在做很多操作都比较吃力,考虑对其进行分库或者分表;
2 数据切分(sharding)方案
数据的切分(Sharding)根据其切分规则的类型,可以分为垂直切分与水平切分;
2.1垂直切分
按照业务模块进行切分,将不同模块的表切分到不同的数据库中。
2.2水平切分
将一张大表按照一定的切分规则,以行为单位切分成不同的表或者切分到不同的库中;
水平切分规则
-
按照ID取模:对ID进行取模,余数决定该行数据切分到哪个表或者库中
-
按照日期:按照年月日,将数据切分到不同的表或者库中
-
按照范围:可以对某一列按照范围进行切分,不同的范围切分到不同的表或者数据库中。
3.切分原则
- 第一原则:能不切分尽量不要切分(如果数据量不高就不要切)。
- 第二原则:如果要切分一定要选择合适的切分规则,提前规划好(规划切分规则,一旦确定不可轻易更改)。
- 第三原则:数据切分尽量通过数据冗余或表分组(Table Group)来降低跨库 Join 的可能。
三、分库分表需要解决的问题
1.分布式事务问题
-
本地事务:ACID
-
分布式事务:CAP定理又称CAP原则,指的是在一个分布式系统中,Consistency(一致性)强一致性、 Availability(可用性)、Partition tolerance(分区容错性);CAP理论最多只能同时满足两个。
-
BASE理论:基本可用+软状态+最终一致性
最终一致性:补偿事务,利用记录日志等方式;
2.分布式主键ID问题
多个库中表的主键冲突,即实现统一ID主键
-
redis incr命令来生成唯一主键ID
-
使用数据库全局表(生成主键)
-
UUID (不好)
-
snowflake(雪花算法)算法(https://www.sohu.com/a/232008315_453160)
3.跨库join问题
-
建立全局表(每个库都有一个相同的表) 代码表、字典表[数据量小的表如lev、权限等]
-
E-R分片(数据量大的表,将有ER关系的记录都存储到一个库中,例如,tel表中有一个uid对应user.id,那么分库的时候tel的记录取模用uid,要依照user的id取模)
- 如果业务要求必须跨库,最多支持跨两张表跨库的join(实际中避免);
四、分库分表实现技术
- 阿里的TDDL
- Cobar 基于阿里Cobar开发的Mycat
- 当当网的sharding-jdbc