三英战SQL:解析NoSQL的可靠性及扩展操作

14 篇文章 0 订阅
摘要:NoSQL的高性能、易扩展及可靠性一直深受数据工作者的喜爱,然而对比传统关系型数据库NoSQL的优势究竟又在何处。Esen Sagynov在DZone上发布了一篇文章,从运行方面分析Cassandra,HBase以及MongoDB产品的扩展性和可靠性;详述了3个NoSQL数据库在故障恢复中的性能和可靠性,更谈及了扩展过程中带来的性能影响。

对比关系型数据库,NoSQL的优点在哪里?NoSQL具有高性能、良好的扩展性以及高可靠性等优点。然而,没有一个产品可以在所有的方面都达到完美。当你仔细审视NoSQL的产品,完全可以找到一些弱点,就像那些杰出的优点一样“鲜明出众”。基于此原因,选择经过验证的NoSQL产品就是关键。在本文中,作者从运行方面分析Cassandra,HBase以及MongoDB等产品的扩展性和可靠性。

Cassandra故障恢复以及数据一致性

Cassandra在数据的分布式和可靠性方面展示了自身卓越的性能。首先,作者检测了它的分布能力,Cassandra通过一致性哈希算法来实现数据的分配处理。

Cassandra的一致性哈希算法

通过一致性哈希算法,用户可以不经过查询元数据就能搜索并发现key存储在哪个节点上。用户通过计算key的哈希值就能发现key,同样只通过Hash值就可以找到节点所在。你可以想像一致性哈希被作为哈希值顺序的放在圆环上,每个节点处理环上的一个部分。如果环上增加了一个节点,那么某个拥有很大体积数据的特定节点就会被拆分然后分配给新的节点;如果某个节点被移除,分配给该节点的资源就会转移到邻节点上。利用这种方式,Cassandra使增加或者移除节点带来的影响降到了最小。

Cassandra的运行中不需要主服务器,换句话说:并没有特定的服务器来管理数据的分配或者故障恢复。这就意味着,Cassandra并不存在单点故障(Single Point Of Failure,SPoF)。取代主服务器,每个节点都和其他节点周期性地分享元数据,这个也被称之为Gossip协议。使用Gossip协议,节点可以对其他节点的运行状态进行查询。

Cassandra通过提供一致性级别来实现系统的可靠性。如果使用一个很低的一致性级别,即使一个节点宕掉也可能导致整个服务的停滞。例如,3个节点中的某一个节点在存储副本数据的过程中宕掉了,一个通用的写操作,就不能立刻返回成功信息,这是因为故障节点不能完成写入数据的请求。然而,如果一致性级别被定义成一个约定值或者是1,而存活的节点数大于或者等于设定值,这样的话就能立刻返回成功。如果是这样的话,只有在所有的3个节点都同时宕掉,才会发生请求错误。

但是,读/写操作真的没有受到节点出错的影响吗?

为了证明这点,当有新节点添加时,作者在不断的服务器请求下故意让一个节点发生故障。结果如下所示:

移除一个节点和增加一个新的节点

以下是移除一个节点和增加一个新的节点的结果:

  1. 在管理工具中明确移除一个节点,存储在此节点中的数据就被迁移到剩余的节点中,然后该节点被移除。
  2. 当一个新节点被增加,这个被称之为引导指令,增加的节点就会向种子节点(seed nodes)报告它已经添加完毕。基于配置信息,新节点会被添加在环上配置信息中指定的范围,或者环上资源被占用最高的节的附近—— 当然这是在没有其它节点被引导在这个范围上。
  3. 数据从那个节点迁移到到新节点上。
  4. 一旦数据迁移进程结束,新节点就能进行使用。

节点失败后增加一个新节点

