皇上,还记得我吗?我就是1999年那个Linux伊甸园啊-----24小时滚动更新开源资讯,全年无休!

为应用程序选择合适的流式处理器

作者 Miyuru Dayarathna     , Srinath Perera      ,译者 无明 

关键要点

  • 选择一款合适的流式处理器具有一定的挑战性,因为有太多的选择,而最终的选择取决于最终用户的使用场景。
  • 流式SQL提供了更快的应用程序开发速度和高度可维护的部署。
  • 查询编辑环境对开发人员的工作效率有显著的影响,这需要高级图形编辑器和用于流式处理器的调试器。
  • 如果系统需要的吞吐量小于50K事件/秒,那么使用双节点高可用性(HA)部署可节省大量成本。
  • 如果事件速率超出单个流式处理器节点的处理能力,那么就应该将传入事件放入消息代理并启用快照。

流式处理器是一种软件平台,让用户能够更快地响应传入的数据流(请参阅“什么是流式处理?”)。

在流式处理器上运行的流式应用程序有多种形式。

以下是一些示例:

  1. 检测条件并生成警报(例如,跟踪厨房设备的温度并在超过预定阈值时创建警报);
  2. 计算移动物体的移动平均位置并更新网页(例如,检测人的位置并在地图上绘制他的轨迹);
  3. 检测异常并对其采取行动(例如,检测可疑用户并对其行为进行详细分析)。

如果你对其他应用程序感到好奇,可以阅读“13 Stream Processing Patterns for Building Streaming and Real-Time Applications”,这篇博文讨论了更多的用例。

正如Quora上的一个问题“What are the best stream processing solutions out there?”所述,有很多流式处理器可供选择。

选择哪一种流式处理器取决于具体用例,本文将讨论如何做出最合适的选择。

我们通过三个步骤来解决这个问题。首先讨论参考架构和流媒体应用程序解析。

然后我们将讨论大多数流式应用程序需要具备的关键功能。

最后,我们将列出用于不同使用场景的可选功能。

流式应用程序参考架构

流式应用程序需要三件组件:数据流、处理数据的处理器和执行决策的代码(参见图1)。

为应用程序选择合适的流式处理器

图1:流式应用程序参考架构

首先,将从数据源接收到的数据流收集到消息代理的队列中。除非你有特定的要求需要使用不同的设计,否则我们建议你将消息放入消息队列并从消息队列读取消息。在必要的情况下可以重播事件,而且可以简化高可用性(HA)和容错。

流式处理器从消息队列中提取事件,将它们发送到流查询,流查询负责处理数据并生成结果。大多数流式处理器会生成警报、公开或调用API、执行操作以及提供可视化元素。我们以“引言”部分提到的场景为例,就是通过监控室温来检测能源使用的异常情况。应用程序将检测异常,并通过电子邮件发送警报。图2是这个用例的应用程序数据流图。

为应用程序选择合适的流式处理器

图2:用于检测室温异常的流式处理应用程序的架构。

在选择流式处理器时,你需要考虑两种功能:必备功能和可选功能。顾名思义,必备功能就是指肯定会被用到的功能。即使你现在用不到,以后也会用到。你可以根据自己的需要选择可选的功能。本文主要关注必备功能。

必备功能

你应该确保所选的流式处理器支持以下所有功能。

支持使用消息代理进行数据收集

在开发应用程序时,你面临的第一个问题是“应用程序如何从外部数据源接收数据”?答案是使用消息代理,并确保你的流式处理器能够提供支持。大部分流式处理器都提供了这种支持功能。以下是使用消息代理的一些好处:

  1. 立即保存消息。
  2. 消息代理将成为你的高可用端点,而系统的其余部分就不需要高可用。
  3. 如果出现问题,可以重播消息代理中的消息。
  4. 一些可伸缩的消息代理(如Kafka)自动为你处理伸缩性问题。

关于消息代理的更多优点,请参阅文章“Questioning the Lambda Architecture”和“The Log: What every software engineer should know about real-time data’s unifying abstraction”。

流式SQL

第一代流媒体引擎(如Apache StormApache Spark)需要用户编写代码。用户可以将编写的代码放在代理(有时称为actor)中,并将这些代理连接在一起用于收集事件。

虽然这是一种很好的起点,但它需要用户编写代码。容易导致代码重复,并增加了维护成本。

假设你要从数据库获取数据,就需要编写描述如何查找数据的代码。编写流式处理代码并不会好到哪儿去。而在进行批处理时可以不编写代码,可以使用SQL进行查询。我们也可以使用流式分析达到同样的目的,其对应的查询语言被称为流式SQL

以下是流式SQL语言的一些优点:

  • 容易理解,而且很容易招到已经熟悉SQL的开发人员。
  • 它富有表现力、简洁、甜美、速度快。
  • 它定义了涵盖90%问题的核心操作。
  • 流式SQL语言专家可以通过编写扩展来实现特定于应用程序的自定义分析。
  • 查询引擎可以使用流式SQL模型更好地优化查询。

