分库分表

分库分表的原因

  随着业务发展,数据越来越多,甚至达到亿级。如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较为流行。

最后

  引入tidb(newsql)解决分库分表带来的一系列问题

  tidb优点:

  1. 高度兼容mysql协议,迁移成本低

  2. 高可用:相比于传统主从(M-S)复制方案,基于Raft的多数派选举协议可以提供金融级的100%数据强一致性保证,且在不丢失大多数副本的前提下,可以实现故障的自动恢复(auto-failover),无需人工介入

  3. 支持海量数据,可扩展性强:分布式数据库,可通过增加tikv节点扩展,支持分裂和自动迁移,对业务基本无感知。

  4. 和传统的分库分表,相比业务拓展性较强:传统的分库分表技术,开发和维护成本都较高,业务侵入性也较大,使用tidb会明显降低RD和DBA的开发维护成本

  5. 分布式事务

tidb分析及使用参考:https://zhuanlan.zhihu.com/p/338955227

 

posted @ 2022-11-20 10:51  白玉神驹  阅读(93)  评论(0)    收藏  举报