数据库分片原则和算法

1. 数据分片概念

        数据库分片是指将一个大型数据库拆分成多个小型数据库,每个小型数据库称为一个分片。通过这种方式,可以将数据库的负载分散到多个服务器上,从而提升性能瓶颈以及可用性。

        数据分片的核心手段就是对关系型数据库进行分库和分表。分库和分表均可以有效的避免由数据量超过可承受阈值而产生的查询瓶颈。除此之外,分库还能够用于有效的分散对数据节点单点的访问(你想想看,查订单的去订单节点查,查用户的去用户节点去查)。

        分表虽然无法缓解数据节点的压力,但却能够提供尽量将分布式事务变为本地事务来处理,一旦涉及到跨库的更新操作,分布式事务往往会使问题变得复杂(比如用户下订单时,扣积分、减库存就够你喝一壶了)。

        使用主从的分片方式,可以有效的避免数据单点,从而提升数据架构的可用性(更新操作去主节点,查询操作去从节点)。

        通过分库和分表进行数据的拆分来使得各个表的数据量保持在阈值以下,以及对流量进行疏导应对高访问量,是应对高并发和海量数据系统的有效手段。

什么情况下应该使用分片?

        是否应该实现分片数据库架构,几乎总是一个争论的问题。有些人认为分片对于达到一定规模的数据库来说,是不可避免的结果。而另一些人则认为这是一个令人头疼的问题,除非绝对必要,否则应该避免,因为分片增加了操作的复杂性。

  • (1)处理大规模数据: 数据量的快速增长是现代应用的常见情况。当数据量达到单个服务器的容量限制时,分片可以帮助应用处理大规模的数据,并将数据分布在多个节点上,充分利用集群的资源。
  • (2)提高读写性能: 分片可以将负载分散到多个节点上,从而提高数据库的读写性能。每个分片独立处理一部分数据,减轻了单个节点的负担,并允许并行处理查询和事务。

(3)增加可扩展性: 分片允许根据需求扩展数据库的容量和吞吐量。当数据量增加时,可以简单地增加更多的分片节点,而不是升级单个节点的硬件或软件。

(4)减少单点故障: 通过将数据分布在多个节点上,分片可以减少单个节点故障对整个系统的影响。如果一个节点发生故障,其他节点仍然可用,从而保证了系统的可用性和容错性。

5)提供地理位置灵活性: 分片使得数据可以根据地理位置进行存储。这可以帮助应用满足数据存储的合规性要求,并降低数据访问的延迟。

2.1分片原则

2.1.1垂直分片

1、原理

        按照业务拆分的方式叫做垂直分片,又叫做纵向拆分,就是专库专用的意思(有点像公司各个部门的意思,各司其职)。拆分之前,一个数据节点由多个业务表构成,每个表存储着不同的业务数据。而拆分之后,我们把表按照业务进行归类,分布到不同的数居节点中,从而将压力分散至不同的数据节点。比如与用户相关的放到用户库,订单相关的放到订单库。

        垂直分片需要对架构和设计进行调整。通常来讲,是来不及应对互联网业务需求快速变化的(例如双十一订单量突然增大);而且,它也无法真正地解决单点瓶颈。垂直拆分可以缓解数据量和访问量带来的问题,但无法根治。如果垂直拆分之后,表中的数据量依然超过单节点所能承载的阈值,则需要水平分片来进一步处理。

2、特点

(1)每个库(表)的结构都不一样;

(2)每个库(表)的数据至少有一列一样(分库或分表后至少有一个字段一样以将多个库或表关联起来);

(3)每个库(表)的并集是全量数据;

3、优点

(1)拆分后业务清晰(转库专用按业务拆分);

(2)实现动静分离、冷热数据分离设计体现。冷库是指访问较少的数据;热库是指访问较多的数据。

(3)数据维护简单,按业务不同放到不同机器上。

4、缺点

(1)无法很好的应对业务需求快速变化的情况;

(2)部分业务无法关联,存在跨库查询问题。

2.1.2水平分片

1、原理

        水平分片又叫做横向拆分(就像一个公司会在不同的城市设置不同的分公司去处理日常工作)。相对于垂直分片,它不再将数据根据业务逻辑归类,而是通过某个字段(或某几个字段),根据某种规则将数据分散至多个节点或表中,每个分片仅包含数据的一部分。例如:根据主键分片,偶数主键的记录放入0库(或表),奇数主键的记录放入1库(或表)。

        水平分片从理论上突破了单机数据量处理的瓶颈,并且扩展相对自由,是分库分表的标准解决方案。

2、特点

(1)每个库(表)的原理都一样;

(2)每个库(表)的数据都不一样;

(3)每个库(表)的并集是全量数据;

3、优点

(1)单库(表)的数据保持在一定的量,有助于性能提高;

(2)提高了系统的稳定性和负载能力;

(3)拆分的库(表)的结构相同,程序改造较少;

4、缺点

(1)数据的扩容很有难度维护量大,拆分规则很难抽象出来;

2.1.3数据分片引发问题

        面对散乱的分库分表之后的数据,开发工程师和数据库管理员对数据库的操作变得复杂就是其中的重要挑战之一。他们需要知道数据需要从哪个具体的数据库的哪个表中获取。你想想看,原来我们都在同一个地方办公,你想叫张三、李四都很容易,但现在大家都分派在天南海北,交流起来就不方便。

