数据库的sharding技术作为一个“新瓶装旧酒”的概念,在新的应用环境中被赋予了新的意义。随着云计算的发
展,sharding在最近几年是越来越火热,越来越多的产品开始声称自己支持sharding功能。那么到底什么是sharding,sharding
到底能为你的数据库应用带来哪些好处。另外最重要的,如何实现一个sharding系统,有哪些sharding算法可供选择。本文将为你解决这些问题。
一.
简介
1. 背景
数据库的扩展是一个永恒的话题。对于传统的关系数据库,采用的是纵向扩展(Scale
Up)的方式,即买更好的机器添加更多的资源来取得更好的性能(如硬件升级、更快更多的CPU、更大的内存、更多更大的磁盘等)。而形式上采用的是并行数
据库、分布式数据库的模式,具体细节依赖水平分区或者垂直分区的技术。关系数据库通过ScaleUp方式已在传统的企业应用环境中统治了将近三十多年。
但是近年来随着数据量的暴增尤其是云计算模式的出现,这种扩展模式对于某些应用已经不太适合,这时便出现了横向扩展(Scale
Out)模式。这种方式采用一些Ad-hoc的技术,比如说对数据库进行主从配置(Master-Slave)、采用数据库复制
(Replication)技术以及服务器的缓存(Server
Cache)等,来将负载分布到多个物理节点上去。另外sharding技术也逐步发展,并在近年来吸引了众人的眼球。
2. 什么是Sharding
Sharding 是把数据库Scale
Out到多个物理节点上的一种有效的方式。Shard这个词的意思是“碎片”。如果将一个数据库当作一块大玻璃,将这块玻璃打碎,那么每一小块都称为数据
库的碎片(DatabaseShard)。将整个数据库打碎的过程就叫做sharding,可以翻译为分片。
形式上,Sharding可以简单定义为将大数据库分布到多个物理节点上的一个分区方案。每一个分区包含数据库的某一部分,称为
一个shard,分区方式可以是任意的,并不局限于传统的水平分区和垂直分区。一个shard可以包含多个表的内容甚至可以包含多个数据库实例中的内容。
每个shard被放置在一个数据库服务器上。一个数据库服务器可以处理一个或多个shard的数据。系统中需要有服务器进行查询路由转发,负责将查询转发
到包含该查询所访问数据的shard或shards节点上去执行。
3. Sharding与分区的比较
Sharding与分区有着千丝万缕的联系,它们所采取的技术本质上是类似的,可以说sharding的概念就是由分区而来。在
某些情况下sharding可能指的就是水平分区。另外有些文档中使用了fragment(也是碎片的意思)的术语(在并行数据库中的这些分区称为
partition,在分布式数据库中则称为fragment)。\ref footnote 1
Foot note 1:
[[
Daniel C. Zilio. Physical Database Design Decision
Algorithms and ConcurrentReorganization for Parallel Database Systems.
PhD thesis 1997.
M. Tamer Özsu, Patrick Valduriez. Principles ofDistributed Database Systems, Third Edition. Springer. 2011
]]
但是我们所说的sharding和分区还是有很大区别的。下面罗列一下:
(1)扩展方式不同。Sharding属于scaleout,而分区则属于scale up方式。
(2)目的不同。分区的目的是为了将一个查询进行并行处理,这样所有的节点能并行处理一个查询;而sharding是让每个节点尽量处理不同的查询。
(3)应用场景:分区适用与传统的企业应用,尤其是OLAP的应用,基本上每个查询都需要访问大部分的数据;而sharding适用于云Web应用,特征是有大量的用户和查询,但是每个查询访问到的元组是非常少的,sharding可以将负载分散到多个物理节点上。
(4)可用性:对于分布式数据库基本上每个查询都需要所有的节点参与,如果某些节点down掉后,系统会大受影响;而
sharding所处理的应用一般只涉及到少数几个节点,所以可用性上sharding要好一些。另外分布式数据库需要有一个主节点来生成执行计划并协调
相关节点执行等,很容易形成单点瓶颈。
(5)分割粒度:分区一般只针对于一个数据库内部进行分割;而sharding可以以数据库为粒度进行分割,因此可用来构建多租房数据库系统(multi-tenantdatabase)。
4.Sharding的优点
对于Sharding来说,主要有以下主要的优点:
(1)提高了数据库的可扩展性,可以随着应用的增长来增加更多的服务器,只需要将新增加的数据以及负载放到新加的服务器上就可以。
(2)提高了数据库的可用性。其中几个shard服务器down掉之后,并不会使整个系统对外停止服务,而只会影响到需要访问这几个shard服务器上的数据的用户。
(3)小的数据库的查询压力比较小,查询更快,性能更好。
(4)系统有更好的可管理性。对系统的升级和配置可以按照shard一个一个来做,并不会对服务产生大的影响。
本部分首先简单介绍sharding系统的基本架构,然后重点介绍sharding机制中常用的三种表数据划分方法。
一.
数据划分算法
1. Sharding 系统的基本结构
上节我们说到Sharding可以简单定义为将大数据库分布到多个物理节点上的一个分区方案。每个shard都被放置在一个节点上面。
Sharding系统是一个shared-nothing的系统,基本上都采用下图中所示的架构。最下面是很多数据库服务器节点,每个节点上面都会运行一
个或多个数据库的实例。中间一层叫做查询路由器,客户端的连接都通过它进行转发。查询路由器负责解析用户的查询语句,并将这些语句转发到包含有所需要的数
据的shard节点上面去执行。执行的结果也会通过查询路由器进行汇总并发送给相应的客户端。
对于这样一个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个节点上的情况。
但是,简单的直接用划分键上的值来计算放置节点的算法可能会造成数据的不均匀。因此,轮流放置有很多改进版,比如说哈希
方式(Hashing),即n = hash(t.k) mod
N。先将划分键的值进行hash操作,变成一个与输入分布无关、输出均匀的值,然后再进行取模操作。哈希函数可以有很多选择,你可以针对你的应用的特征去
选取。
Pros: 轮流放置算法的实现非常简单,而且几乎不需要元数据就可以进行查询的路由,因此有着比较广泛的应用。例如EMC的Greenplum的分布式数据仓库采用的就是轮流放置和哈希相结合的方式。
Cons:
轮流放置同样具有很明显的缺点:当系统中添加或者删除节点时,数据的迁移量非常巨大。举个有20个节点的例子(下表),当系统由4个节点变为5个节点时,
会有如下的放置结果:红色部分是mod 4和mod
5时结果不相等的情况,不相等意味着这些元组当系统由4个节点变为5个节点时需要进行迁移。也就是说多达80%的元组都需要迁移。数据的迁移会对系统的性
能造成很大的影响,严重时可能会中断系统的服务。当系统的节点数目频繁变化时,是不提倡使用这种方式的。
数据迁移量大的问题可以通过改进轮流放置算法来达到,比较常见的两个改进算法是一致性哈希和分区划分算法。
2.2 Consistent Hashing
一致性哈希是一种特殊的哈希方式。传统的哈希方式(在上一小节中讲到)在当节点数目发生变化时,会引起大量的数据迁移。
而使用一致性哈希则不会产生这种问题。一致性哈希最早是一个分布式缓存(Distributed
Caching)系统的放置算法(现在很热门的Memcached就用的是一致性哈希)。但是现在它已经被广泛应用到了其它各个领域。对于任何一个哈希函
数,其输出值都有一个取值范围,我们可以将这个取值区间画成一个环,如下图所示:
通过哈希函数,每个节点都会被分配到环上的一个位置,每个键值也会被映射到环上的一个位置。这个键值最终被放置在距离该
它的位置最近的,且位置编号大于等于该值的节点上面,即放置到顺时针的下一个节点上面。下图形象的表示了这种放置方案,其中Node
0上面放置Range 0上面的数据,以此类推。
Pros:
由于采用的哈希函数通常是与输入无关的均匀函数,因此当键值和节点都非常的多的时候,一致性哈希可以达到很好的分布式均匀性。并且由于特殊的放置规则,一
致性哈希在节点数据发生变动时可以将影响控制在局部区间内,从而保证非常少的数据迁移(接近理论上的最小值)。当增加一个节点时,只有这个节点所在的区间
内的数据需要被重新划分,如下图中,只需要将range 2上面的数据会从node 1中迁移到node
3上面。当删除一个节点时,只需要将这个节点上面的数据迁移到下一个节点上面,比如删除node 3,只把range 2上面的数据迁移到node
1上面就可以并,而其它的数据是不需要迁移变动的。
一致性哈希有非常广泛的应用,Key-Value系统,文档数据库或者分布式关系数据库都可以使用。Amazon的
NoSQL系统Dynamo应用采用的就是一种改进的一致性哈希算法。在这个系统中又引入了虚拟节点的概念,使得这个算法的load
balance更加的好,并且同时考虑了复制技术。环上的点就变成了虚拟节点,然后再采用其它的方式将这些虚拟节点映射到实际的物理节点上面去。这使得系
统有很好的可扩展性和可用性。
2.3 Range-Based Partitioning
区间划分是现在很热门的NoSQL数据库MongoDB的sharding方案中所使用的算法。系统会首先把所有的数据
划分为多个区间,然后再将这些区间分配到系统的各个节点上面。最简单的区间划分是一个节点只持有一个区间:在有n个节点的情况下,将划分键的取值区间均匀
划分(这里的均匀是指划分后的每个partition的数据量尽量一样大,而并非值域区间一样大)为n份,然后每个节点持有一块。例如,按照用户名首字母
进行划分,可能有以下的划分方案:
如果发生数据分布不均匀的情况,可以通过调整区间分布达到均匀情况,数据迁移同样会很小。
但是另外一些情况下,可能会导致连锁迁移。
情况一:数据分布不均,调整导致的连锁迁移
情况二:增加或删除节点导致的连锁迁移:
为了解决这个问题,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中。这种迁移方式的数据迁移量是理论上的最小值。
Cons:
每个节点多个区间的做法的缺点是使得对元数据的处理变得复杂,我们需要记录每个节点上面存储的所有区间。但是一般来说,每个节点上面的区间数目不是很大,
因此元数据的数目不会很大。这种同时保证了数据的最小迁移,并且实现也比较简单的方案是一个很理想的做法,虽然它的无数据管理和同步上面会有一些问题。
另外,区间划分非常适合处理有区间查询的查询语句,但是也带来很大的一个trade-off。如果一个查询需要访问到多
条元组,那么对区间的边界的选取就变得非常棘手,如果选择不当的话,很容易造成一个查询需要在多个节点上面进行运行的情况,这种跨节点的操作会对系统的性
能进行很大的影响。
当然了,对于分区划分来说,对于很多应用还是非常适合的,但是对于某些应用就非常不适合。同样上面介绍的轮流放置和一致
性哈希算法也是如此,这些算法只针对某些应用有用,我们需要一些更智能的算法来针对不同的应用选择不同的合适的算法。下一章我们会介绍几个比较智能的
sharding方案,这些方案会考虑并分析用户应用的工作流(Workload)、实际数据的特征等等从而从中得到一个比较好的方案出来。
转:http://qing.weibo.com/1814335080/6c248e6833000br2.html#
分享到:
相关推荐
#资源达人分享计划#
ShardingJdbc和达梦数据库的扩展和配置问题,ShardingJdbc和DruidDataSource、Mybatis整合的兼容、冲突问题,以及这些问题的解决方案,该demo包含测试用的创表SQL
Apache ShardingSphere 是一套开源的分布式数据库解决方案组成的生态圈。 组成部分: JDBC、Proxy 和 Sidecar(规划中)这 3 款既能够独立部署,又支持混合部署配合使用的产品组成。 功能特性:它们均提供标准化的...
分片是一种通过在多个数据库中的多个表中存储同一表的不同行来水平分区数据的方法。 这有助于增加与给定资源的连接数,并提高应用程序的读取性能。 阅读文档 有关如何在应用程序中设置分片的信息,请。 开发人员...
2.增删改查使用,分页,排序,投影,以及多种扩展使用 3.丰富查询语句,比如算术查询,等值查询,逻辑查询,数组查询,where查询,模糊查询等 4.索引创建,游标、存储过程使用 5.聚合运算,支持Group,Aggregation, ...
分片JDBC是JDBC的扩展,提供了诸如分片,读/写拆分和BASE事务之类的分布式功能。 特征 1.分片 分布式数据库中支持的聚合功能,分组依据,排序依据和限制SQL。 支持联接(内部/外部)查询。 分片运算符= ,支持...
TiDB 对业务没有任何侵入性,能优雅的替换传统的数据库中间件、数据库分库分表等 Sharding 方案。同时 它也让开发运维人员不用关注数据库 Scale 的细节问题,专注于业务开发,极大的提升研发的生产力。
生产系统随着业务增长总会经历一个业务量由小变大的过程,可扩展性是考量数据库系统高可用性的一个重要指标;在单表/数据库数据量过大,更新量不断飙涨时,MySQL DBA往往会对业务系统提出sharding的方案。既然要...
多年来致力于分布式系统架构、微服务、分布式数据库、大数据技术的研究,曾主导过众多分布式系统、微服务及大数据项目的架构设计、研发和实施落地。在高并发、高可用、高可扩展性、高可维护性和大数据等领域拥有丰富...
TiDB 对业务没有任何侵入性,能优雅的替换传统的数据库中间件、数据库分库分表等 Sharding 方案。同时 它也让开发运维人员不用关注数据库 Scale 的细节问题,专注于业务开发,极大的提升研发的生产力。
MyCat是一个开源的分布式数据库系统,它是基于MySQL协议的分布式数据库中间件,旨在提供高性能、高可用性和易扩展性的数据库解决方案。MyCat的设计目标是为了解决单一数据库服务器性能瓶颈和数据容量限制的问题,...
Apache ShardingSphere 是一个分布式SQL事务与查询引擎,能够支持数据分片、扩展、加密等功能,并且适用于任何数据库。我们社区的主导开发理念是“Database Plus”,旨在构建一个完整的生态系统,使任何数据库都能够...
语言:中文 (简体) This extension will generate the query sql with sharding role 配置数据库sharding规则,通过sharding规则方便的生成目标数据SQL。
此扩展将生成具有sharding角色的查询sql。 配置数据库sharding规则,通过sharding规则方便的生成目标数据SQL。 支持语言:中文 (简体)
核心特性全数据库全SQL兼容,完美RR等级读写分离,与原生一致的ACID特性,轻量简单易扩展另外一个轮子的意义很多人会质疑城市表面过度流行的Sharding中间件/应用层Sharing框架已经有很多,他们都已经发展了很久了,...
华为高斯数据库 Guass DB T 介绍,,支持系统高扩展,强一致的分库分表Sharding架构的数据库集群GaussDB T
分片JDBC是JDBC的扩展,提供了诸如分片,读/写拆分和BASE事务之类的分布式功能。 特征 1.分片 分布式数据库中支持的聚合函数,分组依据,排序依据和限制SQL。 支持联接(内部/外部)查询。 分片运算符= ,支持...
mongodb是一个介于nosql数据库和mysql数据库之间的一个数据存储系统,它没有严格的数据格式,但同时支持复杂查询,而且自带sharding模式和Replica Set模式,支持分片模式,复制模式,自动故障处理,自动故障转移,...
MongoDB (名称来自”humongous”) 是一个可扩展的、高性能、开源、模式自由、面向文档的数据库,集文档数据库、键值对存储和关系型数据库的优点于一身。官方站点:http://www.mongodb.org/,MongoDB特点: •面向...
看过一篇文章,学到一些东西,和大家共享! 随着互联网应用的广泛普及,海量数据的存储和访问成为了系统设计的瓶颈问题。...通过数据切分来提高网站性能,横向扩展数据层已经成为架构研发人员首选的方式。