下面是节点失败后新增节点的结果:

  1. 当一个节点宕掉之后,存储在节点上的数据并没有迁移到其他的节点上,服务在于两个副本(节点)共舞。换句话说,并没有返回任何错误信息,即使在这段时间里又收到服务请求。
  2. 当一个新节点被增加的时候,该节点会被分配到环上的一个特定区域。然而,引导指令并没有执行,因为引导指令只有系统中存在3份副本的时候才会被执行!
  3. 新增的节点并没有数据,但是它能处理请求,这是因为它可以提供服务。如果此时接受到一个读请求,节点并不会对key返回数据。如果备份因子是3而读一致性的级别是1,那么1/3的读请求可能不会返回数据。如果一致性级别被设置为约定值,1/6的读请求可能会返回空数据。简单来讲,这没有读一致性的保证,除非故障节点已经恢复。实际上在级别1中,协调节点是最有可能第一个接受来自新节点的响应。出现这种情况是因为没有来自新节点的I/O请求——因为它没有数据。出于这个原因,新的节点比现有节点有更大的机率返回空数据。
  4. 当通过管理工具对新节点做Read Repair时,节点通过读其他节点的同步数据才能得以建立。此时读一致性就被破坏了,只到Read Repair完成。

即使节点失败,Cassandra也能提供无错的服务。尽管Cassandra在写数据的时候,展示了自身强大的性能,但是在读数据的时候并非如此,因为Read Repair的延迟必然导致数据的非一致性的延迟。因此,为了在节点故障中保持读一致性,需要使用以下的方法:

  • 设置读一致性水平为“all”然后执行读操作。在这种情况下,就能获得所有来自副本的最新数据。
  • 一旦读请求失败,Cassandra会再次进行尝试。这是因为在第一次读写的时候Read Repair可能会作为第二次读写时的恢源数据源。然而,这种方法能确保Rread Repair在二次读之前完成。(当一致性的水平较低,那么读修复就会在后台执行,这是一个独立的线程,区别于读操作过程的线程)

HBase的失败因子和恢复方法

HBase包含以下几个组件:

HRegionServer负责数据的分布处理,由HMaster进行监控。HDFS存储和复制数据,Zookeeper存储了HMaster以及备选HMaster的储存单元信息。如果没有为每个组件建立冗余,所有的组件都会成为SPoF。

HRegionServer主要负责响应用户I/O请求,向HDFS文件系统中读写数据,是HBase中最核心的模块。HRegionServer内部管理了一系列HRegion对象,每个HRegion对应了Table中的一个Region,HRegion中由多个HStore组成。每个HStore对应了Table中的一个Column Family的存储,可以看出每个Column Family其实就是一个集中的存储单元,因此最好将具备共同IO特性的column放在一个Column Family中,这样最高效。(百度百科)

HRegionServer把数据分布到一些称之为“region”的单元中,region就是将一张大表格通过指定字段对数据进行排序,然后针对排序键的范围拆分出的结果(就像大表中的一小块)。每个region排序字段的值范围存储在一个单独的region中,被称为meta region。而region和meta region的对应关系被存储在root region中。长话短说,region服务器存储着一个层次树中,包含了root region、meta region以及data region。如果一个region服务器宕机,这个region服务器包含的region都不可以被访问直到被分配给了其它region服务器。因此产生了服务器宕机时间,直到那个region被恢复。

如果是这种情况,宕机的时间能持续多久?

下面我们来估计一下故障恢复中的宕机时间。

在一个region的服务器上如果有故障产生,数据恢复会按照以下描述的步骤进行:

  1. HMaster检测故障点,然后找出一个其他的服务器来执行故障服务器上的服务。
  2. 指定的HRegionServer首先读取新region上的WAL(Write Ahead Log),然后恢复该region上的MemStore。
  3. 一旦MemStore完成恢复,HMaster修正meta region中region存储的位置,并重启该region上的服务。
  4. 存储在磁盘上的region数据将会通过HDFS进行恢复。

总之,故障的恢复时间取决于故障的检测、读日志以及创建一个新的region的时间。因为分配给恢复region的服务器可以访问存储在HDFS中的文件,所以在HDFS中不会发生数据迁移。因此,宕机时间并不是不长。

HDFS故障

