|
最近在网上又看到有关于 Hadoop 适用性的讨论 [1] 。想想今年大数据技术开始由互联网巨头走向中小互联网和传统行业,估计不少人都在考虑各种“纷繁复杂”的大数据技术的适用性的问题。这儿我就结合我这几年在 Hadoop 等大数据方向的工作经验,与大家讨论一下 Hadoop 、 Spark 、 HBase 及 Redis 等几个主流大数据技术的使用场景(首先声明一点,本文中所指的 Hadoop ,是很“狭义”的 Hadoop ,即在 HDFS 上直接跑 MapReduce 的技术,下同)。
我这几年实际研究和使用过大数据(包含 NoSQL )技术包括 Hadoop 、 Spark 、 HBase 、 Redis 和 MongoDB 等,这些技术的共同特点是不适合用于支撑事务型应用,特别是与“钱”相关的应用,如“订购关系”、“超市交易”等,这些场合到目前为止还是 Oracle 等传统关系型数据库的天下。
1. Hadoop Vs. Spark
Hadoop/MapReduce 和 Spark 最适合的都是做离线型的数据分析,但 Hadoop 特别适合是单次分析的数据量“很大”的情景,而 Spark 则适用于数据量不是很大的情景。这儿所说的“很大”,是相对于整个集群中的内存容量而言的,因为 Spark 是需要将数据 HOLD 在内存中的。一般的, 1TB 以下的数据量都不能算很大,而 10TB 以上的数据量都是算“很大”的。比如说, 20 个节点的一个集群(这样的集群规模在大数据领域算是很小的了),每个节点 64GB 内存(不算很小,但也不能算大),共计 1.28TB 。让这样规模的一个集群把 500GB 左右的数据 HOLD 在内存中还是很轻松的。这时候,用 Spark 的执行速度都会比 Hadoop 快,毕竟在 MapReduce 过程中,诸如 spill 等这些操作都是需要写磁盘的。
这儿有 2 点需要提一下: 1 )一般情况下,对于中小互联网和企业级的大数据应用而言,单次分析的数量都不会“很大”,因此可以优先考虑使用 Spark ,特别是当 Spark 成熟了以后( Hadoop 已经出到 2.5 了,而 Spark 才刚出 1.0 呢)。比如说,中国移动的一个省公司(在企业级,移动公司的数据量还是算相当大的),他们单次分析的数量一般也就几百 GB ,连 1TB 都很少超过,更不用说超过 10TB 了,所以完全可以考虑用 Spark 逐步替代 Hadoop 。 2 )业务通常认为 Spark 更适用于机器学习之类的“迭代式”应用,但这仅仅是“更”。一般地,对于中等规模的数据量,即便是不属于“更适合”范畴的应用, Spark 也能快 2 ~ 5 倍左右。我自己做过一个对比测试, 80GB 的压缩数据(解压后超过 200GB ), 10 个节点的集群规模,跑类似“ sum+group-by ”的应用, MapReduce 花了 5 分钟 ,而 spark 只需要 2 分钟 。
2. HBase
对于 HBase ,经常听到的一个说法是: HBase 只适合于支撑离线分析型应用,特别是做为 MapReduce 任务的后台数据源。持这个观点不少,甚至在国内一个响当当的电信设备提供商中, HBase 也是被归入数据分析产品线的,并明确不建议将 HBase 用于在线应用。可实际情况真是这样吗?让我们先看看它的几大案例: Facebook 的消息类应用,包括 Messages 、 Chats 、 Emails 和 SMS 系统,用的都是 HBase ;淘宝的 WEB 版阿里旺旺,后台是 HBase ;小米的米聊用的也是 HBase ;移动某省公司的手机详单查询系统,去年也由原先的 Oracle 改成了一个 32 节点的 HBase 集群——兄弟们,这些可都是知名大公司的关键应用啊,够能说明问题了吧。
实际上从 HBase 的技术特点上看,它特别适用于简单数据写入(如“消息类”应用)和海量、结构简单数据的查询(如“详单类”应用)。在上面提到的 4 个 HBase 的应用中, Facebook 消息、 WEB 版阿里旺旺、米聊等均属于以数据写入为主的消息类应用,而移动公司的手机详单查询系统则属于以数据查询为主的详单类应用。
HBase 的另一个用途是作为 MapReduce 的后台数据源,以支撑离线分析型应用。这个固然可以,但其性能如何则是值得商榷的。比如说, superlxw1234 同学通过实验对比了“ Hive over HBase ”和“ Hive over HDFS ”后惊奇的发现 [2] ,除了在使用 rowkey 过滤时,基于 HBase 的性能上略好于直接基于 HDFS 外,在使用全表扫描和根据 value 过滤时,直接基于 HDFS 方案的性能均比 HBase 好的多——这真是一个谬论啊!不过对于这个问题,我个人感觉从原理上看,当使用 rowkey 过滤时,过滤程度越高,基于 HBase 方案的性能必然越好;而直接基于 HDFS 方案的性能则跟过滤程度没有关系。
3. HBase Vs. Redis
HBase 和 Redis 在功能上比较类似,比如它们都属于 NoSQL 级别的数据库,都支持数据分片等,关键的不同点实际上只有一个:对 HBase 而言,一旦数据被成功写入,从原理上看是不会丢的,因为它有 Writa-ahead Log (功能上类似于 Oracle REDO );而对于 Redis 而言,即便是配置了主从复制功能,在 Failover 时完全存在发生数据丢失的可能(如果不配置主从复制,那么丢失的数据会更多),因为它第一没有类似 REDO 的重做日志,第二采用了异步复制的方式。
关键还在于性能。通常, Redis 的读写性能在 100,000 ops/s 左右,时延一般为 10 ~ 70 微妙 左右 [4][5] ;而 HBase 的单机读写性能一般 不会超过 1,000ops/s ,时延则在 1 ~ 5 毫秒之间 [3] 。忽略其中的硬件因素, 100 倍的读写性能差异已经足够说明问题了。顺便提一下的是, Redis 在 Tuning 上还是比较讲究的,比如说,当使用 numactl (或 taskset )将 Redis 进程绑定到同一个 CPU 的不同 CORE 上时,它的性能一般可以提升 30% 左右 [6] ,在一些特别的场景下甚至可以有近一倍的提升。
从上述的功能和性能比较上,我们就很容易的总结出 HBase 和 Redis 各自的适用范畴:
1 )当用来支撑简单“消息类”应用时,如果数据失败是不能容忍的,那就用只能用 HBase ;如果需要一个高性能的环境,而且能够容忍一定的数据丢失,那完全可以考虑使用 Redis 。
2 ) Redis 很适合用来做缓存,但除此之外,它实际上还可以在一些“读写分离”的场景下作为“读库”来用,特别是用来存放 Hadoop 或 Spark 的分析结果。
有不少人认为 Redis 只适合用作“缓存”,根据我的理解,这主要是基于以下 2 个原因:第一, Redis 在设计上存在数据丢失的可能性;第二,当无法将数据全部 HOLD 在内存中时,其读写性能会急剧下降到每秒几百 ops[6] ,这一现象类似于 Google 开源的 Leveldb[7] , Facebook 的 RocksDB 团队的通过 Performance Benchmark 也证实了这一现象的存在 [8] 。但是,当用作“读库”或用于支撑允许数据丢失的“消息类”应用时,这两个问题实际上都没有关系。
[1] Hadoop 虽然强大,但不是万能的。http://database.51cto.com/art/201402/429789.htm
[2] Hiveover HBase 和Hive over HDFS 性能比较分析。http://superlxw1234.iteye.com/blog/2008274
[3] Hbase 性能测试。http://www.cnblogs.com/colorfulkoala/archive/2013/05/13/3076139.html
[4] 互联网利器 Redis 内存数据库性能评测。http://tech.it168.com/a2012/1011/1406/000001406978_all.shtml
[5] Howfast is Redis?http://redis.io/topics/benchmarks
[6] Redis 千万级的数据量的性能测试。http://www.cnblogs.com/lovecindywang/archive/2011/03/03/1969633.html
[7] Leveldb.https://code.google.com/p/leveldb/
[8] RocksDBbenchmark results. https://github.com/facebook/rocksdb/wiki/Performance-Benchmarks
----------------------------
原文链接:https://blog.51cto.com/datainsight/1426538
程序猿的技术大观园:www.javathinker.net
|
|