大型网站之存储瓶颈(数据库的水平扩展)

来源:互联网 发布:q币拦截软件 编辑:程序博客网 时间:2024/05/01 17:50

原文:http://blog.jobbole.com/84180/

一、简介

数据库的水平扩展是指通过增加服务器的方式提升整个存储层的性能。
  数据库的水平扩展基本都是基于水平拆分进行的,也就是说数据库的水平扩展是在数据库水平拆分后再进行一次水平拆分,水平扩展的次数也就代表的水平拆分迭代的次数。因此要谈好数据库的水平扩展问题,我们首先要更加细致的分析下水平拆分的方案,当然这里所说的水平拆分方案指的是狭义的水平拆分。
  数据库的水平扩展其实就是让被水平拆分的表的数据跟进一步的分散,而数据的离散规则是由水平拆分的主键设计方案所决定的,在前文里我推崇了一个使用sequence及自增列的方案,当时我给出了两种实现手段,一种是通过设置不同的起始数和相同的步长,这样来拆分数据的分布,另一种是通过估算每台服务器的存储承载能力,通过设定自增的起始值和最大值来拆分数据,我当时说到方案一我们可以通过设置不同步长的间隔,这样我们为我们之后的水平扩展带来便利,方案二起始也可以设定新的起始值也来完成水平扩展,但是不管哪个方案进行水平扩展后,有个新问题我们不得不去面对,那就是数据分配的不均衡,因为原有的服务器会有历史数据的负担问题。而在我谈到狭义水平拆分时候,数据分配的均匀问题曾被我作为水平技术拆分的优点,但是到了扩展就出现了数据分配的不均衡了,数据的不均衡会造成系统计算资源利用率混乱,更要命的是它还会影响到上层的计算操作,例如海量数据的排序查询,因为数据分配不均衡,那么局部排序的偏差会变得更大。解决这个问题的手段只有一个,那就是对数据根据平均原则重新分布,这就得进行大规模的数据迁移了,由此可见,除非我们觉得数据是否分布均匀对业务影响不大,不需要调整数据分布,那么这个水平扩展还是很有效果,但是如果业务系统不能容忍数据分布的不均衡,那么我们的水平扩展就相当于重新做了一遍水平拆分,那是相当的麻烦。其实这些还不是最要命的,如果一个系统后台数据库要做水平扩展,水平扩展后又要做数据迁移,这个扩展的表还是一个核心业务表,那么方案上线时候必然导致数据库停止服务一段时间。

数据库的水平扩展本质上就是水平拆分的迭代操作,换句话说水平扩展就是在已经进行了水平拆分后再拆分一次,扩展的主要问题就是新的水平拆分是否能继承前一次的水平拆分,从而实现只做少量的修改就能达到我们的业务需求。

二、水平扩展和数据迁移
  对于数据库,我们所做的水平拆分的主键设计方案都是基于一个平均的原则进行的,如果新的服务器加入后就会破坏数据平均分配的原则,为了保证数据分布的均匀我们就不能不将数据做相应的迁移。这个问题推而广之,就算我们水平拆分没有过分强调平均原则,或者使用其他维度来分割数据,如果这个维度在水平扩展时候和原库原表有关联关系,那么结果都有可能导致数据的迁移问题,因此水平扩展是很容易产生数据迁移问题。

对于一个实时系统而言,核心的业务表发生数据迁移是一件风险很大成本很高的事情,抛开迁移的操作危险,数据迁移会导致系统停机,这点是所有系统相关方很难接受的。那么如何解决水平扩展的数据迁移问题了,那么这个时候一致性哈希就派上用场了,一致性哈希是固定哈希算法的衍生,下面我们就来简单介绍下一致性哈希的原理,首先我看看如下图

图1-1


一致性哈希使用时候首先要计算出用来做水平拆分服务器的数字哈希值,并将这些哈希值配置到0~232的圆上,接着计算出被存储数据主键的数字哈希值,并把它们映射到这个圆上,然后从数据映射到的位置开始顺时针查找,并将数据保存在找到的第一个服务器上,如果主键的哈希值超过了232,那么该记录就会保存在第一台服务器上。这些如图1-1。

那么有一天我们要添加新的服务器了,也就是要做水平扩展了,如上图的第二张图,新节点(图上node5)只会影响到的原节点node4,即顺时针方向的第一个节点,因此一致性哈希能最大限度的抑制数据的重新分布。


上面的例图里我们只使用了4个节点,添加一个新节点影响到了25%左右的数据,不过一致性哈希上的分布节点越多,那么添加和删除一个节点对于总体影响最小。

在图1-2中,添加节点node5后,其实只想减少了节点node4压力,并没有为其他节点分流减压,各节点负载不平衡。另外,对于节点数量比较少时,节点的hash分布可能会非常不均匀,继而造成负载不平衡。要取得比较好的负载均衡的效果,往往在服务器数量比较少的时候需要增加虚拟节点来保证服务器能均匀的分布在圆环上。因为使用一般的hash方法,服务器的映射地点的分布非常不均匀。使用虚拟节点的思想,为每个物理节点(服务器)在圆上分配100~200个点。这样就能抑制分布不均匀,最大限度地减小服务器增减时的缓存重新分布。用户数据映射在虚拟节点上,就表示用户数据真正存储位置是在该虚拟节点代表的实际物理服务器上。

关于此的更多内容请参考《memcache的一致性hash算法使用

三、水平扩展与数据排序

当我们要做水平扩展时候肯定有个这样的因素在作怪:数据量太大了。前文里我说道过海量数据会对读操作带来严重挑战,对于实时系统而言,要对海量数据做实时查询几乎是件无法完成的工作,但是现实中我们还是需要这样的操作,可是当碰到如此操作我们一般采取抽取部分结果数据的方式来满足查询的实时性。

0 0
原创粉丝点击