一、事件驱动型应用 1.1 事件驱动型应用 事件驱动型应用是一种软件设计模式,它的工作方式就像在等待和响应事件的触发一样。我们可以把它类比成一个门铃系统: ……
事件驱动型应用是一种软件设计模式,它的工作方式就像在等待和响应事件的触发一样。我们可以把它类比成一个门铃系统:
想象你在家里,门上装有一个门铃。当有人按下门铃时,你会听到门铃声并知道有人来访。在这个情况下,门铃的按下是一个事件,你的反应是对这个事件做出回应。
在事件驱动型应用中,程序也会等待类似的事件发生,比如用户的点击、键盘输入、网络请求、定时器触发等等。一旦这些事件发生,程序会立即捕获它们并相应地执行预定义的操作,就像你听到门铃声后会去开门一样。
这种模式的好处在于,它使得程序可以高效地响应外部的变化和用户的交互,而不需要事先预定特定的顺序或流程。就像你不需要一直守在门边等待访客一样,程序也不需要长时间忙碌地等待某些事情的完成,而是可以专注于处理实际发生的事件。
事件驱动型应用在很多地方都有应用,比如电脑上的应用程序、手机上的APP,甚至是互联网上的网站和服务器。它使得软件更加灵活、高效,并能够适应各种复杂的场景和需求。
当谈到事件驱动型应用时,以下是一些更具体的例子:
- 图形界面应用程序(GUI 应用):常见的桌面程序,如文本编辑器、图片浏览器和音乐播放器,都是事件驱动型的。当用户点击按钮、输入文本或拖动窗口时,程序会相应地捕获这些事件并做出对应的操作。
- 游戏:电子游戏通常也是事件驱动型的。游戏中的玩家动作(比如按键、鼠标点击)会触发事件,游戏引擎捕获这些事件并更新游戏场景、角色动画等。
- 网络应用:Web 应用也是事件驱动型的。当用户在浏览器中点击链接、提交表单或滚动页面时,浏览器会生成相应的事件,Web 应用程序会通过事件来处理这些用户操作。
- 操作系统:操作系统本身也是事件驱动型的。它需要监听和处理各种硬件和软件事件,比如键盘输入、鼠标移动、网络请求、磁盘读写等等。
- 物联网设备:智能家居设备、传感器等物联网设备也使用事件驱动型应用。当某个传感器探测到环境变化(如温度、湿度、光线等),设备会相应地产生事件并触发相应的操作。
- 消息队列系统:消息队列是一种事件驱动型的通信机制,用于在分布式系统中传递和处理消息。当一个系统产生消息时,它会被发送到消息队列,然后其他系统可以订阅这些消息并相应地处理它们。
这些例子展示了事件驱动型应用的广泛应用领域。它使得软件能够更加灵活、响应更快,并且能够处理复杂的用户交互和系统间通信。
站在 Flink 的视角,事件驱动型应用是有状态的流应用程序,它从一个或多个事件流提取数据,并根据到来的事件触发计算、状态更新或其他外部动作。根据业务逻辑,事件驱动的应用程序可以触发诸如发送警报、或电子邮件之类的操作,或者将事件写入向外发送的事件流以供另一个应用程序使用。
事件驱动应用程序是微服务的演变。它们通过事件日志而不是 REST 调用进行通信,并将应用程序数据保存为本地状态,而不是将其写入外部数据存储区(例如关系数据库或键值数据库)。如下图显示了由事件驱动的流应用程序组成的服务架构。
如上图中的应用程序通过事件日志连接。一个应用程序将其输出发送到事件日志通道(Kafka),另一个应用程序使用其他应用程序发出的事件。事件日志通道将发送者和接收者分离,并提供异步、非阻塞的事件传输。每个应用程序都可以是有状态的,并且可以本地管理自己的状态而无需访问外部数据存储。应用程序也可以单独处理和扩展。
与事务性应用程序或微服务相比,事件驱动的应用程序具有多种优势。与读写远程数据库相比,本地状态访问提供了非常好的性能。扩展性和容错性都由流处理器来保证,并且以事件日志作为输入源,应用程序的整个输入数据可以可靠地存储,并且可以确定性地重放。此外,Flink 可以将应用程序的状态重置为先前的保存点(Savepoint),从而可以在不丢失状态的情况下更新或重新扩展应用程序。
事件驱动的应用程序对运行它们的流处理器有很高的要求,并不是所有流处理器都适合运行事件驱动的应用程序。API 的表现力,以及对状态处理和事件时间支持的程度,决定了可以实现和执行的业务逻辑。这方面取决于流处理器的 API,主要看它能提供什么样的状态类型,以及它对事件时间处理的支持程度。此外,精确一次(Exactly-Once)的状态一致性和扩展应用程序的能力是事件驱动应用程序的基本要求。Apache Flink 符合所有的这些要求,是运行此类应用程序的一个非常好的选择。
总结:事件驱动型应用是在计算存储分离的传统应用基础上进化而来。在传统架构中,应用需要读写远程事务型数据库。相反,事件驱动型应用是基于状态化流处理来完成。在该设计中,数据和计算不会分离,应用只需访问本地(内存或磁盘)即可获取数据。系统容错性的实现依赖于定期向远程持久化存储写入 Checkpoint。
在 Flink 中,事件驱动型应用通常遵循以下模式:
- 事件源:事件源是数据流的起点,可以是消息队列、Kafka 主题、Socket 连接、文件等。数据以事件的形式进入 Flink 应用。
- 事件处理:Flink 应用会定义一系列数据处理逻辑,这些逻辑会根据事件的内容和属性对事件进行转换、过滤、聚合等操作。
- 时间语义:事件驱动型应用通常需要处理事件的时间属性。Flink 支持不同的时间语义,比如事件时间(Event Time)、处理时间(Processing Time)和摄入时间(Ingestion Time)。
- 状态管理:对于一些需要跨事件保持状态的计算,Flink 提供了状态管理机制,允许应用程序在处理事件时存储和更新状态信息。
- 输出结果:处理后的事件流可以输出到文件、数据库、消息队列等,也可以将结果发送回其他系统。
Flink 的事件驱动型应用优势在于它能够以低延迟、高吞吐量的方式处理实时数据流。它的流式处理模型让开发人员可以轻松构建复杂的数据流处理应用,适用于多种场景,如实时监控、实时分析、实时报警、实时推荐等。
需要注意的是,虽然 Flink 强调了事件驱动型的特性,但它也可以用于批处理任务。Flink 提供了统一的 API,允许开发人员在同一个平台上实现流处理和批处理任务,提供了更大的灵活性和一致性。
下图描述了传统应用和事件驱动型应用架构的区别。
1.2 事件驱动型应用的优势
事件驱动型应用无须查询远程数据库,本地数据访问使得它具有更高的吞吐和更低的延迟。而由于定期向远程持久化存储的 checkpoint 工作可以异步、增量式完成,因此对于正常事件处理的影响甚微。事件驱动型应用的优势不仅限于本地数据访问。传统分层架构下,通常多个应用会共享同一个数据库,因而任何对数据库自身的更改(例如:由应用更新或服务扩容导致数据布局发生改变)都需要谨慎协调。反观事件驱动型应用,由于只需考虑自身数据,因此在更改数据表示或服务扩容时所需的协调工作将大大减少。
事件驱动应用程序的典型场景包括:
- 实时推荐(例如,在客户浏览零售商网站时推荐产品)
- 行为模式检测或复杂事件处理(例如,用于信用卡交易中的欺诈检测)
- 异常检测(例如,检测侵入计算机网络的尝试)
- 基于规则的报警
- 业务流程监控
- 社交网络舆情告警
- 反欺诈和羊毛党
二、数据管道应用
2.1 什么是数据管道
当今的 IT 架构包括许多不同的数据存储,例如关系型数据库和专用数据库系统、事件日志、分布式文件系统,内存中的缓存和搜索索引。所有这些系统都以不同的格式和数据结构存储数据,为其特定的访问模式提供最佳性能。公司通常将相同的数据存储在多个不同的系统中,以提高数据访问的性能。
在存储系统之间进行数据转换和迁移的常用方法是定期 ETL(提取–转换–加载) 作业。ETL 作业通常会周期性地触发,将数据从事务型数据库拷贝到分析型数据库或数据仓库。但是,它们不能满足当今许多场景的低延迟要求。
数据管道和 ETL 作业的用途相似,都可以转换、丰富数据,并将其从某个存储系统移动到另一个。但数据管道是以持续流模式运行,而非周期性触发。因此它支持从一个不断生成数据的源头读取记录,并将它们以低延迟移动到终点。例如:数据管道可以用来监控文件系统目录中的新文件,并将其数据写入事件日志;另一个应用可能会将事件流物化到数据库或增量构建和优化查询索引。
以较低的延迟来提取、转换和插入数据是有状态流处理应用程序的另一个常见应用场景。这种类型的应用程序称为数据管道(Data Pipeline)。数据管道必须能够在短时间内处理大量数据。操作数据管道的流处理器还应具有许多源(Source)和接收器(Sink)的连接器,以便从各种存储系统读取数据并将数据写入各种存储系统。当然,Flink 完成了所有这些功能。
下图描述了周期性 ETL 作业和持续数据管道的差异。
2.2 数据管道的优势
和周期性 ETL 作业相比,持续数据管道可以明显降低将数据移动到目的端的延迟。此外,由于它能够持续消费和发送数据,因此用途更广,支持用例更多。
典型的数据管道应用实例:
- 电子商务中的实时查询索引构建
- 电子商务中的持续 ETL
三、 数据分析应用
3.1 什么是数据分析应用
数据分析任务需要从原始数据中提取有价值的信息和指标。传统的分析方式通常是利用批查询,或将事件记录下来并基于此有限数据集构建应用来完成。为了得到最新数据的分析结果,必须先将它们加入分析数据集并重新执行查询或运行应用,随后将结果写入存储系统或生成报告。
借助一些先进的流处理引擎,还可以实时地进行数据分析。和传统模式下读取有限数据集不同,流式查询或应用会接入实时事件流,并随着事件消费持续产生和更新结果。这些结果数据可能会写入外部数据库系统或以内部状态的形式维护。仪表展示应用可以相应地从外部数据库读取数据或直接查询应用的内部状态。
如下图所示,Apache Flink 同时支持流式及批量分析应用。
3.2 流式分析应用的优势
ETL 作业定期将数据导入数据存储区,数据的处理是由即席查询(用户自定义查询)或设定好的通常查询来做的。无论架构是基于数据仓库还是基于 Hadoop 生态系统的组件,这都是批处理。多年来最好的处理方式就是,定期将数据加载到数据分析系统中,但它给分析管道带了的延迟相当大,而且无法避免。
根据设定好的时间间隔,可能需要数小时或数天才能将数据点包含在报告中。我们前面已经提到,数据管道可以实现低延迟的 ETL,所以在某种程度上,可以通过使用数据管道将数据导入存储区来减少延迟。但是,即使持续不停地进行 ETL 操作,在用查询来处理事件之前总会有延迟。虽然这种延迟在过去可能是可以接受的,但是今天的应用程序,往往要求必须能够实时收集数据,并立即对其进行操作(例如,在手机游戏中去适应不断变化的条件,或者在电商网站中提供个性化的用户体验)。
流式分析应用程序不是等待定期触发,而是连续地提取事件流,并且通过纳入最新事件来更新其计算结果,这个过程是低延迟的。通常,流应用程序将其结果存储在支持更新的外部数据存储中,例如数据库或键值(key-value)存储。流分析应用程序的实时更新结果可用于驱动监控仪表板(Dashboard)应用程序,如下图所示。
和批量分析相比,由于流式分析省掉了周期性的数据导入和查询过程,因此从事件中获取指标的延迟更低。不仅如此,批量查询必须处理那些由定期导入和输入有界性导致的人工数据边界,而流式查询则无须考虑该问题。
另一方面,流式分析会简化应用抽象。批量查询的流水线通常由多个独立部件组成,需要周期性地调度提取数据和执行查询。如此复杂的流水线操作起来并不容易,一旦某个组件出错将会影响流水线的后续步骤。而流式分析应用整体运行在 Flink 之类的高端流处理系统之上,涵盖了从数据接入到连续结果计算的所有步骤,因此可以依赖底层引擎提供的故障恢复机制。
典型的数据分析应用实例
- 电信网络质量监控
- 移动应用中的产品更新及实验评估分析
- 消费者技术中的实时数据即席分析
- 大规模图分析
还没有评论呢,快来抢沙发~