HBase概念学习(十)HBase与MongDB等NoSQL数据库对照

转载请注明出处: jiq•钦 's technical Blog - 季义钦

一、开篇

淘宝之前使用的存储层架构一直是 MySQL 数据库,配合以 MongDB,Tair 等存储。

MySQL 因为开源,而且生态系统良好,本身拥有分库分表等多种解决方式,因此非常长一段时间内都满足淘宝大量业务的需求。可是因为业务的多样化发展,有越来越多的业务系统的需求開始发生了变化。一般来说有下面几类变化:

(1)    数据量变得越来越多,其实如今淘宝差点儿不论什么一个与用户相关的在线业务的数据量都在亿级别,每日系统调用次数从亿到百亿都有,且历史数据不能轻易删除。这须要有一个海量分布式文件系统,能对 TB 级甚至 PB 级别的数据提供在线服务。

(2)    数据量的增长非常快且不一定能准确估计,大多数应用系统从上线起在一段时间内数据量都呈非常快的上升趋势,因此从成本的角度考虑对系统水平扩展能力有比較强烈的需求,且不希望存在单点制约。

(3)     仅仅须要简单的 kv 读取,没有复杂的 join 等需求。

(4)     对系统的并发能力以及吞吐量、响应延时有很高的需求,并希望系统能保持强一致性。

(5)    通常系统的写入很频繁,尤其是大量系统依赖于实时的日志分析。

(6)    希望可以高速读取批量数据(HBase 基于行健存储的优势)。

(7)    schema 灵活多变,可能常常更新列属性或新增列。

(8)    希望可以方便使用,有良好且语义清晰的java 接口。

 

以上需求综合在一起,我们觉得 hbase 是一种比較适合的选择。

1、首先它的数据由 hdfs 天然地做了数据冗余,云梯三年的稳定执行,数据 100% 可靠己经证明了 hdfs 集群的安全性,以及服务于海量数据的能力。

2、其次 hbase 本身的数据读写服务没有单点的限制,服务能力能够随 server 的增长而线性增长,达到几十上百台的规模。

3、LSM-Tree 模式的设计让 hbase 的写入性能很良好,单次写入通常在 1-3ms 内就可以响应完毕,且性能不随数据量的增长而下降。

4、region(相当于数据库的分表)能够 ms 级动态的切分和移动,保证了负载均衡性。

5、因为 hbase 上的数据模型是按 rowkey 排序存储的,而读取时会一次读取连续的整块数据做为 cache,因此良好的 rowkey 设计能够让批量读取变得十分 easy,甚至仅仅须要1次 IO 就能获取几十上百条用户想要的数据。

6、最后,淘宝大部分 project 师是 java 背景的同学,因此 hbase 的 api 对于他们来说很 easy 上手,培训成本相对较低。 

 

这个问题足以说明,Hbase 相对于 MongDB 拥有上面讲到的那几点优势。

另外 FaceBook 是 Hbase 眼下的最大的用户,其抛弃了自创的终于一致性数据库 Cassandra 而选择了 Hbase。http://wiki.apache.org/hadoop/Hbase/PoweredBy页面也罗列出了非常多当前正在使用 HBase 的大用户。

 

二、NoSQL 数据库特点

1、 MongDB 特点:

(1) MongDB 是文档存储,文档按组又分成集合。集合类似于关系数据库中的表,只是不同

的是其不正确 Schema 进行严格约束,即一个集合能够包括不论什么文档。

文档以 BSON 格式存在,这是一种 JSON 类文档的二进制编码格式,结构类似于嵌套的键值对,每一个文档都有一个唯一的标识。

(2) MongDB 选择用内存映射文件存储,所以能够通过提供更大的 RAM 或者分配更大的虚拟内存能够提升 MongDB 的性能,能够看出高性能是贯穿 MongDB 设计的一个重要理念。

(3) 限制:由于採用内存映射文件存储,所以 32 位系统上数据库的最大值不能超过 2G。此外单个文档不能超过 16M,说明不适合存储大对象。另一个 MongDB 数据库最多仅仅能存储 8000 个集合。这些约束都限制了 MongDB 数据库的无限增长。

