数据库Sharding的基本思想和切分策略


《大数据平台架构与原型实现:数据中台建设实战》一书由博主历时三年进行创作,现已由知名IT图书品牌电子工业出版社博文视点出版发行,真诚推荐给每一位读者!点击《重磅推荐:建大数据平台太难了!给我发个工程原型吧!》了解图书详情,扫描左侧二维码可进入京东购书页面!

本文着重介绍sharding的基本思想和理论上的切分策略,关于更加细致的实施策略和参考事例请参考我的另一篇博文:数据库分库分表(sharding)系列(一) 拆分实施策略和示例演示 

一、基本思想

Sharding的基本思想就要把一个数据库切分成多个部分放到不同的数据库(server)上,从而缓解单一数据库的性能问题。不太严格的讲,对于海量数据的数据库,如果是因为表多而数据多,这时候适合使用垂直切分,即把关系紧密(比如同一模块)的表切分出来放在一个server上。如果表并不多,但每张表的数据非常多,这时候适合水平切分,即把表的数据按某种规则(比如按ID散列)切分到多个数据库(server)上。当然,现实中更多是这两种情况混杂在一起,这时候需要根据实际情况做出选择,也可能会综合使用垂直与水平切分,从而将原有数据库切分成类似矩阵一样可以无限扩充的数据库(server)阵列。下面分别详细地介绍一下垂直切分和水平切分.

垂直切分的最大特点就是规则简单,实施也更为方便,尤其适合各业务之间的耦合度非常低,相互影响很小,业务逻辑非常清晰的系统。在这种系统中,可以很容易做到将不同业务模块所使用的表分拆到不同的数据库中。根据不同的表来进行拆分,对应用程序的影响也更小,拆分规则也会比较简单清晰。(这也就是所谓的”share nothing”)。

水平切分于垂直切分相比,相对来说稍微复杂一些。因为要将同一个表中的不同数据拆分到不同的数据库中,对于应用程序来说,拆分规则本身就较根据表名来拆分更为复杂,后期的数据维护也会更为复杂一些。

让我们从普遍的情况来考虑数据的切分:一方面,一个库的所有表通常不可能由某一张表全部串联起来,这句话暗含的意思是,水平切分几乎都是针对一小搓一小搓(实际上就是垂直切分出来的块)关系紧密的表进行的,而不可能是针对所有表进行的。另一方面,一些负载非常高的系统,即使仅仅只是单个表都无法通过单台数据库主机来承担其负载,这意味着单单是垂直切分也不能完全解决问明。因此多数系统会将垂直切分和水平切分联合使用,先对系统做垂直切分,再针对每一小搓表的情况选择性地做水平切分。从而将整个数据库切分成一个分布式矩阵。

二、切分策略

如前面所提到的,切分是按先垂直切分再水平切分的步骤进行的。垂直切分的结果正好为水平切分做好了铺垫。垂直切分的思路就是分析表间的聚合关系,把关系紧密的表放在一起。多数情况下可能是同一个模块,或者是同一“聚集”。这里的“聚集”正是领域驱动设计里所说的聚集。在垂直切分出的表聚集内,找出“根元素”(这里的“根元素”就是领域驱动设计里的“聚合根”),按“根元素”进行水平切分,也就是从“根元素”开始,把所有和它直接与间接关联的数据放入一个shard里。这样出现跨shard关联的可能性就非常的小。应用程序就不必打断既有的表间关联。比如:对于社交网站,几乎所有数据最终都会关联到某个用户上,基于用户进行切分就是最好的选择。再比如论坛系统,用户和论坛两个模块应该在垂直切分时被分在了两个shard里,对于论坛模块来说,Forum显然是聚合根,因此按Forum进行水平切分,把Forum里所有的帖子和回帖都随Forum放在一个shard里是很自然的。

对于共享数据数据,如果是只读的字典表,每个shard里维护一份应该是一个不错的选择,这样不必打断关联关系。如果是一般数据间的跨节点的关联,就必须打断。