HDFS包含一个NameNode和几个DataNode,在这里,NameNode是存储元数据的节点。所以当NameNode宕掉,服务就会出现问题。然而,如果其中的DataNode宕掉了,服务是不会受影响的,这是因为这些数据都拥有副本。但是存储在故障节点中的数据,将通过其他节点中的复制因子来恢复正常。在这个时候,一个巨大的数据复制可能会发生,从而减缓了任何来自服务或者是应用程序的任何读请求,这是由于受到数据复制过程中的磁盘I/O影响。

MongoDB中的复制和故障恢复

MongoDB从主节点给其它从节点异步复制数据。异步复制的好处是不会降低主节点的性能,这样的话在添加从节点的时候也不会降低服务的性能。然而在发放生故障时数据将会丢失,因为数据是不一致的。

MongoDB的故障恢复和DBMS的HA是很相似的。在产生故障时,它也是选择一个master,我们来分开讨论一下:

节点故障

配置三个节点,一个主节点和两个从节点。一旦主节点停止,两个从节中将会自动的选取出一个作为主节点。当故障发生时,选择一个新的主节点的时间仅仅只需要几秒钟,这段时间并不算很久。然而,配置的主节点宕掉,然后选择作为主节点的从节点也宕掉了,就没有主节点可选了!

添加一个节点

向主节点中输入数据,确认数据的大小是5GB,这要保证比内存的容量小。接下来,添加一个新的slave节点到主节点上,在这种情况下,新增的从节点并不会降低主节点的性能,而新增一个从节点复制所有数据的时间只需要几分钟。

而对MongoDB来说,由于故障或者增加节点带来的性能降低是非常小的。然而当主节点和从节点的备份信息是不一致的,一旦主节点出现故障 —— 那些还没有复制到从节点中的数据有可能会丢失。在MongoDB中,主节点将操作记录写入本地服务器的Oplog日志中,然后从节点读取日志并且储存在自己的数据库中。如果在故障发生时从节点仍然未完成日志读取并保存,未经读取的数据将会丢失。此外,即使主节点的日志已满,但是从节点还未完成文件的复制,所有主节点的数据都被读取并存入从节点,而不是复制到日志中。这被称为数据同步。如果上面这种情况发生主节点故障,那么大量的数据将会丢失。

结论:

到现在为止,作者对Cassandra, HBase以及MongoDB的故障恢复逐一做了论述。

Cassandra提供高可用性的写操作,然而,它需要很长时间来从一个失败中恢复数据。这是因为Cassandra识别要恢复的所有数据,然后读和写每个数据的最新版本。它还因在响应服务请求添加新节点时,仍在恢复数据,导致错误的读取结果返回。此外,Read Repair会在读取数据用以恢复的时候运行两次。尽管它在新节点添加同时发生节点失败会有相对处理,但是如果在数据恢复之前进行读取仍然会返回错误的结果。因此一致性等级的性能不被提高,它仍然不能用于需要读操作的服务。

由于它的配置问题,HBase自身存在很多因素可能导致问题的产生。不过对比Cassandra节点失败时必须进行数据的恢复,HBase却不需要恢复数据,除非HDFS出现问题。这样HBase宕机时间就会很短,即使HDFS出现问题宕机时间也不会很长。虽然读性能在数据的恢复过程中会受到影响,但是数据的一致性完全可以得到保证。用这种方式,如果SPoF部分成为冗余,我们将从HBase获得很高的可靠性。

MongoDB提供了一个自动故障恢复并且发生宕机的时间很短。然而,异步复制方式在故障恢复的过程中很容易造成数据的丢失。

当然,在最终选择适合自己的数据库解决方案之前,应该对比每个产品的特点。举个例子,CUBRID 关系型数据库系统,为数据的一致性提供了同步的高可用性体系,虽然没有数据的丢失问题,但是它远远比不上NoSQL解决方案的性能。(编译/王鹏、仲浩 审校/包研)

原文链接:The Availability and Operational Stability of NoSQL

欢迎关注@CSDN云计算微博,了解更多云信息。

本文为CSDN编译整理,未经允许不得转载。如需转载请联系market@csdn.net

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值