分库分表

分库分表

什么是分库分表

  • 分库分表是两个概念 :分库分表
  • 目的:为了解决由于库、表数据量过大,而导致数据库性能持续下降的问题
  • 做法:按照一定的规则
    • 分库:将原本数据量大的数据库拆分成多个单独的数据库
    • 分表:将原本数据量大的表拆分成若干个数据表
  • 目标:是单一的库、表 性能达到最优的效果(响应速度快),以此提升整体数据库性能

如何分库分表

  • 核心理念:切分(Sharding)& 切分后对数据快速定位和查询结果整合
  • 方式:垂直(纵向)切分和 水平(横向)切分

垂直切分

垂直分库

  • 核心理念:专库专用
  • 垂直分库很大程度上取决于业务的划分,按业务类型对表进行分类,相同业务的表放在对应的数据库中。
    • 比如:订单系统可以分为 订单DB、优惠券DB、积分DB等
    • 不同业务间通过调用API接口来操作其他业务数据
  • 在一定程度上,垂直分库提升了一些数据库性能,但实际上并没有解决由于单表数据量过大导致的性能问题,需要配合水平切分方式来解决

垂直分表

  • 概念:是基于数据表的列(字段)为依据切分的,是一种大表拆小表的模式
  • 例如:订单表(order),将订单金额、订单编号等访问频繁的字段,单独拆成一张表。把blob类型的大字段或访问不频繁的字段,拆分出来创建一个单独的扩展表work_extend
  • 这样拆分后,核心表大多是访问频率高的字段,而且字段长度也较短,因而可以加载更多数据到内存,来增加查询的命中率,减少磁盘IO,以此来提升数据库性能。

优缺点

  • 垂直切分的优点
    • 业务间数据解耦,不同业务的数据进行独立的维护、监控、扩展。
    • 在高并发场景下,一定程度上缓解了数据库的压力。
  • 垂直切分的缺点
    • 提升了开发的复杂度,由于业务的隔离性,很多表无法直接访问,必须通过接口方式聚合数据。
    • 分布式事务管理难度增加。
    • 数据库还是存在单表数据量过大的问题,并未根本上解决,需要配合水平切分。

水平切分

垂直切分还是会存在单库、表数据量过大的问题,当我们的应用已经无法在细粒度的垂直切分时, 依旧存在单库读写、存储性能瓶颈,这时就要配合水平切分一起了,水平切分能大幅提升数据库性能。

水平分库

  • 概念:是把同一个表按一定的规则拆分到不同的数据库中,每个库可以位于不同的服务器上,以此实现水平扩展
  • 优点:解决了单库存储量级性能瓶颈问题
  • 缺点:同一个表被分配在不同的数据库中,数据的访问需要额外的路由工作,因此系统的复杂度也被提升了
  • 订单DB = 订单DB_1 + 订单DB_2 + 订单DB_3
    在这里插入图片描述

水平分表

  • 概念:是在同一个数据库内,把一张大数据量的表按一定规则,切分成多个结构完全相同表,而每个表只存原表的一部分数据。

在这里插入图片描述

优缺点

  • 水平切分的优点:

    • 解决高并发时单库数据量过大的问题,提升系统稳定性和负载能力。
    • 业务系统改造的工作量不是很大。
  • 水平切分的缺点:

    • 跨分片的事务一致性难以保证。
    • 跨库的join关联查询性能较差。
    • 扩容的难度和维护量较大,(拆分成几千张子表想想都恐怖)。

一定的规则是什么

  • 其实是一种路由算法,就是决定一条数据具体应该存在那个数据库的哪张表里
  • 常见的有 取模算法范围限定算法

取模算法

  • 概念:按字段取模(对hash结果取余数 (hash() mod N),N为数据库实例数或子表数量)
  • 比如:order订单表,对订单编号order_no进行取模
  • 优点:
    • 数据分片相对比较均匀,不易出现请求都打到一个库上的情况。
  • 缺点:
    • 这种算法存在一些问题,当某一台机器宕机,本应该落在该数据库的请求就无法得到正确的处理,这时宕掉的实例会被踢出集群,此时算法变成hash(userId) mod N-1,用户信息可能就不再在同一个库中了。

范围限定算法

  • 概念:按照 时间区间ID区间 来切分

  • 比如:order订单表,对主键id进行切分,第一个库存 id 从1 ~ 9999的数据,第二个库存 id 为10000 ~ 20000,第三个库存 id 为 20001~ 30000…

  • 再比如对按时间范围划分,一张表存一天的数据

  • 优点:

    • 单表数据量是可控的
    • 水平扩展简单只需增加节点即可,无需对其他分片的数据进行迁移
    • 能快速定位要查询的数据在哪个库
  • 缺点:

    • 由于连续分片可能存在数据热点,比如按时间字段分片,可能某一段时间内订单骤增,可能会被频繁的读写,而有些分片存储的历史数据,则很少被查询。

分库分表的难点

1、分布式事务

  • 由于表分布在不同库中,不可避免会带来跨库事务问题。
  • 一般可使用 "三阶段提交 "和 “两阶段提交” 处理,但是这种方式性能较差,代码开发量也比较大。
  • 通常做法是做到最终一致性的方案,如果不苛求系统的实时一致性,只要在允许的时间段内达到最终一致性即可,采用事务补偿的方式。

2、分页、排序、跨库联合查询

  • 分页、排序、联合查询是开发中使用频率非常高的功能,但在分库分表后,这些看似普通的操作却是让人非常头疼的问题。
  • 将分散在不同库中表的数据查询出来,再将所有结果进行汇总整理后提供给用户。

3、分布式主键

分库分表后数据库的自增主键意义就不大了,因为我们不能依靠单个数据库实例上的自增主键来实现不同数据库之间的全局唯一主键,此时一个能够生成全局唯一ID的系统是非常必要的,那么这个全局唯一ID就叫 分布式ID

4、读写分离

不难发现大部分主流的关系型数据库都提供了主从架构的高可用方案,而我们需要实现 读写分离 + 分库分表,读库与写库都要做分库分表处理。

5、数据脱敏

数据脱敏,是指对某些敏感信息通过脱敏规则进行数据转换,从而实现敏感隐私数据的可靠保护,如身份证号、手机号、卡号、账号密码等个人信息,一般这些都需要进行做脱敏处理。

©️2020 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页