需要特别说明的是:当同时进行垂直和水平切分时,切分策略会发生一些微妙的变化。比如:在只考虑垂直切分的时候,被划分到一起的表之间可以保持任意的关联关系,因此你可以按“功能模块”划分表格,但是一旦引入水平切分之后,表间关联关系就会受到很大的制约,通常只能允许一个主表(以该表ID进行散列的表)和其多个次表之间保留关联关系,也就是说:当同时进行垂直和水平切分时,在垂直方向上的切分将不再以“功能模块”进行划分,而是需要更加细粒度的垂直切分,而这个粒度与领域驱动设计中的“聚合”概念不谋而合,甚至可以说是完全一致,每个shard的主表正是一个聚合中的聚合根!这样切分下来你会发现数据库分被切分地过于分散了(shard的数量会比较多,但是shard里的表却不多),为了避免管理过多的数据源,充分利用每一个数据库服务器的资源,可以考虑将业务上相近,并且具有相近数据增长速率(主表数据量在同一数量级上)的两个或多个shard放到同一个数据源里,每个shard依然是独立的,它们有各自的主表,并使用各自主表ID进行散列,不同的只是它们的散列取模(即节点数量)必需是一致的。(本文着重介绍sharding的基本思想和理论上的切分策略,关于更加细致的实施策略和参考事例请参考我的另一篇博文:数据库分库分表(sharding)系列(一) 拆分实施策略和示例演示 


1.事务问题


解决事务问题目前有两种可行的方案:分布式事务和通过应用程序与数据库共同控制实现事务下面对两套方案进行一个简单的对比。


方案一:使用分布式事务


    优点:交由数据库管理,简单有效


    缺点:性能代价高,特别是shard越来越多时


方案二:由应用程序和数据库共同控制


     原理:将一个跨多个数据库的分布式事务分拆成多个仅处于单个数据库上面的小事务,并通过应用程序来总控各个小事务。


     优点:性能上有优势


     缺点:需要应用程序在事务控制上做灵活设计。如果使用了spring的事务管理,改动起来会面临一定的困难。


2.跨节点Join的问题

只要是进行切分,跨节点Join的问题是不可避免的。但是良好的设计和切分却可以减少此类情况的发生。解决这一问题的普遍做法是分两次查询实现。在第一次查询的结果集中找出关联数据的id,根据这些id发起第二次请求得到关联数据。


3.跨节点的count,order by,group by以及聚合函数问题


这些是一类问题,因为它们都需要基于全部数据集合进行计算。多数的代理都不会自动处理合并工作。解决方案:与解决跨节点join问题的类似,分别在各个节点上得到结果后在应用程序端进行合并。和join不同的是每个结点的查询可以并行执行,因此很多时候它的速度要比单一大表快很多。但如果结果集很大,对应用程序内存的消耗是一个问题。

参考资料:

《MySQL性能调优与架构设计》

注:本文图片摘自《MySQL性能调优与架构设计》一 书

相关阅读:

数据库分库分表(sharding)系列(五) 一种支持自由规划无须数据迁移和修改路由代码的Sharding扩容方案

数据库分库分表(sharding)系列(四) 多数据源的事务处理

数据库分库分表(sharding)系列(三) 关于使用框架还是自主开发以及sharding实现层面的考量

数据库分库分表(sharding)系列(二) 全局主键生成策略

数据库分库分表(sharding)系列(一) 拆分实施策略和示例演示

关于垂直切分Vertical Sharding的粒度

数据库Sharding的基本思想和切分策略

  • 101
    点赞
  • 413
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 40
    评论
### 回答1: ShardingJDBC是一种分库分表的策略,它可以将一个大型的数据库拆分成多个小型的数据库,每个小型数据库都可以独立运行。这种策略可以提高数据库的性能和可扩展性,同时也可以减少数据库的负载和维护成本。ShardingJDBC可以通过水平分割数据表来实现分库分表,将数据按照一定的规则分散到不同的数据库中,从而实现数据的分布式存储和查询。这种策略可以有效地解决大型数据库的性能瓶颈和扩展问题,是现代大型应用程序中常用的数据库架构之一。 ### 回答2: ShardingJDBC是一种支持分库分表的轻量级中间件,它可以将数据库表数据按照一定规则划分到多个数据库中,从而达到高性能、高可用性、高扩展性的目的。ShardingJDBC的分库分表策略是其核心功能之一,根据不同的应用场景和需求,可以选择不同的策略进行数据分片。 常见的分库分表策略有水平拆分和垂直拆分两种方式。水平拆分是将同一张表的数据按照某种规则划分到不同的数据库中,比如按照订单号的后两位分库,或按照用户ID的奇偶性分表。水平拆分可以有效地将负载分散到不同的数据库上,提高查询效率,但也会增加分布式事务管理和数据一致性的复杂度。 垂直拆分则是将一个大的表根据字段的不同划分成多个小表,每个小表只包含特定的字段,比如用户表中的基本信息和敏感信息分别存储在两个表中。这样做可以有效地避免表结构过于臃肿的问题,也可以加快查询速度,但也会增加关联查询的复杂度。 ShardingJDBC还支持一些高级的分片策略,如自定义分片、广播表、只读分离等。自定义分片可以根据具体需求定制自己的分片规则,广播表可以将某些表在所有数据库中都复制一份,用于高频率的查询和写入,只读分离则可以将读操作和写操作分开处理,提高查询效率。 总之,ShardingJDBC的分库分表策略可以根据不同情况有针对性地选择,用于优化数据库性能和扩展性,但也需要在实际应用中考虑如何保证数据一致性和事务管理的复杂度。 ### 回答3: ShardingJDBC是一种分库分表的数据库中间件,可以将数据分散到多个数据库、表中存储,提高查询效率,同时支持水平扩展,提高系统的性能和可扩展性。在使用ShardingJDBC时需要实现分库分表策略,来决定如何将数据分散存储到多个数据库和多个表中。 ShardingJDBC的分库分表策略包括垂直分库、水平分库、水平分表等,可以根据具体业务需求选择不同的策略。 垂直分库是指根据业务功能将不同的表分配到不同的数据库中存储,比如将用户信息、订单信息等分别存储在不同的数据库中,当需要查询某个业务时,只需连接对应的数据库即可,避免了全表扫描,提高了查询效率。 水平分库是将一个大的数据库分成多个小的数据库分别存储数据,可以通过分库键将数据划分到不同的数据库中。例如将订单信息按照用户ID的哈希值分别存储在不同的数据库中,通过这种方式将查询请求分散到不同的数据库中,从而提高并发能力和响应速度。 水平分表是将一个大表按照某个关键字段(如用户ID、时间戳等)进行拆分,拆分后的小表分布在不同的数据库中。例如将订单表按照订单创建时间拆分成多个小表,每个表存储一段时间内的订单信息。这样可以降低单张表的数据量,提高查询性能和数据存储效率。 在实现分库分表策略时,需要考虑数据一致性和事务管理问题,ShardingJDBC提供了事务管理和XA分布式事务等功能,保证数据的一致性和可靠性。 总之,ShardingJDBC提供了多种分库分表策略,可以根据业务需求选择不同的策略来分散存储数据,在提高查询效率和性能的同时,保证数据的一致性和可靠性,提高系统的可扩展性和稳定性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 40
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Laurence 

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值