(1)数据聚合

        能够正确地运行在单节点数据库中的SQL,在分片之后的数据库中并并不一定能够正确运行。例如,分表导致表名称的修改,或者分页、排序、聚合分组等操作的不正确处理,比如,我们想查询订单表的前10条数据,以前只要一条SQL语句搞定,现在分到不同的数据节点,这时再想分页查询会让你崩溃。

(2)分布式事务

        采用分表策略,在降低一个表数据量的情况下,尽量使用本地事务,因为都在一个数据节点下就可以避免跨库事务的问题。

        在不能避免跨库事务的场景中,有些业务还是要保证事务的一致性,基于XA分布式事务在高并发的场景中性能无法满足需要,大多采用最终一致性的柔性事务代替强一致事务。

 2.2分片中间件

2.2.1 jdbc应用层分片

相比proxy性能更强,但其把语言限制在只能使用java,导致局限性很大。

1、sharding-jdbc(shardingsphere)

2.2.2 proxy代理层分片

没有语言限制!

1、mycat

2、mysql-proxy

2.3分片算法

2.3.1 range

思路:以用户中心的业务主键uid为划分依据,将数据水平切分到两个数据库实例上去:

        db_1:存储0到1千万的uid数据;

        db_2:存储1千万到2千万的uid数据;

(1)range算法的优点

  • 切分策略简单,根据id,按照范围,业务很快能够定位到数据在哪个库上;
  • 扩容简单,如果容量不够,只要增加db_3即可;

(2)range算法的不足

  • id必须要满足递增的特性;
  • 数据量不均,新增的db_3,在初期的数据会比较少;
  • 请求量不均,一般来说,新注册的用户活跃度会比较高,故db_2往往会比db_1负载要高,导致服务器利用率不平衡;

2.3.2 hash

思路:以用户中心的业务主键uid为划分依据,将数据水平切分到两个数据库实例上去:

        db_1:存储id取模得1的id数据;

        db_0:存储id取模得0的id数据;

(1)hash算法的优点

  • 切分策略简单,根据uid,按照hash,业务很快能够定位到数据在哪个库上;
  • 数据量均衡,只要uid是均匀的,数据在各个库上的分布一定是均衡的;
  • 请求量均衡,只要uid是均匀的,负载在各个库上的分布一定是均衡的;

(2)hash算法的不足

  • 扩容麻烦,如果容量不够,要增加一个库,重新hash可能会导致数据迁移,如何平滑的进行数据迁移,是一个需要解决的问题;

2.3.3索引表

思路:id能直接定位到库,数据不能直接定位到库,如果通过id能查询到db,问题解决;

解决方案

(1)建立一个索引表记录id ->db的映射关系;

(2)用id来访问时,先通过索引表查询到id,再定位相应的库;

(3)索引表属性较少,可以容纳非常多数据,一般不需要分库;

(4)如果数据量过大,可以通过id来分库;

优点:节点扩容无影响;

潜在不足:多一次数据库查询,性能下降一倍;

2.4实现分片

        开启分片(Sharding)涉及多个方面,包括数据库架构设计、部署配置和应用程序的更改。下面是一般情况下开启分片的步骤:

(1)设计分片策略: 首先需要确定适合应用的分片策略,如基于范围、哈希或列表等方式。根据应用的需求和数据特点选择合适的分片策略,并考虑分片键的选择。

(2)数据库架构设计: 根据分片策略设计数据库的整体架构。确定分片的数量和节点规模,以及分片之间的数据关联方式和数据路由规则。

(3)物理服务器部署: 根据数据库架构设计,部署和配置物理服务器。每个分片应该分配给独立的物理节点或服务器,确保每个节点有足够的计算和存储资源。

(4)数据库分片初始化: 在每个分片节点上创建数据库实例,并根据分片策略进行初始化。创建相应的表结构、索引和约束等,确保每个分片节点的数据库结构一致。

(5)数据迁移: 将现有的数据迁移到分片集群中。根据分片策略将数据拆分并导入到各个分片中,保证数据的一致性和完整性。这可能涉及数据导出、转换和导入的过程。

(6)应用程序更改: 修改应用程序代码,使其能够适应分片架构。更新数据库连接配置,确保应用程序能够正确地路由和访问各个分片。此外,还需要修改查询语句、事务处理和数据访问逻辑,以适应分片环境。

(7)负载均衡和路由配置: 配置负载均衡和路由机制,确保请求在分片集群中均匀分布。这可以通过负载均衡器或代理来实现,将请求路由到相应的分片节点。

(8)测试和监控: 对分片环境进行全面测试,确保分片策略的正确性和性能表现。设置监控系统,实时监测各个分片节点的运行状态和性能指标。

需要注意的是,开启分片是一个复杂的过程,需要综合考虑应用需求、数据特点和系统架构。在进行分片之前,建议进行充分的规划和评估,确保分片的正确实施和运维。同时,还需要考虑数据迁移的复杂性和系统升级的挑战。

猜你喜欢

转载自blog.csdn.net/weixin_47156401/article/details/132368472
今日推荐