(4) 原子性:MongDB 并不注重原子性,也未定义并发操作中事物完整性和隔离级别,因此在更新同一个集合时,两个进程可能相互冲突。仅仅有一类成为 Modifier Operation 的操作 (主要有累加字段、设定字段值、删除字段等操作) 才提供原子性。而 Hbase 和 Hypertable 等列式数据库提供行级的原子更新和一致性状态。

(5) 水平拓展:选用 MongDB 一个常见的原因是弱 Schema 集合,另一个原因就是其良好的性能和可拓展性,近期的版本号中 MongDB 開始支持自己主动分片,其支持将集合分开保存到多台机器上,每台机器保存一部分,即一个分片,故障转移通过复制分片来实现,这使得水平拓展变得 easy 了很多。

(6) 支持很丰富的查询、支持各种索引、支持各种聚合函数、支持排序,总之拓展了关系型数据库的很多实用的功能。

(7) 和 Mapreduce 结合不是非常好、当数据规模增大时,稳定性不够好。

尽管 MongDB 是一种 NoSQL 数据库,可是因为本身的一些特性和实际行业中的使用经验表明,MongDB 更像是介于 NoSQL 数据库和内存数据库之间的一种数据库。

 

2、 Hbase 特点:

Facebook 是 Hbase 的最大用户,以下是我从 SIGMOD2011 上 facebook 发表的一篇论文翻译而来,具体说明了他们为什么选择 Hbase。

Facebook 主要给出了三类应用场景:Facebook Messaging、Facebook Insight 和 FacebookMetrics System(ODS)。Messaging 就是 Facebook 的新型消息服务,每个月存储 1350 亿条消息。Insight 是提供给开发人员和站点拥有者的数据分析工具,能够帮助他们清楚了解到訪问者怎样与他们站点交互,以便更好地优化他们的服务。ODS 则是 Facebook 内部的软硬件状态统计系统,对于每个或者一组 server,都能够有效地从不同的维度来监控他们的状态。这三个应用场景都有各自的特色,但简单地来说,面临的问题是相同的:单机或者拆分的关系型数据库无法满足需求。

 

Facebook 选择 Hadoop/Hbase 的主要原因有下面几点:

1、可拓展性:可以以最小的代价、无须停机的方式添加存储系统的容量。一些情况下我们须要高速添加系统的容量,而且可以自己主动负载、利用到这些新的硬件设备。

2、高写入吞吐量:大多数应用都须要存储巨大量的数据,这就要求非常高的写入吞吐量。

3、单个 data center 内高性能、低延迟的强一致性:一些重要的应用、比方消息、要求非常强的单个数据中心内的一致性,这些需求非常直观来自于用户需求,比方展示在主页的“未读消息”的数目和 inbox 页面显示的消息就应当是高度一致的。虽然全局强一致性的分布式系统差点儿是不可能的,可是一个系统至少可以提供在单个数据中心内的强一致性,这可以带来非常好的用户体验。

4、高效的随机读取性能:虽然应用层的缓存技术 (无论是嵌入式的还是 memcached 方式) 被广泛应用,可是非常多訪问仍然没办法命中缓存,须要后端的存储系统来处理,Hbase 随机读取性能非常稳定。MySQL 在随机读取方面非常优秀,但假设 Hbase 结合分布式缓存 MemeCached 或者 MemBase,那么其读取性能就能够和 MySQL 比肩了。

5、高可用性以及灾难恢复:我们须要提供给用户高度可用的服务,无论是遇到计划中的事件(比方软件升级、或者硬件 / 容量的添加),还是遇到一些计划之外的事件(比方硬件失效)。我们也须要可以容许数据中心的一些数据丢失,可以在合理的时间范围内切换到其它数据中心来为用户提供服务。

6、故障隔离:我们在大量的 MySQL 数据库上的应用经验表明,故障隔离是非常关键的。单个数据库能够 down 掉,可是仅仅仅有非常小一部分用户会被这种事件影响。类似地,在我们的 Hadoop 存储中,单个磁盘故障仅仅仅会影响到一小部分数据,并且系统能够非常快恢复。

