从 Google 的大数据三驾马车谈起
Google 在 2003 年到 2004 年先后发布了被称为大数据三驾马车的三篇重要论文, 分别是分布式数据处理 MapReduce, 分布式数据存储 GFS 以及列式存储 数据库 BigTable. 正是谷歌的这三驾马车掀开了大数据时代的序幕, 谷歌也毋庸置疑的成为了当代大数据技术的始祖, 可以说现今几乎所有的大数据技术都是由这三种技术发展而来的.
谷歌的这三驾马车之所以能够奠定大数据技术的基础, 是因为这三种技术涵盖了大数据技术所需要的海量存储, 海量数据库, 分布式计算这三个最基本的需求.
大数据之所以能被称为大数据, 就是因为要处理的数据量比一般情况下大得多, 大到单独一台机器远远无法承担.
为了处理更大量的数据, 传统的解决办法是升级机器, 配上更大的磁盘容量, 更多核数的 CPU, 更大的内存, 来存储和处理更多的数据, 这种做法叫做纵向扩展. 这种做法简单直接, 但是成本高昂. 更麻烦的是, 单台机器的性能是有极限的, 对于现在动不动就要上 PB 的数据规模来说, 再高的配置也远远不够. 更不用说, 单台机器还存在机器故障后数据丢失的风险, 数据的可靠性难以保证.
谷歌的三驾马车则为大数据问题提供了更优的解决思路, 那就是增多机器数而非提升机器性能, 即横向扩展. 按照这种思路, 可以使用大量的廉价通用服务器构建一个巨大的集群, 对海量的数据进行分布式的存储和处理. 俗话说, 三个臭皮匠顶上诸葛亮, 100 台廉价服务器加在一起的性能是要远高于单独一台顶配服务器的. 因此利用谷歌的这种思路, 你就能通过堆机器这种方法以相对低的成本获得以往无法想象的数据处理性能.
谷歌的这三驾马车虽然牛逼, 但是一直以来都只作为谷歌的内部技术被使用, 并没有向业界开源, 因此真正熟知并理解这三种技术的人其实并不多. 真正被世人熟知的大数据技术始祖其实是 Hadoop, 这个后人借助谷歌三驾马车思想而构建的开源大数据套件.
大数据存储之 Hadoop HDFS
大数据处理的第一步自然是要先找到一个存放数据的地方. HDFS 提供的便是海量文件的存储技术.
HDFS 是谷歌 GFS 技术的开源实现版本. HDFS 将文件分成块分布到不同的机器上, 从而借助成千上万台廉价 PC 实现海量数据的高可靠性存储.
在 HDFS 中, 一份文件会拥有多份分布在不同机器上的复制, 因此即使某台机器坏了数据也不会丢失, 具备极高的可靠性.
尽管 HDFS 使用了很多复杂的分布式存储技术, 但是对用户来说, 使用 HDFS 和使用以往的文件系统一样简单. 用户不用关心文件是如何分块的或者文件存储在集群的哪个节点上这种问题, 只需要连上 HDFS, 之后像使用 Linux 本地文件系统一样使用 HDFS 即可.
大数据计算之 Hadoop MapReduce
数据有地方存了, 接下来要做的当然是对数据进行分析了.
Hadoop MapReduce 和 Google 的 MapReduce 一样, 提供海量数据的分布式处理能力. 通过 MapReuduce, 成百上千台机器可以共同协作去计算同一个问题, 从而依靠大量机器的共同力量去解决海量数据的计算问题.
MapReduce 通过 Map 和 Reduce 两个主要阶段. 在 Map 阶段, MapReuce 把数据划分成很多个部分读入, 然后将数据解析成方便计算和 key-value 形式. 在 Reduce 阶段, 数据按照 key 的不同被再次划分到不同的机器, 然后每台机器格子对数据进行聚合计算, 最终形成用户期望的计算结果. 下边一张图可以让你对 MapReduce 的过程有一个更形象的认识:
MapReduce 过程
MapReduce 实际的计算流程要比上边描述的复杂的多, 而你只要记住, MapReduce 解决的本质问题就是如何将数据合理的分布到很多台机器上进行计算, 以及如何合理的合并多台机器上的计算结果.
Pig:
通过编写 MapReduce 脚本已经可以借助大数据手段解决几乎所有的海量数据的计算和分析问题. 但是, MapReduce 存在一个严重的问题, 那就是 MapReduce 脚本编写起来实在是太费劲了! 想编写 MapReuce 程序, 你首先需要弄懂 MapReduce 的原理, 合理的把计算过程拆分成 Map 和 Reduce 两步, 然后你还需要正确的配置一大堆 MapReduce 的执行参数, 之后提交任务, 反复检查运行状态, 检查运行结果, 这时候如果你的 MapReduce 脚本存在问题, 那么你还需要去翻 log 分析问题出在哪里, 然后修改你的脚本再来一遍. 因此, 想写出一个能用的 MapReduce 程序不但有较高的难度, 还需要耗费大量的时间和精力.
那么, 如果我很懒, 实在不想去写复杂的 MapReduce 程序, 那么有没有什么办法能够简化写 MapReduce 的这个繁杂的过程呢? 当然有, 那就是 Pig 了(此时你一定明白 Pig 这个名称的由来了, 就是为懒人服务的工具).Pig 的意义就是替你编写复杂的 MapReduce 脚本, 从而简化 MapReduce 的开发流程, 大大缩短开发周期.
Pig 实现了一种叫做 Pig Latin 的语言, 你只需要编写简单的几行 Latin 代码, 就可以实现在 MapReduce 需要大量代码才能实现的功能. Pig 帮你预设了多种数据结构, 从而帮助你方便的将输入文本中的内容转换为 Pig 中结构化数据. Pig 还提供了诸如 filter,group by,max,min 等常用的计算方法, 帮助你快速实现一些常规的数据计算. 执行和查看结果在 Pig 中也非常的简单, 你不再需要配置 MapReduce 中的一大堆复杂的参数, 也不再需要手动到 HDFS 上下载运行结果并对下载结果进行排版, Pig 会直接把运行结果用良好的排版展示给你看, 就像在 SQL 数据库中一样方便.
有了 Pig, 不用写 MapReduce 了, 数据开发也快多了. 但是 Pig 仍然存在一些局限, 因为使用 Pig 从本质上来说还相当于用 MapReduce, 只是脚本的编写比以前快了, 但是你仍然要一行一行的去写 Pig 脚本, 从而一步一步的实现你的数据分析过程. 此时如果有工程师说自己已经懒得无可救药了, 连 Pig 脚本也不想写; 或者有数据分析师说自己不懂技术, 压根不会写脚本, 只会写几句简单的 SQL, 那么有没有什么比 Pig 还简单的办法呢? 那么下边就该 Hive 出场了!
Hive:
Hive 是一种数据仓库软件, 可以在分布式存储系统的基础之上 (例如 HDFS) 构建支持 SQL 的海量数据存储数据库.
简单的说, Hive 的作用就是把 SQL 转换为 MapReduce 任务进行执行, 拿到结果后展示给用户. 如此一来, 你就可以使用普通的 SQL 去查询分布在分布式系统上的海量数据.
尽管 Hive 能提供和普通 SQL 数据库一样好用的 SQL 语句, 但是 Hive 的查询时延是要远高于普通数据库的, 毕竟查询时间和数据规模二者还是不能兼得的啊! 由于 Hive 并且每次查询都需要运行一个复杂的 MapReduce 任务, 因此 Hive SQL 的查询延时是远高于普通 SQL 的. 与此同时, 对于传统数据库必备的行更新, 事务, 索引这一类 "精细化" 操作, 大条的 Hive 自然也都不支持. 毕竟 Hive 的诞生就是为了处理海量数据, 用 Hive 处理小数据无异于杀鸡用牛刀, 自然是无法得到理想的效果, 因此, Hive 只适合海量数据的 SQL 查询.
Spark
有了 Hive, 不会编程的你也能用 SQL 分析大数据了, 世界似乎已经美好了很多. 可惜好戏不长, 慢慢的, 你还发现 Hive 依旧有一堆的问题, 最典型的问题就是查询时延太长(这里特指 MapReduce Hive, 而非 Spark Hive). 受限于 MapReduce 任务的执行时间, 查一次 Hive 快则几十分钟, 慢则几小时都是有可能的. 试想领导着急的问你还要报表, 而你只能无奈的等待缓慢的 Hive 查询运行完, 此时的你一定急的想砸显示屏了. 那么有没有什么既好用, 又执行迅速的大数据工具呢? 下边就该我们的新星级产品 Spark 登场了.
与 MapReduce 类似, Spark 同样是分布式计算引擎, 只是 Spark 的诞生要比 MapReduce 晚一些, 但是 Spark 后来者居上, 如今在很多领域都大有取代 MapReduce 的趋势.
Spark 相较于 MapReduce 最大的特点就是内存计算和对 DAG 模型的良好支持, 借助这些特点, 对于计算任务, 尤其是需要分很多个阶段进行的复杂计算任务, Spark 的执行速度要远远快于 MapReeduce.
在 MapReduce 执行过程中, 需要将中间数据先写入到磁盘中, 然后再加载到各个节点上进行计算, 受限于巨大的磁盘 IO 开销, MapReduce 的执行经常要很长时间. 而 Spark 则是将中间数据加载在内存中, 因此能取得远高于 MapReduce 的执行速度.
Spark 的优点还远不止此. 相较 MapReduce,Spark 提供了很多高层次封装的功能, 在易用性上和功能丰富程度上都要远远高于 MapReduce. 用 Spark 你甚至只需要一行代码就能实现 group,sort 等多种计算过程. 这点上 Spark 可以说是同时融合了 Pig 和 Hive 的特点, 能够用简单几行代码实现以往 MapReduce 需要大量代码才能实现的功能. 下边来一行 Spark 代码让大家感受下:
val wordCounts = textFile.flatMap(line => line.split(" ")).groupByKey(identity).count()
以上代码实现 Word Count.
除此之外, Spark 还支持 Python,Scala,Java 三种开发语言, 对于 Python 和 Scala 甚至还提供了交互式操作功能, 对于非 Java 开发者以及科研工作者真是友好到爆, 事实上 Spark 确实也广受科研工作者的欢迎.
新版本的 Spark 还提供了 Spark SQL,Spark streaming(后边会介绍)等高层次的功能, 前者提供类似 Hive 的 SQL 查询, 后者提供强大的实时计算功能(后边会详细介绍), 大有一统大数据分析领域的趋势. 因此 Spark 绝对是当今发展势头最好的大数据组件之一.
不过 Spark 也并非真的就无敌了, 内存计算的特点还是会对 Spark 能够应对的数据规模产生影响. 另外, 对于计算过程的控制和调优, Spark 也不如 MapReduce 灵活.
Storm
有了前边讲的这一系列工具, 我们已经能够对海量数据进行方便的计算分析了. 但是前边的这些工具, 从基础的 MapReduce 到简单易用的 Hive, 都依然存在一个问题, 那就是计算过程需要较长的时间. 也就是说, 从你开始执行数据分析任务, 到 MapReduce 生成你要的结果, 常常需要若干小时的时间. 由于这个延时的存在, MapReduce 得到的数据分析结果是要比线上业务慢半拍的, 例如今天得到昨天的日志分析结果, 也因此, MapReduce 又被称作离线数据处理或者批处理.
但是, 如果你希望能够立刻得到数据的分析结果, 例如像天猫双十一实时大屏那样实时的显示最新的成交额, 那么你就需要一些实时数据处理工具了.
最新火起来的实时数据处理工具要当属 Apache Storm 了. 我们直到在 MapReduce 这类离线处理工具中, 数据是要一批一批的被处理的, 并且每批数据都需要一定的处理时延. 而在 Storm 中, 是没有批这个概念的, 在 Storm 中数据就如同水龙头中的水一样源源不断地流出, 并被实时的进行处理. 因此, 在 Storm 中, 只要你搭建好了数据处理流程, 数据就会源源不断的, 永不停止的被接受并处理, 并且你可以随时看到数据的最新处理结果.
Storm
尽管 Storm 和 MapReduce 的处理流程差异很大, 但是它们的基本思路是一致的, 都是把数据按照 key 分散到不同的机器上, 之后由各个机器对数据进行处理, 最终将各个机器的计算结果汇总在一起.
不同的是, Storm 中的数据处理是一条一条实时进行的, 因此结果会处于一种不断的刷新过程中; 而 MapReduce 是一次性处理完所有输入数据并得到最终结果, 因此你将会直接看到最终结果.
例如, 假设有大量的文章需要统计单词的出现次数, 对于 MapReduce, 你将直接看到最终结果: hello: 3, world: 2, you: 6; 而对于 Storm, 你将会看到 hello:1, world:1, you: 1, world: 2, you:2...... 这样的处于不断刷新中的统计结果.
另外值得一提的是, Storm 和 MapReduce 也并不是一个互相取代的关系, 而是一个互补的关系. Storm 可是让你实时的得到数据的最新统计状态, 但是在数据吞吐量方面是要低于 MapReduce 的, 并且对于相同的数据量, 如果只关注最终结果, MapReuce 得到最终结果所需的时间和资源肯定是要小于 Storm 的. 因此, 如果你需要实时的查看数据的最新统计状态, 用 Storm; 如果你只关注数据的最终统计结果, 用 MapReduce.
Flink 和 Spark Streaming
谈完 Storm, 就必须顺带也谈一下另外两种同样火爆的实时数据处理工具, 那就是 Flink 和 Spark Straming. 这两种技术要晚于 storm 诞生, 但是现在大有后来者居上的趋势.
Flink 与 Storm 非常类似, 都能够提供实时数据流处理功能. 区别在于 Flink 还能够支持一些更高层的功能, 例如 group by 这种常用算法. 另外, Flink 还具备比 Storm 更高的吞吐量和更低的延时, 这是因为 Flink 在处理完一条条数据的时候是分组批量确认的, 而 Storm 则是一条一条确认. Flink 的这种特性带来了很大的性能优势, 但是也会对单条数据的处理时延带来很大的不稳定因素, 因为任何相邻数据的处理失败都会导致整组数据被重新处理, 从而严重影响一组数据的处理时延. 因此, 如果你追求更高的吞吐量, 可以选择 Flink, 如果你对每条数据的处理时延都有极高的要求, 那么选 Storm.
至于 Spark Streaming, 其实并不能算得上是纯正的实时数据处理, 因为 Spark Streaming 在处理流数据时依然用的是批处理的模式, 即凑齐一批数据后启动一个 Spark 任务得到处理结果. 你甚至可以把 Spark Streaming 简单看成是带流输入的 Spark. 得益于 Spark 任务执行快速的优点, 尽管 Spark Streaming 是一种伪实时处理系统, 但是依然能得到还不错的实时性(秒级), 当然要跟 Storm 比的话实时性还是差不少的, 但是 Spark 在吞吐量方面要强于 Storm.
Spark Streaming 和 Flink 除了吞吐量这个优点外, 还有另一个重要的优点, 那就是能够同时支持批处理和实时数据处理. 也就是说, 你只需要一套系统就能够同时分析你的实时数据和离线数据, 这对于架构精简 (tōu lǎn) 来说是大有好处的.
来源: http://www.jianshu.com/p/d16f4d7b1959