`

用sharding技术来扩展你的数据库 (二)

 
阅读更多
摘要:

本部分首先简单介绍sharding系统的基本架构,然后重点介绍sharding机制中常用的三种表数据划分方法。

 

一.  数据划分算法

 

1. Sharding 系统的基本结构

 

上节我们说到Sharding可以简单定义为将大数据库分布到多个物理节点上的一个分区方案。每个shard都被放置在一个节点上面。 Sharding系统是一个shared-nothing的系统,基本上都采用下图中所示的架构。最下面是很多数据库服务器节点,每个节点上面都会运行一 个或多个数据库的实例。中间一层叫做查询路由器,客户端的连接都通过它进行转发。查询路由器负责解析用户的查询语句,并将这些语句转发到包含有所需要的数 据的shard节点上面去执行。执行的结果也会通过查询路由器进行汇总并发送给相应的客户端。

用sharding技术来扩展你的数据库 (二)

 

对于这样一个sharding系统,我们需要考虑到下面几个问题:如何将数据划分到多个shard节点上面;用户的查询语句如何正确的转发到相应的 节点上面去执行;当节点数据变化的时候怎样重新划分数据。对于数据划分和查询路由来说,所用的算法一般是对应的。下面就讲一下一些常用的数据划分的方法。 这里的假设前提是:只考虑单个表,并且这个表的划分键(Partitioning Key)已经被指定。

 

2. 常见的表划分算法

本节介绍三种常见的数据划分方法:轮流放置(Round-Robin)、一致性哈希(Consistent Hashing)和区间划分(Range-based Partitioning)。

 

2.1 Round-Robin

 

轮流放置是最简单的划分方法:即每条元组都会被依次放置在下一个节点上,以此进行循环。一般在实际应用中为了处理的方便,通常按照主键的值来决定次 序从而进行划分。即给定一个表T,表T的划分键 (Partitioning Key) 是k,需要划分的节点数目N,那么元组t ∈ T将会被放置在节点n上面,其中n = t.k mod N。由于划分只与划分键有关,因此我们可以把对元组的划分简化为对数字的划分,对于不是数字的键值可以通过其它方式比如哈希转化为数字形式。下面给出一个 例子来表示这种划分方式,把9个元组分布到3个节点上的情况。

用sharding技术来扩展你的数据库 (二)

但是,简单的直接用划分键上的值来计算放置节点的算法可能会造成数据的不均匀。因此,轮流放置有很多改进版,比如说哈希 方式(Hashing),即n = hash(t.k) mod N。先将划分键的值进行hash操作,变成一个与输入分布无关、输出均匀的值,然后再进行取模操作。哈希函数可以有很多选择,你可以针对你的应用的特征去 选取。

 

Pros: 轮流放置算法的实现非常简单,而且几乎不需要元数据就可以进行查询的路由,因此有着比较广泛的应用。例如EMC的Greenplum的分布式数据仓库采用的就是轮流放置和哈希相结合的方式。

 

Cons: 轮流放置同样具有很明显的缺点:当系统中添加或者删除节点时,数据的迁移量非常巨大。举个有20个节点的例子(下表),当系统由4个节点变为5个节点时, 会有如下的放置结果:红色部分是mod 4和mod 5时结果不相等的情况,不相等意味着这些元组当系统由4个节点变为5个节点时需要进行迁移。也就是说多达80%的元组都需要迁移。数据的迁移会对系统的性 能造成很大的影响,严重时可能会中断系统的服务。当系统的节点数目频繁变化时,是不提倡使用这种方式的。

 

用sharding技术来扩展你的数据库 (二)

 

数据迁移量大的问题可以通过改进轮流放置算法来达到,比较常见的两个改进算法是一致性哈希和分区划分算法。

 

2.2 Consistent Hashing

 

一致性哈希是一种特殊的哈希方式。传统的哈希方式(在上一小节中讲到)在当节点数目发生变化时,会引起大量的数据迁移。 而使用一致性哈希则不会产生这种问题。一致性哈希最早是一个分布式缓存(Distributed Caching)系统的放置算法(现在很热门的Memcached就用的是一致性哈希)。但是现在它已经被广泛应用到了其它各个领域。对于任何一个哈希函 数,其输出值都有一个取值范围,我们可以将这个取值区间画成一个环,如下图所示:

用sharding技术来扩展你的数据库 (二)

通过哈希函数,每个节点都会被分配到环上的一个位置,每个键值也会被映射到环上的一个位置。这个键值最终被放置在距离该 它的位置最近的,且位置编号大于等于该值的节点上面,即放置到顺时针的下一个节点上面。下图形象的表示了这种放置方案,其中Node 0上面放置Range 0上面的数据,以此类推。

用sharding技术来扩展你的数据库 (二)

 

Pros: 由于采用的哈希函数通常是与输入无关的均匀函数,因此当键值和节点都非常的多的时候,一致性哈希可以达到很好的分布式均匀性。并且由于特殊的放置规则,一 致性哈希在节点数据发生变动时可以将影响控制在局部区间内,从而保证非常少的数据迁移(接近理论上的最小值)。当增加一个节点时,只有这个节点所在的区间 内的数据需要被重新划分,如下图中,只需要将range 2上面的数据会从node 1中迁移到node 3上面。当删除一个节点时,只需要将这个节点上面的数据迁移到下一个节点上面,比如删除node 3,只把range 2上面的数据迁移到node 1上面就可以并,而其它的数据是不需要迁移变动的。

 

用sharding技术来扩展你的数据库 (二)

 

一致性哈希有非常广泛的应用,Key-Value系统,文档数据库或者分布式关系数据库都可以使用。Amazon的 NoSQL系统Dynamo应用采用的就是一种改进的一致性哈希算法。在这个系统中又引入了虚拟节点的概念,使得这个算法的load balance更加的好,并且同时考虑了复制技术。环上的点就变成了虚拟节点,然后再采用其它的方式将这些虚拟节点映射到实际的物理节点上面去。这使得系 统有很好的可扩展性和可用性。

 

2.3 Range-Based Partitioning

 

区间划分是现在很热门的NoSQL数据库MongoDB的sharding方案中所使用的算法。系统会首先把所有的数据 划分为多个区间,然后再将这些区间分配到系统的各个节点上面。最简单的区间划分是一个节点只持有一个区间:在有n个节点的情况下,将划分键的取值区间均匀 划分(这里的均匀是指划分后的每个partition的数据量尽量一样大,而并非值域区间一样大)为n份,然后每个节点持有一块。例如,按照用户名首字母 进行划分,可能有以下的划分方案:

 

用sharding技术来扩展你的数据库 (二)

如果发生数据分布不均匀的情况,可以通过调整区间分布达到均匀情况,数据迁移同样会很小。

用sharding技术来扩展你的数据库 (二)

 

但是另外一些情况下,可能会导致连锁迁移。

 

情况一:数据分布不均,调整导致的连锁迁移

用sharding技术来扩展你的数据库 (二)

 

情况二:增加或删除节点导致的连锁迁移:

 

用sharding技术来扩展你的数据库 (二)

 

为了解决这个问题,MongoDB采用的是每个节点持有多个区间的方案(Multiple range shards)。当需要进行迁移的时候,将持有过多数据的节点上的区间分裂,使得分裂出来的区间刚好满足迁移需要,然后再进行迁移。举例来说 (下图),如果shard 1中存有[a, f]区间的数据,数据量为500G,此时需要从shard 1上面迁移100G到shard 4,以保证数据的均匀分布。经统计,shard 1中的[a, d]段的数据为400G,[d, f]段数据为100G,因此将shard 1中的[d, f]段的数据直接迁移到shard 4上面。同理,需要从shard 2中迁移100G的数据到shard 3中。这种迁移方式的数据迁移量是理论上的最小值。

 

用sharding技术来扩展你的数据库 (二)

 

Cons: 每个节点多个区间的做法的缺点是使得对元数据的处理变得复杂,我们需要记录每个节点上面存储的所有区间。但是一般来说,每个节点上面的区间数目不是很大, 因此元数据的数目不会很大。这种同时保证了数据的最小迁移,并且实现也比较简单的方案是一个很理想的做法,虽然它的无数据管理和同步上面会有一些问题。

 

另外,区间划分非常适合处理有区间查询的查询语句,但是也带来很大的一个trade-off。如果一个查询需要访问到多 条元组,那么对区间的边界的选取就变得非常棘手,如果选择不当的话,很容易造成一个查询需要在多个节点上面进行运行的情况,这种跨节点的操作会对系统的性 能进行很大的影响。

 

当然了,对于分区划分来说,对于很多应用还是非常适合的,但是对于某些应用就非常不适合。同样上面介绍的轮流放置和一致 性哈希算法也是如此,这些算法只针对某些应用有用,我们需要一些更智能的算法来针对不同的应用选择不同的合适的算法。下一章我们会介绍几个比较智能的 sharding方案,这些方案会考虑并分析用户应用的工作流(Workload)、实际数据的特征等等从而从中得到一个比较好的方案出来。

分享到:
评论

相关推荐

    sharding-jdbc,分布式数据库中间件.zip

    **分布式数据库中间件Sharding-JDBC详解** Sharding-JDBC是Apache ShardingSphere项目的一部分,它是一个开源的、轻量级的Java框架,能够在现有的Java应用中无缝集成,实现数据库的分布式处理。作为数据库中间件,...

    一种基于Sharding碎片技术提升分布式非结构化数据库扩展能力的方法.pdf

    在实际应用中,采用Sharding技术的分布式非结构化数据库系统,对于I/O密集型应用而言,可以有效地缓解存储端的瓶颈问题,避免单纯依赖增加存储硬件容量来解决问题,进而减少硬件成本、降低维护成本,并对开发人员的...

    杨廷琨 - 从分区到Sharding:数据库核心业务表的分区设计

    例如,可以通过Sharding技术将数据分布到不同的数据库分片中,而在每个分片内部可以使用分区技术来进一步提高性能和可管理性。 总结来说,杨廷琨深入讲解了Oracle数据库分区技术的发展历程、Sharding技术的核心要点...

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

    **Sharding**,也称为数据库分片,是一种提高数据库性能和扩展性的技术手段。它的核心思想是将一个大型数据库分解成多个较小的部分(称为分片或shard),并将这些分片分布存储在不同的物理服务器上。这种做法有助于...

    sharding-jdbc分布式数据库培训方案

    总的来说,Sharding-JDBC 是一个强大的工具,能够帮助开发者构建可扩展的分布式数据库系统,应对大规模数据和高并发的业务场景。通过合理的设计和配置,可以有效地提升数据库的性能和系统的可靠性。

    当当开源sharding-jdbc-轻量级数据库分库分表中间件

    总之,Sharding-JDBC以其简单高效的设计理念、高度兼容性以及出色的性能表现,在数据库分库分表领域内占据了一席之地,对于需要解决大规模数据处理问题的企业来说,是一个值得关注和尝试的选择。

    数据库Sharding

    **数据库Sharding**,又称数据库分片,是一种在大型、高并发的系统中优化数据库性能和扩展性的技术手段。其核心思想在于将单一数据库的数据分割并分布到多个数据库(服务器)上,以此来提高数据处理能力和响应速度,...

    分布式数据库-MySQL Sharding1

    分布式数据库-MySQL Sharding1 是一种将单个数据库拆分成多个数据库节点的技术,目的是为了解决单个数据库的性能瓶颈和存储空间限制。这种技术可以将数据分布到多个数据库节点上,以提高系统的整体性能和可扩展性。 ...

    轻量级当当数据库中间件Sharding-JDBC深度解析

    Sharding-JDBC是由当当网开源的一个分布式数据库解决方案,它在保持传统关系型数据库的基础上,通过分库分表、读写分离等技术手段,以保证数据库的可扩展性、高性能和高可用性。Sharding-JDBC的一个重要特性是它不...

    SpringBoot整合Sharding-JDBC,实现从数据库加载sharding-jdbc数据源,实现多种数据库数据源切换,数据库方言动态切换

    而Sharding-JDBC则是阿里巴巴开源的一个分布式数据库中间件,用于解决大数据量下的数据库扩展问题。本篇将详细介绍如何在SpringBoot项目中整合Sharding-JDBC,实现在运行时动态地从数据库加载数据源,以及实现数据库...

    demo-example-sharding-jdbc-4.1.1.rar

    这个压缩包旨在展示如何在实际应用中有效地管理和扩展数据库表的规模,以应对高并发和大数据量的场景。 【描述】提到的"mvc + springboot + shardingjdbc 4.1.1"揭示了项目的技术栈。MVC(Model-View-Controller)...

    数据库分库分表(sharding)的技术

    ### 数据库分库分表(Sharding)技术详解 #### 一、基本概念与原理 **数据库分库分表(Sharding)**是一种常见的数据库优化技术,主要用于解决大规模数据存储和高并发访问带来的性能瓶颈问题。它通过将单一数据库...

    数据库+分库分表+sharding-jdbc

    通过以上介绍,我们可以看到,"数据库+分库分表+sharding-jdbc"这个主题涵盖了数据库性能优化、分布式架构设计以及具体实现工具Sharding-JDBC的使用,这些都是构建大规模分布式系统时不可或缺的关键技术。

    spring-sharding-mybatis

    【标签】"sharding" 指的是数据库分片,这是一种数据库水平扩展的技术,通过将大数据分布到多个物理数据库上,从而提高查询速度和并发处理能力,避免单个数据库成为系统的瓶颈。 以下是关于Spring Boot、...

    sharding jdbc 基于java代码的配置.zip

    Sharding-JDBC是一款轻量级的Java框架,它旨在解决大数据量下的数据库分库分表问题,无需修改数据库和...通过对文件“java0323”的深入学习,你可以掌握如何在项目中实施Sharding-JDBC,实现数据库的高效分片和管理。

    Sharding JDBC PPT 分享

    Sharding JDBC具有易于使用,无需额外依赖和强依赖数据库的特点。它允许开发人员对JDBC进行分片操作,从而实现对数据库进行水平切分。 Sharding JDBC在2015年9月发布,之后在2016年的3月、5月以及12月都有更新。...

    springboot整合sharding-jdbc完整代码

    SpringBoot整合Sharding-JDBC是将Sharding-JDBC这一分布式数据库中间件与SpringBoot框架结合,以实现数据分片、读写分离等高级数据库管理功能。这个完整的代码示例覆盖了Sharding-JDBC的主要技术点,使开发者可以...

    sharding-proxy实现分表

    Sharding-Proxy 支持 SQL 解析、路由、分布式事务等,简化了数据库扩展的复杂度。 ### 4. 使用 Sharding-Proxy 实现分表策略 在本案例中,分表策略是每半年时间分一次表。这意味着根据时间维度(如年份和月份)...

    sharding-jdbc.rar

    4. 编写业务代码:在Service和Controller中,使用Mybatis的Mapper接口进行数据库操作,Sharding-JDBC会在幕后自动处理分片逻辑。 总结,通过将Sharding-JDBC与SpringBoot和Mybatis结合,我们可以轻松地实现数据库的...

    Sharding JDBC 实现数据分片 - 技术分享.pdf

    使用ShardingJDBC时,对项目的侵入性非常小,开发者几乎不需要做代码层的修改,也不需要修改SQL语句,只需要通过配置来指定待分库分表的数据表即可。ShardingJDBC兼容所有的基于JDBC的ORM框架,包括但不限于JPA、...

Global site tag (gtag.js) - Google Analytics