分布式的并行计算框架,从数据处理时效角度可以分为离线的批处理框架和实时的流处理框架。当前最流行的批处理框架是Spark,流处理框架是Flink。
这里所说的批处理指的是大数据离线分布式批处理技术,专用于应对那些一次计算需要输入大量历史数据,并且对实时性要求不高的场景。目前常用的开源批处理组件有MapReduce和Spark,两者都是基于MapReduce计算模型的。
1.MapReduce计算模型
MapReduce是Google提出的分布式计算模型,分为Map阶段和Reduce阶段。在具体开发中,开发者仅实现map()和reduce()两个函数即可实现并行计算。Map阶段负责数据切片,进行并行处理,Reduce阶段负责对Map阶段的计算结果进行汇总。
这里举一个通俗的例子帮助你理解。假如现在有3个人想打一种不需要3~6的扑克牌游戏,需要从一副扑克牌中去掉这些牌,过程描述如下:
第一步,将这一副牌随机分成3份,分给3个人,然后每个人一张张查看手中的牌,遇到3~6的牌就挑出去;
第二步,等所有人都完成上面的步骤后,再将每个人手上剩余的牌收集起来。
在这个过程中,第一步操作属于Map阶段,相当于对每张牌做一次判断(映射、函数运算),是否保留;第二步属于Reduce阶段,将结果汇总。
MapReduce数据流图如图1所示。
▲图1 MapReduce数据流图
MapReduce处理的数据格式为键-值格式,一个MapReduce作业就是将输入数据按规则分割为一系列固定大小的分片,然后在每一个分片上执行Map任务,Map任务相互独立,并行执行,且会在数据所在节点就近执行;当所有的Map任务执行完成后,通过缓存机制将分散在多个节点的键值相同的数据记录拉取到同一节点,完成之后的Reduce任务,最后将结果输出到指定文件系统,比如HDFS、HBase。基于以上解释和描述,可以看出MapReduce不适合实现需要迭代的计算,如路径搜索。
2.Spark
Spark是基于内存计算的大数据并行计算框架,最初由美国加州大学伯克利分校的AMP实验室于2009年开发,于2010年开源,是目前最主流的批处理框架,替代了MapReduce。
整个Spark项目由四部分组成,包括SparkSQL、Spark Streaming、MLlib、Graphx,如图2所示。其中SparkSQL用于OLAP分析,Streaming用于流式计算的(微批形式),MLlib是Spark的机器学习库,Graphx是图形计算算法库。Spark可在Hadoop YARN、Mesos、Kubernetes上运行,可以访问HDFS、Alluxio、Cassandra、HBase等数据源。
▲图2 Spark组件
Spark使用先进的DAG(Directed Acyclic Graph,有向无环图)执行引擎,支持中间结果仅存储在内存中,大大减少了IO开销,带来了更高的运算效率,并且利用多线程来执行具体的任务,执行速度比MapReduce快一个量级。
在Spark中,Spark应用程序(Application)在集群上作为独立的进程集运行,由主程序(称为Driver)的SparkContext中的对象协调,一个Application由一个任务控制节点(Driver)和若干个作业(Job)构成。Driver是Spark应用程序main函数运行的地方,负责初始化Spark的上下文环境、划分RDD,并生成DAG,控制着应用程序的整个生命周期。Job执行MapReduce运算,一个Job由多个阶段(Stage)构成,一个阶段包括多个任务(Task),Task是最小的工作单元。在集群环境中,Driver运行在集群的提交机上,Task运行在集群的Worker Node上的Executor中。Executor是运行在Spark集群的Worker Node上的一个进程,负责运行Task,Executor既提供计算环境也提供数据存储能力。在执行过程中,Application是相互隔离的,不会共享数据。Spark集群架构示意图如图3所示。
▲图3 Spark集群架构
具体来说,当在集群上执行一个应用时,SparkContext可以连接到集群资源管理器(如YARN),获取集群的Worker Node的Executor,然后将应用程序代码上传到Executor中,再将Task发送给Executor运行。
Spark的核心数据结构是RDD(Resilient Distributed Dataset,弹性分布式数据集),只支持读操作,如需修改,只能通过创建新的RDD实现。
当前实时处理数据的需求越来越多,例如实时统计分析、实时推荐、在线业务反欺诈等。相比批处理模式,流处理不是对整个数据集进行处理,而是实时对每条数据执行相应操作。流处理系统的主要指标有以下几个方面:时延、吞吐量、容错、传输保障(如支持恰好一次)、易扩展性、功能函数丰富性、状态管理(例如窗口数据)等。
目前市面上有很多成熟的开源流处理平台,典型的如Storm、Flink、Spark Streaming。三者的简单对比如下:Storm与Flink都是原生的流处理模型,Spark Streaming是基于Spark实现的微批操作;Spark Streaming的时延相对前两者高;Flink与Streaming的吞吐量高,支持的查询功能与计算函数也比Storm多。总体来说,Flink是这三者中综合性能与功能更好的流平台,当前的社区发展也更火热。
1.Flink简介
Flink最初由德国一所大学开发,后进入Apache孵化器,现在已成为最流行的流式数据处理框架。Flink提供准确的大规模流处理,支持高可用,能够7×24小时全天候运行,支持exactly-once语义、支持机器学习,具有高吞吐量和低延迟的优点,可每秒处理数百万个事件,毫秒级延迟,支持具有不同的表现力和灵活性的分层API,支持批流
一体。
2.Flink的架构
Flink是一个分布式系统,可以作为独立群集运行,也可以运行在所有常见的集群资源管理器上,例如Hadoop YARN、Apache Mesos和Kubernetes。
Flink采用主从架构,Flink集群的运行程序由两种类型的进程组成:JobManager和一个或多个TaskManager。TaskManager连接到JobManager,通知自己可用,并被安排工作。两者的功能如下所示:
JobManager负责协调Flink应用程序的分布式执行,完成任务计划、检查点协调、故障恢复协调等工作。高可用性设置需要用到多个JobManager,其中一个作为领导者(leader),其他备用。
TaskManager,也称为Worker,负责执行数据处理流(dataflow)的任务,并缓冲和交换数据流。TaskManager中资源调度的最小单位是任务槽(slot),TaskManager中slot的数量代表并发处理任务的数量。
Flink架构示意图如图4所示。
▲图4 Flink架构
客户端(Client)不是Flink运行程序的一部分,它在给JobManager发送作业后,就可以断开连接或保持连接状态以接收进度报告。
3.Flink对数据的处理方式
流处理是对没有边界数据流的处理。执行时,应用程序映射到由流和转换运算符组成的流式数据处理流。这些数据流形成有向图,以一个或多个源(source)开始,以一个或多个输出(sink)结束。程序中的转换与运算符之间通常是一对一的关系,但有时一个转换可以包含多个运算符。Flink流式处理步骤示例如图5所示。
▲图5 Flink流式处理步骤示例
4.Flink的接口抽象
Flink为开发流、批处理的应用提供了四层抽象,实践中大多数应用程序是基于核心API的DataStream/DataSet API进行编程的,四层抽象从低到高的示意图如图6所示。
▲图6 Flink接口抽象层次
Low-level:提供底层的基础构建函数,用户可以注册事件时间和处理时间回调,从而允许程序实现复杂的计算。
Core API:DataStream API(有界/无界流)和DataSet API(有界数据集)。基于这些API,用户可以实现transformation、join、aggregation、windows、state等形式的数据处理。
Table API:基于表(table)的声明性领域特定语言(DSL)。Table API遵循(扩展的)关系模型,表具有附加的表结构(schema),并且该API提供类似关系模型的操作,例如select、join、group-by、aggregate等。Table API的表达性不如Core API,但优点是使用起来更为简洁,编码更少。Flink支持在表和DataStream/DataSet之间进行无缝转换,因此可以将Table API与DataStream/DataSet API混合使用。
SQL:此层是最高层的抽象,在语义和表达方式上均类似于Table API,但是将程序表示为SQL查询表达式。
本文摘编于《数据应用工程:方法论与实践》,经出版方授权发布。(书号:9787111704096)转载请保留文章出处