有了流式SQL,用户无需编写代码就能查询数据。流式SQL平台负责处理数据传输、数据解析,并且提供了连接、窗口和模式之类的操作符。清单1显示了异常检测应用程序的流式SQL代码。

清单1:室温异常检测应用程序

@App:name("High Room Temperature Alert")

@App:description('An application which detects abnormal increase of room temperature.')

@source(type='kafka', @map(type='json'), bootstrap.servers='localhost:9092',topic.list='inputStream',group.id='option_value',threading.option='single.thread')
define stream RoomTemperatureStream(roomNo string, temperature double);
	
@sink(type='email', @map(type='text'), ssl.enable='true',auth='true',content.type='text/html', username='sender.account', address='sender.account@gmail.com',password='account.password', subject="High Room Temperature Alert", to="receiver.account@gmail.com")
define stream EmailAlertStream(roomNo string, initialTemperature double, finalTemperature double);

--Capture a pattern where the temperature of a room increases by 5 degrees within 2 minutes
@info(name='query1')
from every( e1 = RoomTemperatureStream ) -> e2 = RoomTemperatureStream [e1.roomNo == roomNo and (e1.temperature + 5.0) <= temperature]
    within 2 min
select e1.roomNo, e1.temperature as initialTemperature, e2.temperature as finalTemperature
insert into EmailAlertStream;

如果流式处理器不支持流式SQL,那么开发流式应用程序就需要花更多的时间。例如,如果你使用Java开发清单1中所示的应用程序,需要花费大量的时间用于编写代码。此外,一旦部署在生产环境中,维护成本是很高的。流式应用程序需要多种运算符,例如转换、聚合/关联、窗口和模式匹配,你必须从头开始编写这些算法。要了解有关流式SQL的更多信息,请阅读“Stream Processing 101: from SQL to Streaming SQL”。

流式处理API和查询编辑环境

你的流式处理器为你提供了哪些工具?大多数众所周知的流式处理器会提供可视化或基于文本的查询编辑器。下图(图3)显示了使用WSO2 Stream Processor编写的查询,这是一个基于Apache 2.0许可证发行的开源流式处理器。这个编辑器支持错误消息可视化和自动完成。流式SQL是一种强大而精致的语言。在编写查询时能够看到输出结果是一个非常重要的优势。第一个级别是能够将事件存档附加到编辑器,重放它们,并查看输出结果。第二个级别是在修改查询时立即看到不同的结果。

为应用程序选择合适的流式处理器

图3:室温警报应用程序在Stream Processor Studio中的代码视图

几乎所有的流式处理器都支持应用程序调试,但支持的程度各不相同。有些调试器可以设置断点,并检查中间变量值(图4),有些则提供事件日志。有些调试器提供可见的度量指标,如操作符之间的事件流量计数。

如果无法进行调试,那么诊断流式应用程序的行为就会变得非常困难。你应该选择具有广泛调试支持的流式处理器,在编辑和维护查询期间可以帮你节省很多时间。

为应用程序选择合适的流式处理器

图4:在Stream Processor Studio中调试室温警报应用程序

一些流式处理器还提供拖放式的图形用户界面(图5)。拖放式GUI通常会提供一个工具箱,其中包含可拖放的元素,以及用于放置这些元素的双向可滚动画布。工具箱中可能还包含用于定义流的图标、操作符(如window、join和filter)。在将流式操作符放置到画布上之后,可以通过操作符的设置向导来修改每个操作符的属性。

为应用程序选择合适的流式处理器

图5:Stream Processor Studio的图形编辑器,显示了室温警报应用程序的应用程序数据流图

虽然Stream Processor Studio做了很棒的演示,但我们也不清楚拖放式界面是否适合用来构建应用程序。例如,在SQL方面,这样的界面从未被广泛使用过。SQL查询是通过直接编写SQL代码来完成的。不懂编程的业务人员可以使用拖放工具箱,但即使是这样,他们也需要通过学习编程来提升基础知识。

可靠性、高可用性(HA)和最小HA

如果你的系统突然发生崩溃会怎样?流式处理应用程序会一直运行下去,永不停止。因此,如果你的应用程序是有状态的,那么它就会因为系统故障而丢失有价值的信息(例如状态)。我们将从故障中恢复的能力称为“可靠性”,我们将能够以最小的中断保持持续运行的能力称为高可用性(HA)。

状态管理

大多数流式查询都是有状态的。那么应该在哪里保存和读取状态?状态是流式处理器记住的事件之间的信息。

状态有三种类型:应用程序状态,用户状态和系统状态。

应用程序状态是指在运行应用程序时创建和维护的值。例如在检测条件时所需的状态:一个时间窗口内的模式或内容。应用程序状态驻留在临时存储(图6)中,例如主内存,并被定期刷新到永久存储中。

