分库分表的原因
随着业务发展,数据越来越多,甚至达到亿级。如mysql单库在5000万以内性能较好,超过阈值后性能会随着数据量的增大而明显降低。单表的数据量超过1000万,性能也会下降,导致查询一次所花的时间变长,并发操作达到一定量可能会卡死,甚至把系统拖垮。
通过提升服务器硬件能力来提高数据处理能力,但这种方案很贵且硬件有上限。因此把数据分散在不同的数据库中,使得单一数据库和表的数据量变小,从而提升数据库操作性能的目的-分库分表。
分库分表:把较大数据库的数据按照某种策略进行拆分。
目的在于:降低每个库、每张表的数据量,减少数据库的负担,提供数据库的效率,缩短查询时间。另外,分库分表这种改造是可控的,底层基于RDBMS,因此整个数据库的运维体系以及相关基础设施都是可重用的。
分库分表的方式
垂直分表:
订单拆分为基本信息和订单详情;基本信息访问频次高于商品详情,且两种数据特性不一样,因此拆分。
垂直分表定义:将一个表的字段分散到多个表中,每个表存储其中一部分字段。
垂直分表带来的提升:1.减少io争抢,减少锁表的几率,查看详情和概述互不影响;2.充分发挥高频数据的操作效率,对概述操作的高效率不会被操作商品详情数据的低效率所拖累。
一般来说,业务实体中各个数据访问频次是不一样的,部分数据项可能占用存储空间比较大,因此可以将表字段拆分,将热门字段、冷门字段分开放置在不同表中。垂直切分带来的性能提升,主要集中在热门数据的操作效率上,而磁盘争用情况减少。
通常按照以下原则垂直拆分:
1. 把不常用的字段单独放在一张表
2. 把text,blob等大字段拆分出来单独放一张表
3. 经常组合查询的字段单独放在一张表中
垂直分库
订单表的订单基本信息和订单详情耦合度较高,一起放在订单库;而套餐包信息相对独立,可以单独放在权益库。
垂直分库定义:通过垂直分表,数据库性能得到一定提升,但还没达到要求,并且磁盘空间也快不够了,数据始终存放在一台服务器。库内垂直分表只解决了单一表数据量大的问题,但没将表分布到不同机器的库上,因此还是竞争同一个物理机的cpu,内存,网络io、磁盘。
垂直分库是按照业务将表进行分类,分布到不同数据库上面,每个库可以放在不同的服务器上,从而达到多个服务器共同分摊压力的效果。
垂直分库带来的提升:1.解决业务层面的耦合,业务清晰 2.能对不同业务数据进行分级管理、维护、监控、扩展等 3.高并发场景下,垂直分库在一定程度上可以提升io、数据库连接数、单机硬件资源的性能。
水平分库
订单库存储数据已经超出预估,根据订单id区分是否为奇数(一定规则),将此操作映射到订单库1,为偶数映射到订单库2。
水平分库定义:把同一个表的数据按一定规则拆分到不同的数据库中,每个库可以放在不同的服务器上。
水平分库带来的提升:1.解决了单库大数据,高并发的性能瓶颈 2.按照合理拆分规则拆分,join操作基本避免跨库 3.提高了系统的稳定性及可用性
当一个应用难以再细粒度垂直切分,或切分后数据量行数仍然巨大,存在单库读写、存储性能瓶颈,这时候需要进行水平分库了,经过水平切分的优化,往往能解决单库存储量及性能瓶颈。但由于同一个表被分配在不同的数据库,需要额外进行数据操作的路由工作,因此大大增加了系统复杂度。
水平分表
与水平分库类似,把订单库中的订单基础信息表和详情表拆分成两套表。订单id为奇数映射到订单信息表1,为偶数映射订单信息表2.
水平分表定义:把同一个表的数据按一定规则拆分到多个表中。
水平分表带来的提升:1.优化单一表数据量过大而产生的性能问题 2.避免io争抢并减少锁表的几率
库内的水平分表,解决了单一表数据库过大的问题,分出来的小表中只包含一部分数据,从而使得单个表的数据量变小,提高检索性能。但由于同一个表的数据被拆分为多张表,也需要额外惊醒数据操作的路由工作,因此增加了系统复杂度。
分库分表总结
垂直分表:把一个宽表的字段按频次访问、业务耦合松紧、是否大字段原则拆分多个表,这样业务清晰且提升部分性能。拆分后,尽量从业务角度避免联查,否则性能方面得不偿失。
垂直分库:把多个表按业务耦合松紧归类,分别存放在不同的库,这些库可以分布在不同服务器,从而使访问压力被多个服务器负载,大大提升性能,同时提高整体架构的业务清晰度,不同业务库可根据自身情况定制优化方案。但需要解决跨库带来的所有复杂问题。
水平分库:把一个表的数据按行分到多个不同库,每个库只有这个表的部分数据,这些库可以分布在不同服务器,从而使访问压力被多服务器负载,提升性能。但需要解决跨库带来的复杂问题,和数据路由问题。
水平分表:把一个表的数据分到多个同一个数据库的多张表,每个表只有这个表的部分数据,可以小幅提升性能,仅仅作为水平分库的一个补充优化。
一般来说,在系统设计阶段就应该根据业务耦合松紧来确定垂直分库,垂直分表方案,在数据量及访问压力不是特别大的情况,首先考虑缓存、读写分离、索引技术等方案。若数据量极大,且持续增大,再考虑水平分库分表方案。
分库分表带来的问题
事物一致性问题
由于分库分表把数据分布在不同库甚至不同服务器,不可避免会带来分布式事务问题,需要额外变成解决该问题。
跨节点join
在没有分库分表前,可以通过join关联查询,分库分表后无法通过sql语句进行关联查询,需要额外编程解决该问题。
跨节点分页、排序和聚合函数
跨节点多库进行查询时,limit分页、order by排序及聚合函数等问题,复杂了。需要先在不同的分片节点中将数据进行排序并返回,然后将不同分片返回的结果集进行汇总和再次排序。
主键避重
在分库分表中,由于表中数据同时存在不同数据库中,主键值平时使用的自增长将无用武之地,某个分区数据库生成的id无法保证全局唯一。因此需要单独设计全局主键,以避免跨库主键重复问题。
由于分库分表后,数据被分散在不同服务器、数据库和表中。因此对数据的操作也就无法通过常规方式完成,并且带来一系列问题。开发过程中可以通过一些中间件解决,如Sharding-JDBC和mycat较为流行。
标签:分库,数据库,垂直,订单,分表,数据 From: https://www.cnblogs.com/cgy-home/p/16907964.html