7、原子的“读 - 改动 - 写”原语:原子的计数器和检查并设置 (checkand set、或者称 compare and swap) 等 API 在构建无锁的并发应用时非常实用,能够帮助用户有效地解决多线程竞争造成的非常多问题。

8、范围扫描:一些应用要求特定范围内的行的集合的高效检索。比如,给定用户的近期 100 条消息的检索。

 

FaceBook 对 HDFS 做了一些优化:

HDFS 最初是被设计为支持一些离线 Mapreduce 应用的批处理文件系统,在可拓展性和批量数据处理方面非常优秀,基于一些实时性的需求,faceBook 对 HDFS 进行了优化,目的是为了将其打造为更加通用的、低延迟的文件系统。主要优化包含:

(1)    将单节点的 NameNode 改为双节点的热备份。只是 Facebook 觉得这个不是非常重要,他们的 HDFS 集群四年来 NameNode 仅仅出过一次问题,还是由于什么交易日志存储在错误的地方。

(2)    RPC 的优化。

 

FaceBook 对 Hbase 也做了一些优化:

(1)    行级原子性、系统可用性的优化。个人看了一下,仅仅能佩服 faceBook。

(2)    性能优化主要从两点进行,一个是 compaction 性能,还有一个是读性能。

读过 BigTable 论文的应该对其 memtable 和 compaction 的特性比較熟悉。这里主要讨论了让 minor compaction 也删除数据的优点,以及怎样做 major compaction 可以提高合并的性能。在数据读性能方面,文章里主要讨论了降低 IO 操作的方法,当中包含 bloom filter和特定类型 meta 信息(时间戳)的使用。还有非常重要的一点,在部署上保持 RegionServer 和物理文件的局部性!

 

Hbase 主要适用场景:

1 大数据量 (100s TB 级数据) 且有高速随机訪问的需求。

比如淘宝的交易历史记录。数据量巨大无容置疑,面向普通用户的请求必定要即时响应。

2 容量的优雅扩展

大数据的驱使,动态扩展系统容量的必须的。比如:webPage DB。

3 业务场景简单,不须要关系数据库中非常多特性(比如交叉列、交叉表,事务,连接等等)

4 优化方面:合理设计 rowkey。由于 hbase 的查询用 rowkey 是最高效的,也差点儿的唯一生产环境可行的方式。所以把你的查询请求转换为查询 rowkey 的请求吧。

 

HBase 在淘宝的应用

个人感觉是最精华的部分,HBase 在淘宝里用在三个地方:

a)  实时推荐、实时报表、实时计费

这类应用的特点是大量数据的实时写入以及读取

b)  大数据量类型项目

比方历史类或须要长期保存的数据

c)  二次分析类型项目

Hadoop 集群做粗粒度分析,在线做二次分析,比方数据魔方。

 

三、NoSQL 数据库对照

1、 可拓展性

尽管全部 NoSQL 数据库都承诺可拓展性,可是面对挑战是水平却不尽同样。

BigTable 的相似产品 Hbase 和 Hypertable 临时处于率先地位,内存存储 (Membase 或 Redis) 和文档数据库 (MongDB 或 CouchBase) 紧随其后,他们之间的差异随着数据量的增大而被无限放大,特别是到了 PB 级以后。

拓展性方面 Hbase 具备天生的优势,支持自己主动负载均衡,故障转移,压缩和单 server 多分片,并且 Hbase 和 HDFS 配合的很好,HDFS 可以通过复制和自己主动平衡轻松容纳跨越多个 server 的大文件。

所以所假设须要极端拓展性的话,列族 NoSQL 是最好的选择。

可是话又说回来,假设你的大量数据会以惊人的快节奏出现,比如一些实时的交易数据或者广告点击追踪数据,那么单靠列式存储无法提供完美的解决方式。这个时候你须要一些更加轻快、既支持高速读写、又支持实时处理的存储,没有什么比在内存里面处理数据更快了,所以你能够在 Hbase 前面搭配上 MongDB/Redis 来进行实时数据处理以及实时的数据挖掘等。其它一些实时性不是很高的批量查询和数据挖掘能够利用 Mapreduce 在 Hbase 上进行。

 

