使用Apache Spar 的Lambda架构

Lambda Architecture 能与加法算法很好地协同工作。 因此,在另一种情况下,我们需要考虑使用近似算法,例如,使用HyperLogLog处理count-distinct的问题等。

实现

有许多实现Lambda架构的方法,因为对于每个层的底层解决方案是非常独立的。每个层需要底层实现的特定功能,有助于做出更好的选择并避免过度决策:

批量层(Batch Layer):写一次,批量读取多次

服务层(Serving layer):随机读取,不支持随机写入,批量计算和批量写入

速度层(Speed layer):随机读取,随机写入;增量计算

例如,其中一个实现方案的构成(使用Kafka,Apache Hadoop,Voldemort,Twitter Storm,Cassandra)可能如下图所示:

Apache Spark

Apache Spark可以被认为是用于Lambda架构各层的集成解决方案。其中,Spark Core 包含了高层次的API和优化的支持通用图运算引擎,Spark SQL用于SQL和结构化数据处理、 Spark Streaming 可以解决高拓展、高吞吐、容错的实时流处理。在批处理中使用Spark可能小题大做,而且不是所有方案和数据集都适用。但除此之外,Spark算是对Lambda Architecture的合理的实现。

示例应用

下面通过一些路径创建一个示例应用,以展示Lambda Architecture,其主要目的是提供#morningatlohika tweets(一个由我在Lviv, Ukraine发起的本地技术演讲,)这个hash标签的统计:包括之前到今天这一刻的所有时间。

源码在GitHub 上,有关这个主题的更多信息可以在Slideshare上找到。

批处理视图(Batch View)

简单地说,假定我们的主数据集包含自开始时间以来的所有更新。 此外,我们已经实现了一个批处理,可用于创建我们的业务目标所需的批处理视图,因此我们有一个预计算的批处理视图,其中包含所有与#morningatlohika相关的标签统计信息:

编号很容易记住,因为,为方便查看,我使用对应标签的英文单词的字母数目作为编号。

实时视图

假设应用程序启动后,同时有人发如下tweet:

“Cool blog post by @tmatyashovsky about #lambda #architecture using #apache #spark at #morningatlohika”

此时,正确的实时视图应该包含如下的hash标签和统计数据(本例中都是1,因为每个hash标签只用了一次):

查询

当终端用户查询出现是,为了给全部hash标签返回实时统计结果,我们只需要合并批处理视图和实时视图。所以,输出如下所示编码(hash标签的正确统计数据都加了1):

场景

示例中的场景可以简化为如下步骤:

用Apache Spark创建批处理视图(.parquet)

在Spark中缓存批处理视图

将流处理应用连接到Twitter

实时监视包含#morningatlohika 的tweets

构造增量实时视图

查询,即,即时合并批处理视图和实时视图

技术细节

此源代码是基于Apache Spark 1.6.x(注:再引入结构流之前)。 Spark Streaming架构是纯微型批处理架构:

所以当我处理一个流媒体应用程序时,我使用DStream来连接使用TwitterUtils的Twitter:

在每个微批次中(使用可配置的批处理间隔),我正在对新tweets中的hashtags统计信息进行计算,并使用updateStateByKey()状态转换函数来更新实时视图的状态。简单地说,就是使用临时表将实时视图存储在存储器中。

查询服务反映了批处理的合并过程和通过代码表示的DataFrame实时视图: