随着我们步入21世纪的第二个十年,大数据时代悄然降临。这一时期的标志性特征是物联网的兴起以及机器学习和人工智能技术的突破,这些因素共同推动了应用程序形成巨量半结构化和非结构化数据。随之而来的是数据体量、处理速度和多样性的爆炸式增长。面对这样的数据洪流,传统的CEP系统显得力不从心,它们并不是为了应对如此庞杂的数据而设计的,因此难以胜任这项任务。
工程师因此着手开发新一代的实时分析系统来应对挑战。
正是在这样的背景下,Kafka这类技术应运而生。最初,Kafka由LinkedIn公司创建,作为处理高吞吐量数据的分布式消息总线。它能够每秒接收数百万个事件,并将这些事件分布存储在多个节点上以实现容错性。随后,Kafka被捐献给了Apache软件基金会,这一举动使得更广泛的开发者社区可以利用它来构建和扩展事件流应用。
在那个时期,除了上述项目外,还有两个重要的开源流处理框架引起了广泛关注,那就是Apache Samza和Apache Storm。起初由LinkedIn开发的Apache Samza,其设计宗旨是针对大规模数据进行实时处理,并且提供具有容错能力的、持久化的有状态计算功能。Apache Storm的创造者是Nathan Marz,它最初是BackType分析平台的核心组成部分,而BackType是一家专注于社交媒体数据实时分析与洞察的初创企业,该企业在2011年被Twitter收购。
随着Twitter在全球信息交流中扮演“世界城市广场”的角色而广为人知,在2012年,Twitter推出了一项创新功能——实时趋势话题。这一功能的背后,正是由Apache Storm提供技术支持。实时趋势话题不仅展示了用户在平台上热议的最新议题,而且通过这种方式,Twitter试图在其网站上激发更多的用户互动。图2-3展示了该功能的界面截图。
图2-3:Twitter实时趋势话题
Twitter的实时趋势功能,将实时分析的概念广泛传播至众多组织。Nathan Marz还提出了Lambda架构,这一架构模式迅速成为当时实时分析应用的构建基石。
Lambda架构是一种主流的大数据处理系统架构模式,它不仅能支持批量数据处理,还能高效处理实时数据流。该架构有效地解决了传统批处理系统和实时处理系统所面临的诸多挑战。
Lambda架构由三层构成:
批处理层 ( Batch Layer )
这一层类似于Apache Hadoop的批量处理系统,负责以批处理模式并行处理大量数据。
加速层 ( Speed Layer )
加速层与批处理层相辅相成,它类似于Storm这样的流式处理器,专门用于处理实时到达的数据流。
服务层 ( Serving Layer )
服务层包含了读取优化的数据库技术,例如Apache HBase,它存储了批处理层和加速层的输出结果。该层提供了一个统一的视图,结合了历史批处理数据和实时数据流的内容,使得最终用户能够查询一个综合的数据集。
在Lambda架构中,当事件到达时,它们会被同时送入批处理层和加速层。批处理层会定期执行ETL(提取、转换、加载)作业,并创建预聚合的批处理视图,而加速层则对那些尚未被批处理层处理的实时数据进行流处理。这两个层次处理后的结果都会被传递到服务层,由服务层进行整合输出。
当通过服务层进行查询时,系统需要将批处理视图与实时视图的数据进行融合,以确保查询结果的完整性和准确性。这一过程可能会涉及复杂的数据处理逻辑,因为系统需要在向客户端提供结果之前,将这两部分数据无缝拼接。图2-4展示了Lambda架构的组成和工作流程。
图2-4:Lambda架构
Lambda架构的一个显著优势在于其对原始数据流的完整性保护,从而允许用户在未来使用新的处理逻辑对这些数据进行重新分析。这意味着我们能够在加速层和批处理层上不断地试验、调试并优化应用程序代码,这极大地促进了代码的持续进化和改进。
尽管Lambda架构在财富500强公司以及互联网巨头中得到了广泛应用,但那些对实时分析也有强烈需求的中小型组织或早期初创公司却并没有采用它。为什么呢?
我们认为,对Lambda架构的采纳受到三大因素的限制:
技术复杂性
采用如Storm这样的流处理技术,要求开发者具备分布式系统原理和性能工程等高级技能。使用Storm等工具意味着要有能力同时高效管理三个不同的分布式系统——每一层对应一套系统。这不仅需要更多的工程师来运维这些系统,还涉及更多硬件和软件资源的投入。
JVM依赖性
目前大多数主流的流处理器都是基于JVM语言(例如Java和Scala)开发的。这意味着,要顺利使用这些处理器,就必须深入了解JVM相关的知识,包括性能调优和内存问题调试等。这一点对于那些习惯使用Python、C#或Ruby等其他编程语言的开发者或公司来说,构成了一定的门槛。
逻辑冗余性
在复杂的分布式系统中,必须在批处理层和加速层上分别构建、测试和维护处理逻辑。尽管这些逻辑最终旨在产生一致的结果,但它们在各层的工作内容存在重复。
所有这些原因导致了我们今天使用的现代流处理技术栈的形成。