2、 事务完整性和一致性

Hbase 和 Hypertable 提供行级的原子更新以及一致性状态,MongDB 提供文档级别的原子更新,Cassandra 仅仅能提供终于一致性。

可是事务的要求并非必须的,很多数据,比方网络流量日志,社交网络状态更新 (微博等),广告点击,道路交通数据,交易数据和游戏分数等是一次写、多次读,这种数据对事务的需求有限,甚至没有。

有些数据尽管已更新和删除,可是改动通常仅仅限于单记录而非数据集的某个范围,有时更新非常频繁且涉及范围操作。假设范围操作非经常见而且须要保持更新的一致性,那么 RDBMS 才是最佳选择,假设单个条目的原子性已经足够,那么列式数据库、文档数据库和部分键 / 值存储都能够。假设须要事务完整性可是能够容纳临时的窗体不一致,那么终于一致性存储也是不错的选择。

 

3、 数据模型

MongDB 支持类 SQL 查询、主要的关系型引用和数据库对象,假设使用 NoSQL 的主要原因是能够使用宽松的数据结构,那么 MongDB 肯定是開始使用 NOSQL 的最佳选择。

非常多 Web 为中心的业务都開始使用 MongDB,主要是由于它支持灵活的数据模型 (弱 Schema),同一时候可以提供高速的读写能力。(如今敏捷开发非常重要、MongoDB 能更快地开发应用程序。一个明显的原因是 MongoDB 没有固定的 Schema,全部花在提交、沟通和实施 Schema 变更的时间都省下来了)

此外 MongDB 对 Web 框架的支持很好,比方 Spring、Rails 等。

最后要说明的是,MongDb 非常 easy 上手,学习周期非常短。

 

4、 查询支持

挑选 NoSQL 主要考虑的因素除了存储,还有查询。

MongDB 和 Redis 的查询能力比較强。

像 MongDB 的查询,与 SQL 相似,语法简单,easy 学习。MongoDB 支持范围查询,正則表達式查询,对子文档内属性的查询,能够代替原来大多数任务的 SQL 查询。

像 Redis 的查询,查询方法非常全,命令文档也非常丰富。

Hbase 仅仅支持基于 Rowkey 的单条记录查找、基于 Rowkey 的范围查找以及全表扫描。

要注意的是差点儿全部 NoSQL 存储都不支持表之间的 join 操作。

提到查询不得不提到索引,MongDB 本身支持二级索引,Hbase 不支持二级索引,可是如今也有非常多方法 (最常见是借助协处理器) 能够帮助 Hbase 实时建立二级索引。

 

5、 性能

(1)    50/50 读和更新、即读少写多。

Cassandra 最棒,每秒运行超过 1W 次操作,平均读延迟仅仅有 25ms、更新性能更好仅仅有 10ms。

Hbase 紧随其后。至于 MySQL,每秒运行 4000 左右操作的时候才和上面两个有可比性,超过 5000 之后延迟迅速攀升。

(2)    95/5 读和更新、即读多写少。

还是 Cassandra 最棒。

列式存储连续范围的读取性能很优秀,这证明和 Hbase 批量读写的性能很好。

Hbase 表现很稳定,与每秒操作数无关,5% 的更新在 Hbase 里面差点儿没有延迟。

仅仅读情况下 MySQL 性能最好,可能与缓存有关。

假设结合分布式缓存 MemeCached 或者 MemBase,那么 Hbase 的读取性能就能够和 MySQL 比肩了。

 

四、选择 NoSQL 存储须要考虑的维度

1、Data model(数据模型). Thereare many variations of how the data is stored, which include key/value stores(compare to a HashMap), semi-structured, column-oriented stores, anddocument-oriented stores. How is your application accessing the data? Can theschema evolve over time?

