问题剖析:
当业务数据量达到千万级别时,表操作CRUD会比较慢,这个时候我们就该考虑分库分表操作了。分库分表的两个前提问题主要是:IO瓶颈及CPU瓶颈。
IO达到瓶颈时:
1) 网络IO瓶颈达到峰值,请求的数据太大,QPS达到峰值,网络带宽不够。--考虑分库及分表
2) 磁盘读写数据时,数据库缓存放不下,每次查询会产生大量的IO,降低查询的速率。--考虑分库
CPU瓶颈时:
1)单表的数据量太大,查询行数据剧增,耗时太长,SQL效率变低,--水平分表
2)SQL上大量使用了jion ,group by ,order by,非索引字段作为查询条件等,增加了CPU的运算成本,--优化SQL 建立适当的索引及业务层进行非必要sql逻辑运算处理
对于分库分表的概念:
垂直分库 | 以表为依据根据不同的业务进行业务数据库拆分 | 库表的结构不一样,数据也不一样没有交接, 但所有库的并集是全量数据 |
---|---|---|
水平分库 | 以字段为依据,按照hash、range、id取模等方式,将一个全库的数据割接到多个分库中 | 库表数据结构一致,库与库之间数据没有交集, 所有库的并集是全量数据 |
垂直分表 | 以字段为依据,按照字段的热点程度,进行表字段拆分,分为主表和详情表 | 每个表的结构都不一样,数据也不一样,但可能会保留至少 一列交集一般为主键用户关联数据,所有表的并集是全量数据 |
水平分表 | 以字段为依据,按照hash、range、id取模等方式,将一个全表的数据割接到多个分表中 | 表数据结构一致,表与表之间数据没有交集, 所有表的并集是全量数据 |
水平分库问题:系统并发量上来的时候,业务数据量太多,无法简单的通过分表来解决问题,并未通过业务场景垂直分库时。水平分库可减少IO和CPU的压力。
水平分表问题:系统并发量小,但因为单表的数据量太大影响了SQL效率,CPU负荷过重,成为瓶颈。水平分表可将数据量减小,单次SQL执行效率高,减轻了CPU负担。
垂直分库问题:系统并发量太大时,业务数据融合到同一个数据库中,网络负荷大。垂直分库可根据业务场景进行数据量才分,减轻单一模式。
垂直分表问题:系统绝对并发量并没有上来,虽表记录不多,但是字段多,将热点与非热点字段冗余到一起,单行数据存储所需的表空间大,以至于数据库缓存的数据行减少,查询时会读磁盘数据产生大量的随机读取IO,产生IO瓶颈。 对此我们可以将数据进行拆分,借助用户登录及用户详情来理解。垂直分表的拆分原则是将热点数据及非热点数据拆分出来,将热点数据缓存后,减少了随机读取IO,如果要全表的数据可将两个表关联起来,非必要时不适用jion关键字,可在service层处理数据,分别获取两个表数据,然后进行处理。
优点 | 缺点 | |
垂直 | 1.拆分后业务清晰 2.实现动静分离、冷热数据分离设计体现 3.数据维护简单、按根据业务划分不同库和机器 | 1.如果单表数据量大,读写压力比较大 2.受某种业务决定或者被限制 3.部分业务无法关联jion |
水平 | 1单库数据量减小,性能显著提高 2.提高了稳定性和负债能力 | 1.数据扩容比较难,维护量增加 2.拆分规则很难抽象出来 3.join比较麻烦 |
解决方式:
范围区分-(按时间、区域等划分,规划简单,范围查询困难)
预定义-(预估时间范围内的承载量,入手快,后期维护麻烦)
取模-(根据ID取模、一致性hash等方案)
存在问题:
维护成本高-(多库需要维护)
跨库jion查询-(跨库jion查询慢)
分布式事务-(分布式事务困难)
分布式全局ID
解决方案:
jdbc应用层:(性能较佳-直接访问数据库)
shardingsphare、tddl
(配置分片规则->jdbc规范重写->SQL解析->SQL路由->SQL改写-SQL执行->结果归并)
proxy代理层:(开发无感知、跨语言)
mycat、atals
(分片规则->分配逻辑->proxy->mysql返回)