定义


在数据分析场景中,我们可能会遇到这样的问题。例如,我们要做一个推荐系统,如果我们用批处理任务去做,一天或者一小时的推荐频次明显延迟太大。如果用流处理任务,虽然延迟的问题解决了,然而只用实时数据而没有历史数据,那么准确性就无法保证。因此需要结合批处理的历史数据和流处理的实时数据进行处理,既能保证准确性,又能保证实时性。再比如反作弊系统,实时识别作弊用户的时候同时需要用到用户的历史行为。

针对上述问题,Storm 的作者 Nathan Marz 提出了 Lambda 架构。根据维基百科的定义,Lambda
架构的设计是为了在处理大规模数据时,同时发挥流处理和批处理的优势。通过批处理提供全面、准确的数据,通过流处理提供低延迟的数据,从而达到平衡延迟、吞吐量和容错性的目的。为了满足下游的即席查询,批处理和流处理的结果会进行合并。

从上面定义可以看出,Lambda 架构包含三层,Batch Layer、Speed Layer 和 Serving Layer。架构图如下:



下面分别介绍这三层架构的作用。

* Batch Layer
:批处理层,对离线的历史数据进行预计算,为了下游能够快速查询想要的结果。由于批处理基于完整的历史数据集,因此准确性可以得到保证。批处理层可以用
Hadoop、Spark 和 Flink 等框架计算
* Speed Layer
:加速处理层,处理实时的增量数据,这一层重点在于低延迟。加速层的数据不如批处理层那样完整和准确,但是可以填补批处理高延迟导致的数据空白。加速层可以用
Storm、Spark streaming 和 Flink 等框架计算
* Serving Layer:合并层,计算历史数据和实时数据都有了, 合并层的工作自然就是将两者数据合并,输出到数据库或者其他介质,供下游分析。
Amazon AWS 的 Lambda 架构

这里,我将用 AWS 作为例子来介绍 Lambda 架构,AWS Lambda 架构图如下



 

Batch Layer:使用 S3 bucket 从各种数据源收集数据,使用 AWS Glue 进行 ETL,输出到 Amazon S3。数据也可以输出到
Amazon Athena (交互式查询工具)

Speed Layer: 从上图看加速层有三个过程

* Kinesis Stream 从实时数据流中处理增量的数据,这部分数据数据输出到 Serving Layer 的 Amazon EMR,也可以输出到
Kinesis Firehose 对增量数据进行后续处理
* Kinesis Firehose 处理增量数据并写入 Amazone S3 中
* Kinesis Analytics 提供 SQL 的能力对增量的数据进行分析
其实只有上面第一个组件与我们今天讨论的 Lambda 架构有关,其他两个组件只是针对实时处理的。

Serving Layer:合并层使用基于 Amazon EMR 的 Spark SQL 来合并 Batch Layer 和 Speed Layer
的数据。批处理数据可以从 Amazon S3 加载批处理数据,实时数据可以从 Kinesis Stream 直接加载,合并的数据可以写到 Amazone
S3。下面是一段合并数据代码



以上便是 Amazon AWS 实现 Lambda 架构的简单介绍。

我的经历

接下来分享下我之前的项目经历。其实,我们的项目跟上面的 Lambda
架构并不是特别贴合,但是我觉得思想是一致的。本质上都是批处理和流处理相关补充,同时发挥二者的优势。

我们的业务是处理用户的定位数据,最开始主要使用 Spark Streaming 进行增量处理,处理后的数据实时写入 MongoDB。数据读写以用户 id
为粒度,由于粒度比较细,因此每天的数据量比较大。前端如果查询时间跨度较大的数据,每次都需按照用户粒度数据做聚合,导致查询响应比较慢且容易影响实时写入。因此,我们用批处理任务对历史的离线数据进行预计算,再存储到
MongoDB。同时我们开发了基于 gRPC 实现的一套 Service 来充当 Serving
Layer,将历史的数据与实时的数据合并返回给前端,避免前端直接连接数据库。在这个项目中我们的 Batch Layer 和 Speed Layer 都是用的
Spark 框架,因此维护相对容易。

之前介绍 Lambda
都是用加速层弥补批处理层的空白,但是上面的例子中是用批处理层弥补加速层的不足。因此,架构设计只是一个思想,具体的实施还是要根据业务进行灵活变通,不能生搬硬套。

小结

本篇文章简单介绍了 Lambda 架构的内容,同时介绍了 Amazon AWS 实现 Lambda
架构的例子。最后举了一个我自己项目中的一个例子。经过整篇内容我们了解了 Lambda 架构的优势,但是它有没有缺点呢。显然也是有的,我能想到的有以下几点:

* 批处理层、加速层和合并层用到的框架可能不一样,因此会增加了开发的成本
* 批处理层和加速层处理的结果有可能不一致,如果用户看到的数据会变,这个体验不太好
* 如果某一层的逻辑变了,是不是其他两层或者一层的逻辑也要跟着变,因此层与层处理逻辑耦合度较大
你还能想到其他的问题吗, 以及有没有更好的架构能解决这个问题?欢迎交流

欢迎关注公众号「渡码」



 

友情链接
KaDraw流程图
API参考文档
OK工具箱
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:ixiaoyang8@qq.com
QQ群:637538335
关注微信