用户状态是应用程序用来在做出运行时决策的用户数据。例如,RDBMS中包含的用户信用历史信息。

系统状态是指框架提供的其他信息,以确保在流式处理器崩溃时,可以利用这些信息恢复到正常状态。

为应用程序选择合适的流式处理器

图6:带有数据存储的数据流式处理器

高可用的流式处理器需要借助可靠且具备容错能力的状态管理,避免状态丢失。用户状态直接保存在持久性存储中。流式处理器通过主备部署、快照或重新计算来恢复应用程序和系统状态。

发生崩溃后,重新计算将从上一个已知的良好状态处开始重播事件,继续后续的执行。但是,如果应用程序是有状态的,那么上一个已知的良好状态是在开头,这通常会导致重播和重新处理大量的事件。

为避免重播大量事件,流式处理器可以定期获取快照。然后,它可以将状态还原到快照处,并从快照那里开始重播事件。

最小的HA部署

大部分流式处理器的单个节点每秒可以处理超过50,000个事件,而大多数场景所需的最高吞吐量远低于50,000事件/秒,它们通常需要的节点不会超过两个。因此,使用主备部署可以节省大量成本。例如,请参阅文章“Is Your Stream Processor Obese?”。

回压

如果应用程序收到的事件超出了它的处理能力,会发生什么?在流式处理器中,回压起到维持系统稳定性的作用,它将拒绝接受过多的事件。

我们需要在流式处理器的各个层面使用回压才能让它发挥作用。回压将负载转回给了事件源,避免出现队列溢出和内存不足的错误。由于流式处理器停止接受来自外部系统的新事件,外部系统就必须缓冲数据,甚至会在缓冲区溢出时将数据丢弃掉。

如果可以使用动态缩放,那么系统就可以自动缩放而不是使用回压。然而,没有一个系统是可以无限扩展的,当它达到极限时,就需要采用回压。

在选择流式处理器时,这是需要考虑的一个关键功能。

可靠的HA建议

要选择可靠的HA模型,你需要仔细考虑。

如果你需要处理的事件速率在单个流式处理器节点的容量范围内,我们建议进行以下部署。将传入事件放入消息代理中,然后部署两个流式处理器节点(主备模式),让它们消费消息代理中的事件。不过,在活动节点发生崩溃或进行主备切换时,流式处理器需要能够检测到。

如果事件速率超出单个流式处理器节点的容量,那么就应该将传入事件放入消息代理,并启用快照。如果发生故障,流式处理器可以使用快照还原状态并从快照处开始重播事件。

可选功能

前一节讨论了大多数流式应用程序所需的基本功能。相反,以下是一些可能只有某些特定应用程序会用到的可选功能。

  • 拖放式图形用户界面(GUI)
  • 流式机器学习
  • 可选的可靠性功能
    • 消息处理保证
    • 无序事件
  • 大规模系统性能
    • 可伸缩性
    • 处理大窗口数据

由于篇幅有限,本文不讨论更多的可选功能,我们计划在以后的文章中介绍它们。

结论

本质上,不同的流式处理器适用于不同的使用场景。在选择合适的流式处理器时,你必须在多个方面仔细权衡才能做出正确的选择。

本文讨论了流式处理的参考架构,并提出了一种选择流式处理器的系统性方法。首先,流式处理器对核心的流式处理器功能支持到怎样的程度?其次,应用程序的特殊需求是什么,以及流式处理器能够满足这些要求到怎样的程度?前者是本文的重点,后者将在以后的文章中详细讨论。图7显示了在选择流式处理器时需要考虑的功能分类。

为应用程序选择合适的流式处理器

图7:流式处理器的功能分类

本文详细讨论了每个核心功能及其重要性,同时提供了有关如何选择最符合应用程序性质的流式处理器的指南。

关于作者

为应用程序选择合适的流式处理器Miyuru Dayarathna 是WSO2的高级技术主管。他是一名计算机科学家,对流式处理、图形数据管理和挖掘、云计算、性能工程、物联网有浓厚的研究兴趣,并做出了诸多贡献。他还是斯里兰卡莫拉图瓦大学计算机科学与工程系的顾问。他在知名的国际期刊和会议上发表了技术论文,并组织了几次有关高性能图形数据管理和处理的国际性研讨会。

为应用程序选择合适的流式处理器Srinath Perera 是一名科学家、软件架构师以及从事分布式系统工作的程序员。他是Apache软件基金会成员,Apache Axis2WSO2 Stream Processor等几个项目的关键架构师。Srinath撰写了两本有关MapReduce的书,并经常撰写其他技术文章。他获得了博士学位。他自2002年以来一直参与Apache Web Services项目,也是几个Apache开源项目的提交者,包括Apache Axis、Axis2和Geronimo。

查看英文原文How to Choose a Stream Processor for Your App