2、Storage model(存储模型).In-memory or persistent? This is fairly easy to decide on since we arecomparing with RDBMSs, which usually persist their data to permanent storage,such as physical disks. But you may explicitly need a purely in-memorysolution, and there are choices for that too. As far as persistent storage isconcerned, does this affect your access pattern in any way?

3、Consistency model(一致性模型).Strictly or eventually consistent? The question is, how does the storage systemachieve its goals: does it have to weaken the consistency guarantees? Whilethis seems like a cursory question, it can make all the difference in certainuse-cases. It may especially affect latency, i.e., how fast the system canrespond to read and write requests. This is often measured harvest and yield.

4、Physical model(物理模型).Distributed or single machine? What does the architecture look like - is itbuilt from distributed machines or does it only run on single machines with thedistribution handled client-side, i.e., in your own code? Maybe the distributionis only an afterthought and could cause problems once you need to scale thesystem. And if it does offer scalability, does it imply specific steps to doso? Easiest would be to add one machine at a time, while sharded setupssometimes (especially those not supporting virtual shards) require for eachshard to be increased simultaneously because each partition needs to be equallypowerful.

5、Read/writeperformance(读写性能). You have to understand what your application's access patternslook like. Are you designing something that is written to a few times, but readmuch more often? Or are you expecting an equal load between reads and writes?Or are you taking in a lot of writes and just a few reads? Does it supportrange scans or is better suited doing random reads? Some of the availablesystems are advantageous for only one of these operations, while others may dowell in all of them.

6、Secondary indexes(二级索引).Secondary indexes allow you to sort and access tables based on different fieldsand sorting orders. The options here range from systems that have absolutely nosecondary indexes and no guaranteed sorting order (like a HashMap, i.e., youneed to know the keys) to some that weakly support them, all the way to thosethat offer them out-of-the-box. Can your application cope, or emulate, if thisfeature is missing?

7、Failure handling(失败处理). It isa fact that machines crash, and you need to have a mitigation plan in placethat addresses machine failures (also refer to the discussion of the CAPtheorem in Consistency Models). How does each data store handle server failures?Is it able to continue operating? This is related to the "Consistencymodel" dimension above, as losing a machine may cause holes in your datastore, or even worse, make it completely unavailable. And if you are replacingthe server, how easy will it be to get back to 100% operational? Anotherscenario is decommissioning a server in a clustered setup, which would mostlikely be handled the same way.

8、Compression(压缩). Whenyou have to store terabytes of data, especially of the kind that consists ofprose or human readable text, it is advantageous to be able to compress thedata to gain substantial savings in required raw storage. Some compressionalgorithms can achieve a 10:1 reduction in storage space needed. Is thecompression method pluggable? What types are available?

9、Load balancing(负载均衡). Giventhat you have a high read or write rate, you may want to invest into a storagesystem that transparently balances itself while the load shifts over time. Itmay not be the full answer to your problems, but may help you to ease into ahigh throughput application design.

10、AtomicRead-Modify-Write(原子读改动写操作). While RDBMSs offer you a lot of these operations directly (becauseyou are talking to a central, single server), it can be more difficult toachieve in distributed systems. They allow you to prevent race conditions in multi-threadedor shared-nothing application server design. Having these compare and swap(CAS) or check and set operations available can reduce client-side complexity.Locking, waits and deadlocks It is a known fact that complex transactionalprocessing, like 2-phase commits, can increase the possibility of multipleclients waiting for a resource to become available. In a worst-case scenario,this can lead to deadlocks, which are hard to resolve. What kind of lockingmodel does the system you are looking at support? Can it be free of waits andtherefore deadlocks?


附上一些实用的网址:

MongDB 介绍: http://www.csdn.net/article/2012-11-15/2811920-mongodb-quan-gong-lue

NOSQL 数据库对照: http://vschart.com/compare/hbase/vs/mongodb

几种 NoSQL 性能对照: http://www.jdon.com/46128


參考

1、淘宝的应用场景和优化:http://blog.csdn.net/jiyiqinlovexx/article/details/29260677

2、淘宝大数据的相关 PPT。

3、Facebook 的论文。

4、HBase 权威指南。