带有Apache Spark的Lambda架构
欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~
目标
市场上的许多玩家已经建立了成功的MapReduce工作流程来每天处理以TB计的历史数据。但是谁愿意等待24小时才能获得最新的分析结果?这篇博文将向您介绍旨在利用批处理和流处理方法的Lambda架构。我们将利用Apache Spark(Core,SQL,Streaming),Apache Parquet,Twitter Stream等实时流数据快速访问历史数据。还包括清晰的代码和直观的演示!
简史
Apache Hadoop的丰富历史始于2002年。Hadoop由Doug Cutting创建,Doug Cutting是Apache Lucene(一个被广泛使用的文本搜索库)的创建者。Hadoop起源于Apache Nutch,一个开源的网络搜索引擎,它本身就是Lucene项目的一部分。它在10年前成为一个独立的项目。
因此,大量客户实施了有效的基于Hadoop的M/R处理管道。现实生活中有一些很好的例子:
- Oozie编排的工作流程每天运行并处理高达150 TB的数据以生成分析结果
- bash管理的工作流程每天运行并处理高达8 TB的数据以生成分析结果
现状
商业现实已经发生了变化,所以现在更快做出的决定更有价值。除此之外,技术也在不断发展。Kafka,Storm,Trident,Samza,Spark,Flink,Parquet,Avro,Cloud providers等都是工程师和企业广泛采用的流行语。
因此,现代基于Hadoop的M/R管道(使用Kafka,Avro和数据仓库等现代二进制格式,即Amazon Redshift,用于临时查询)可能采用以下方式:
这看起来相当不错,但它仍然是一种传统的批处理方式,具有所有已知的缺点,主要原因是客户端的数据在批处理花费大量时间完成之前的数据处理时,新的数据已经进入而导致数据过时。
Lambda架构
Nathan Marz针对通用的,可扩展的和容错的数据处理架构提出了术语Lambda Architecture。它是一种旨在通过利用批处理和流处理这两者的优势来处理大量数据的数据处理架构。
我强烈建议阅读Nathan Marz的书,因为它从提出者的角度提供了Lambda Architecture的完整表述。
图层
从宏观角度看,它的处理流程如下:
所有进入系统的数据都被分配到批处理层和速度层进行处理。批处理层管理主数据集(一个不可变的,仅可扩展的原始数据集)并预先计算批处理视图。服务层对批处理视图进行索引,以便可以在低延迟的情况下进行点对点查询。速度层只处理最近的数据。任何传入的查询都必须通过合并来自批量视图和实时视图的结果来得到结果。
焦点
许多工程师认为Lambda Architecture是全部关于这些层次和定义的数据流的,但Nathan Marz在他的书中将重点放在其他重要方面,如:
- 思考的分布式
- 避免增量架构
- 强制数据不可变
- 创建重新计算算法
数据的相关性
如前所述,任何传入查询都必须通过合并来自批量视图和实时视图的结果来得到答案,因此这些视图需要可合并性。需要注意的一点是,实时视图是以前的实时视图和新数据增量的函数,因此可以使用增量算法。批处理视图是所有数据的函数,因此应该在那里使用重算算法。
权衡
我们生活中的每一件事都是一种折衷,而Lambda Architecture也不是一个例外。通常,我们需要解决一些主要的折衷:
- 完全重新计算与部分重新计算
- 在某些情况下,可以使用Bloom过滤器来避免完全重新计算
- 重算算法与增量算法
- 使用增量算法有很大的诱惑力,但根据指南我们必须使用重新计算算法,即使它使达到相同的结果变得更加困难。
- 加法算法与近似算法
- Lambda Architecture与加法算法很好地协作。因此,这是我们需要考虑使用近似算法的另一种情况,例如,HyperLogLog用于计数不同的问题等。
实现
有多种实现Lambda体系结构的方法,因为它对于每个层的底层解决方案都是不可知的。每一层都需要底层实现的特定功能,这可能有助于做出更好的选择并避免过度的决定:
- 批处理层:一次写入,批量读取多次
- 服务层:随机读取,不随机写入; 批量计算和批量写入
- 速度层:随机读取,随机写入; 增量计算
例如,其中一个实现(使用Kafka,Apache Hadoop,Voldemort,Twitter Storm,Cassandra)可能如下所示:
Apache Spark
Apache Spark可以被视为在所有Lambda体系结构层上处理的集成解决方案。它包含Spark Core,包括高层次的API,并且支持通用执行图表的优化引擎,Spark SQL为SQL和结构化数据提供处理,以及Spark Streaming,支持可扩展性,高吞吐量,容错流的实时数据流的处理。当然,使用Spark进行批量处理可能会非常昂贵,并且可能不适合所有场景和数据量,但除此之外,它是Lambda Architecture实施方案的适当匹配。
示例应用程序
让我们用一些捷径创建一个示例应用程序来演示Lambda架构,这个程序的主要目标是提供在#morningatlohika推文中使用的主题标签统计数据。
源代码位于GitHub上,关于上述主题的更多视觉信息位于Slideshare上。
批处理视图
为了简单起见,假设我们的主数据集包含自开始以来的所有推文。另外,我们实施了批量处理,创建我们业务目标所需的批处理视图,因此我们有一个预先计算的批处理视图,其中包含与#morningatlohika一起使用的所有主题标签统计信息:
apache – 6 architecture – 12 aws – 3 java – 4 jeeconf – 7 lambda – 6 morningatlohika – 15 simpleworkflow – 14 spark – 5
数字很容易记住,因为我简单地在相应的主题标签中使用了许多字母。
实时视图
想象一下,当应用程序启动并运行时,现在有人正在发送推文消息:
“ @tmatyashovsky关于 #lambda #architecture使用 #apache #spark在 #morningatlohika的酷博客文章 ”
在这种情况下,适当的实时视图应该包含以下hash标签和它们的统计信息(在我们的例子中仅为1,因为相应的hash标签只用了一次):
apache – 1 architecture – 1 lambda – 1 morningatlohika – 1 spark – 1
查询
当客户端为了实时得到所有的Hash标签的统计结果进行查询时,我们只需要将批量视图与实时视图合并即可。所以输出应该如下所示(适当的hashtags的统计数字增加1):
apache – 7 architecture – 13 aws – 3 java – 4 jeeconf – 7 lambda – 7 morningatlohika – 16 simpleworkflow – 14 spark – 6
演示方案
演示场景的简化步骤如下:
- 通过Apache Spark 创建批处理视图(.parquet)
- 在Apache Spark中缓存批处理视图
- 开始连接到Twitter的流应用程序
- 关注即时#morningatlohika推文
- 构建增量的实时视图
- 查询,即即时合并批处理和实时视图
技术细节
源代码基于Apache Spark 1.6.x,即在引入结构化流式传输之前。Spark Streaming架构是纯粹的微批处理架构:
因此,对于流媒体应用程序,我是用DSTREAM使用连接到Twitter TwitterUtils:
JavaDStream < Status > twitterStatuses = TwitterUtils.createStream ( javaStreamingContext,createTwitterAuthorization (),new String [ ] {twitterFilterText } );
在每个微批处理中(使用可配置的批处理间隔),我正在执行新推文中hashtags统计的计算,并使用updateStateByKey()有状态转换更新实时视图的状态。为了简单起见,使用临时表将实时视图存储在内存中。
查询服务反映了通过代码显式合并由DataFrame表示的批处理视图和实时视图:
DataFrame realTimeView = streamingService . getRealTimeView ( ) ; DataFrame batchView = servingService . getBatchView ( ) ; DataFrame mergedView = realTimeView . unionAll ( batchView ) . groupBy ( realTimeView . col ( HASH_TAG . getValue ( ) ) ) . sum ( COUNT . getValue ( ) ) . orderBy ( HASH_TAG . getValue ( ) ) ; List < Row > merged = mergedView . collectAsList ( ) ; return merged . stream ( ) . map ( row - > new HashTagCount ( row . getString ( 0 ) , row . getLong ( 1 ) ) ) . collect ( Collectors . toList ( ) ) ;
结果
使用简化的方法,开头提到的真正基于Hadoop的M/R管道可能会使用Apache Spark进行增强,并按以下方式查看:
并不是后记
正如前面提到的,Lambda Architecture有其优点和缺点,人们也划分成支持者和反对者两派。他们中的一些人说批处理视图和实时视图有很多重复的逻辑,因为他们最终需要从查询角度创建可合并的视图。所以他们创建了Kappa架构 – 简化了Lambda架构。Kappa架构系统是删除了批处理系统的架构。要取代批处理,数据只需通过流式传输系统快速提供:
但即使在这种情况下,Kappa Architecture也有使用Apache Spark的地方,例如流处理系统:
此文已由作者授权腾讯云+社区发布,原文链接:https://cloud.tencent.com/developer/article/1138267?fromSource=waitui