【颠覆数据处理的利器】全面解读Apache Flink实时大数据处理的引擎-上篇

什么是 Apache Flink?

Apache Flink 是一个框架和分布式处理引擎,用于对无界和有界数据流进行有状态计算。Flink 被设计为在所有常见的集群环境中运行,以内存速度和任何规模执行计算。

如何理解无界和有界数据?

无界数据(Unbounded Data)

无界数据是指持续不断生成、没有明确结束点的数据流。这些数据流在时间上是无限的,可以一直产生新的数据。
特点:

  1. 持续性: 无界数据源源不断,常见于实时监控、传感器数据、日志流、社交媒体数据等。
  2. 实时处理: 由于数据没有终点,处理必须实时进行,通常需要低延迟的响应。
  3. 窗口操作: 为了能够处理和分析无界数据,通常会使用窗口(window)操作,将数据流分成有限的小片段进行处理。窗口可以基于时间(时间窗口)或数量(计数窗口)。

例如:

电商网站上的用户点击流,可以无限期地生成点击事件,或者社交媒体上的实时消息流如朋友圈,微博等等。

有界数据(Bounded Data)

有界数据是指有限的、可以确定开始和结束的数据集。处理有界数据通常是批处理的典型特征。
特点:

  1. 有限性: 有界数据有明确的开始和结束,可以一次性加载和处理。
  2. 批处理: 处理可以一次性完成,不需要像无界数据那样持续监听和处理。
  3. 易于管理: 由于数据集是有限的,可以更容易地进行多次重复处理、测试和调试。

例如:

一天的服务器日志文件,数据集是固定大小的,可以一次性处理或者过去一个月的销售数据,用于生成月度报告。

总结:

  1. 无界流有开始但没有明确的结束。它们不会终止,也不会在生成数据时提供数据。无界流必须持续处理,即事件必须在被摄取后立即处理。不可能等待所有输入数据到达,因为输入是无界的,并且在任何时间点都不会完成。处理无界数据通常需要以特定顺序(例如事件发生的顺序)摄取事件,以便能够推断结果的完整性。
  2. 有界流具有定义的开始和结束。有界流可以通过在执行任何计算之前提取所有数据来处理。处理有界流不需要有序提取,因为有界数据集始终可以排序。有界流的处理也称为批处理。

Apache Flink 擅长处理无界和有界数据集。精确的时间和状态控制使 Flink 的运行时能够在无界流上运行任何类型的应用程序。有界流由专门为固定大小数据集设计的算法和数据结构在内部处理,从而获得出色的性能。

数据流处理(Stream Processing)和批处理(Batch Processing)对比

数据流处理示例:

java 复制代码
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
DataStream<String> inputStream = env.socketTextStream("localhost", 9999);

DataStream<Tuple2<String, Integer>> wordCounts = inputStream
    .flatMap(new Tokenizer())
    .keyBy(0)
    .timeWindow(Time.seconds(10))
    .sum(1);

wordCounts.print();
env.execute("Stream WordCount");

批处理示例:

java 复制代码
ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
DataSet<String> text = env.readTextFile("input.txt");

DataSet<Tuple2<String, Integer>> wordCounts = text
    .flatMap(new Tokenizer())
    .groupBy(0)
    .sum(1);

wordCounts.writeAsCsv("output.csv", "\n", " ");
env.execute("Batch WordCount");

总结:

数据流处理和批处理各有其应用场景和优势。数据流处理适用于实时性要求高、需要持续处理数据的场景,而批处理适用于数据量大、需要对完整数据集进行分析的场景。

不过市面上大部分使用Flink的情况来看,都是基于流数据处理的场景使用。

为什么使用Apache Fink?

  • 事件导向性应用程式,从一个或多个事件串流撷取事件,以及执行运作、状态更新或外部动作。借助有状态处理,可在单一讯息转换之外实现逻辑,其中结果取决于撷取事件的历史记录。
  • 资料分析应用程式,从资料中撷取资讯和洞见。传统上,透过查询有限资料集、重新执行查询或修改结果以纳入新资料来执行。借助Apache Flink,可以透过持续更新、串流查询或即时处理撷取的事件、持续发出和更新结果来执行分析。
  • 资料管线应用程式,其中转换和丰富要从一个资料储存移动到另一个资料储存的资料。传统上,提取-转换-载入(ETL) 会定期批次执行。借助Apache Flink,可以持续执行该程序,将资料以低延迟移动到其目标。

利用内存性能

有状态的 Flink 应用程序针对本地状态访问进行了优化。任务状态始终保存在内存中,如果状态大小超出可用内存,则保存在访问效率高的磁盘数据结构中。因此,任务通过访问本地(通常是内存中的)状态来执行所有计算,从而产生非常低的处理延迟。Flink 通过定期和异步地将本地状态检查点到持久存储来保证在发生故障时实现精确一次的状态一致性。

## 状态

每个重要的流式处理应用程序都是有状态的,也就是说,只有对单个事件进行转换的应用程序才不需要状态。任何运行基本业务逻辑的应用程序都需要记住事件或中间结果,以便在以后的某个时间点访问它们,例如在收到下一个事件时或在特定持续时间之后。

应用程序状态是 Flink 中的一等公民。通过查看 Flink 在状态处理上下文中提供的所有功能,您可以看到这一点。

  • 多种状态原语:Flink 为不同的数据结构提供状态原语,例如原子值、列表或映射。开发人员可以根据函数的访问模式选择最高效的状态原语。
  • 可插入状态后端:应用程序状态由可插入状态后端进行管理和检查。Flink 具有不同的状态后端,可将状态存储在内存中或RocksDB(一种高效的嵌入式磁盘数据存储)中。也可以插入自定义状态后端。
  • 精确一次状态一致性:Flink 的检查点和恢复算法保证在发生故障时应用程序状态的一致性。因此,故障是透明处理的,不会影响应用程序的正确性。
  • 非常大的状态:由于异步和增量检查点算法,Flink 能够维护几 TB 大小的应用程序状态。
  • 可扩展的应用程序:Flink 通过将状态重新分配给更多或更少的工作程序来支持有状态应用程序的扩展。

时间

时间是流式应用程序的另一个重要组成部分。大多数事件流具有固有的时间语义,因为每个事件都是在特定时间点产生的。此外,许多常见的流计算都是基于时间的,例如窗口聚合、会话化、模式检测和基于时间的连接。流处理的一个重要方面是应用程序如何测量时间,即事件时间和处理时间之间的差异。

Flink 提供了丰富的时间相关功能。

  • 事件时间模式:使用事件时间语义处理流的应用程序根据事件的时间戳计算结果。因此,无论处理记录事件还是实时事件,事件时间处理都能提供准确且一致的结果。
  • 水印支持:Flink 使用水印来推理事件时间应用程序中的时间。水印也是一种灵活的机制,可以权衡结果的延迟和完整性。
  • 延迟数据处理:在使用水印的事件时间模式下处理流时,可能会发生计算在所有相关事件到达之前就被视为已完成的情况。此类事件称为延迟事件。Flink 提供多种选项来处理延迟事件,例如通过侧输出重新路由它们并更新先前完成的结果。
  • 处理时间模式:除了事件时间模式之外,Flink 还支持处理时间语义,该语义由处理机的挂钟时间触发执行计算。处理时间模式适用于某些具有严格低延迟要求且可以容忍近似结果的应用程序。

分层

Flink 提供了三层 API,每层 API 在简洁性和表现力之间做了不同的权衡,并针对不同的用例。

Flink 是一款高输送量、低延迟的串流处理引擎。 Flink 应用程式由任意复杂的无环图资料流图组成,其中该图形包含串流和转换。资料从一个或多个资料来源撷取并传送到一个或多个目标。来源系统和目标系统可以是串流、讯息伫列或资料储存,包括档案、常用资料库和搜寻引擎。转换可以具有状态性,例如在时间段内进行的汇总或复杂的模式侦测。

透过两种不同的机制实现容错:以检查点自动和定期检查应用程式状态,将其复制到持久性储存中,以便在出现故障时自动复原;随需储存点,其中储存一致的执行状态映射,允许停止和恢复、更新或分流您的Flink 作业,在停止和重新启动后保留应用程式状态。检查点和储存点机制是非同步的,在不「停止世界转动」的情况下拍摄一致的状态快照,而应用程式则会继续处理事件。

什么是事件驱动的应用程序?

事件驱动的应用程序是一种有状态的应用程序,它从一个或多个事件流中提取事件,并通过触发计算、状态更新或外部操作对传入事件做出反应。

事件驱动型应用程序是传统应用程序设计的演变,具有分离的计算层和数据存储层。在此架构中,应用程序从远程事务数据库读取数据并将数据保存到其中。

相比之下,事件驱动型应用程序基于有状态的流处理应用程序。在这种设计中,数据和计算位于同一位置,从而产生本地(内存或磁盘)数据访问。通过定期将检查点写入远程持久存储来实现容错。下图描述了传统应用程序架构与事件驱动型应用程序之间的区别。


事件驱动的应用程序有哪些优点?

事件驱动的应用程序无需查询远程数据库,而是可以在本地访问其数据,从而在吞吐量和延迟方面获得更好的性能。对远程持久存储的定期检查点可以是异步和增量的。因此,检查点对常规事件处理的影响非常小。但是,事件驱动的应用程序设计提供的好处不仅仅是本地数据访问。在分层架构中,多个应用程序共享同一个数据库是很常见的。因此,任何数据库更改(例如由于应用程序更新或扩展服务而更改数据布局)都需要进行协调。由于每个事件驱动的应用程序都负责自己的数据,因此更改数据表示或扩展应用程序所需的协调较少。

Flink 如何支持事件驱动的应用程序?

事件驱动应用程序的极限取决于流处理器处理时间和状态的能力。Flink 的许多出色功能都围绕这些概念展开。Flink 提供了一组丰富的状态原语,可以管理非常大的数据量(高达几 TB),并保证一次一致性。此外,Flink 对事件时间、高度可定制的窗口逻辑和细粒度的时间控制的支持使ProcessFunction高级业务逻辑的实现成为可能。此外,Flink 还具有一个复杂事件处理 (CEP) 库来检测数据流中的模式。

然而,Flink 对于事件驱动应用程序的突出功能是它对保存点的支持。保存点是一个一致的状态映像,可以用作兼容应用程序的起点。给定保存点,可以更新应用程序或调整其规模,或者可以启动应用程序的多个版本进行 A/B 测试。

什么是数据分析应用程序?

分析作业从原始数据中提取信息和见解。传统上,分析是以对记录事件的有界数据集进行批量查询或应用的方式执行的。为了将最新数据纳入分析结果,必须将其添加到已分析的数据集中,然后重新运行查询或应用。结果将写入存储系统或作为报告发出。

借助复杂的流处理引擎,分析也可以实时进行。流式查询或应用程序不是读取有限的数据集,而是获取实时事件流,并在事件被使用时不断生成和更新结果。结果要么写入外部数据库,要么作为内部状态保存。仪表板应用程序可以从外部数据库读取最新结果,或者直接查询应用程序的内部状态。

Apache Flink 支持流式和批量分析应用程序,如下图所示。

流分析应用程序有哪些优势?

与批量分析相比,连续流式分析的优势不仅限于由于消除了定期导入和查询执行,从事件到洞察的延迟大大降低。与批量查询相比,流式查询不必处理输入数据中的人为边界,这些边界是由定期导入和输入的有界性质造成的。

另一方面是更简单的应用程序架构。批量分析管道由几个独立的组件组成,用于定期安排数据提取和查询执行。可靠地操作这样的管道并非易事,因为一个组件的故障会影响管道的后续步骤。相比之下,在 Flink 等复杂的流处理器上运行的流分析应用程序包含从数据提取到连续结果计算的所有步骤。因此,它可以依赖引擎的故障恢复机制。

Flink 如何支持数据分析应用程序?

Flink 为连续流和批量分析提供了非常好的支持。具体来说,它具有符合 ANSI 标准的 SQL 接口,具有统一的批处理和流式查询语义。无论是在记录事件的静态数据集上运行,还是在实时事件流上运行,SQL 查询都会计算相同的结果。对用户定义函数的丰富支持确保可以在 SQL 查询中执行自定义代码。如果需要更多自定义逻辑,Flink 的 DataStream API 或 DataSet API 可提供更多低级控制。

什么是数据管道?

提取-转换-加载 (ETL) 是一种在存储系统之间转换和移动数据的常用方法。通常会定期触发 ETL 作业,以将数据从事务数据库系统复制到分析数据库或数据仓库。

数据管道的作用与 ETL 作业类似。它们转换和丰富数据,并可以将数据从一个存储系统移动到另一个存储系统。但是,它们以连续流模式运行,而不是定期触发。因此,它们能够从连续产生数据的源读取记录,并以低延迟将其移动到目的地。例如,数据管道可能会监视文件系统目录中的新文件并将其数据写入事件日志。另一个应用程序可能会将事件流具体化到数据库或逐步构建和优化搜索索引。

下图描述了周期性 ETL 作业和连续数据管道之间的区别。

数据管道有哪些优点?

与定期 ETL 作业相比,连续数据管道的明显优势在于减少了将数据移动到目的地的延迟。此外,数据管道更加灵活,可以用于更多用例,因为它们能够连续消费和发送数据。

Flink 如何支持数据管道?

Flink 的 SQL 接口(或 Table API)及其对用户定义函数的支持可以解决许多常见的数据转换或丰富任务。具有更高级要求的数据管道可以通过使用更通用的 DataStream API 来实现。Flink 为各种存储系统(如 Kafka、Kinesis、Elasticsearch 和 JDBC 数据库系统)提供了一组丰富的连接器。它还具有用于监视目录的文件系统的连续源和以时间段方式写入文件的接收器。

Flink 运行时由两种类型的进程组成:一个JobManager和一个或多个TaskManagers。

JobManager

JobManager具有许多与协调 Flink 应用程序的分布式执行相关的职责:它决定何时安排下一个任务(或一组任务)、对已完成的任务或执行失败做出反应、协调检查点以及协调故障恢复等。此过程由三个不同的组件组成:

  • ResourceManager 资源管理器

    ResourceManager负责 Flink 集群中的资源解除/分配和配置 - 它管理任务槽,任务槽是 Flink 集群中的资源调度单位(请参阅TaskManagers)。Flink 为不同的环境和资源提供者(如 YARN、Kubernetes 和独立部署)实现了多个 ResourceManager。在独立设置中,ResourceManager 只能分配可用 TaskManager 的槽,而不能自行启动新的 TaskManager。

  • Dispatcher 调度员

    Dispatcher提供 REST 接口来提交 Flink 应用程序以供执行,并为每个提交的作业启动一个新的 JobMaster。它还运行 Flink WebUI 来提供有关作业执行的信息。

  • JobMaster 工作大师

    JobMaster负责管理单个 JobGraph的执行。Flink 集群中可以同时运行多个作业,每个作业都有自己的 JobMaster 。

始终至少有一个 JobManager。高可用性设置可能有多个 JobManager,其中一个始终是领导者,其他的是待机的。

TaskManagers

TaskManagers (也称为worker ) 执行数据流的任务,并缓冲和交换数据流。

必须始终至少有一个 TaskManager。TaskManager 中资源调度的最小单位是任务槽。TaskManager 中的任务槽数量表示并发处理任务的数量。请注意,一个任务槽中可以执行多个算子。

任务和操作链

对于分布式执行,Flink将运算符子任务链接在一起形成 任务。每个任务由一个线程执行。将运算符链接在一起形成任务是一种有用的优化:它减少了线程间切换和缓冲的开销,并在降低延迟的同时提高了整体吞吐量。可以配置链接行为

下图中的示例数据流由五个子任务执行,因此有五个并行线程。

任务槽和资源

每个工作器 (TaskManager) 都是一个JVM 进程,可以在单独的线程中执行一个或多个子任务。为了控制 TaskManager 接受的任务数量,它具有所谓的任务槽(至少一个)。

每个任务槽代表 TaskManager 的固定资源子集。例如,具有三个槽的 TaskManager 将为每个槽分配 1/3 的托管内存。将资源划分为槽意味着子任务不会与其他作业的子任务争夺托管内存,而是拥有一定数量的预留托管内存。请注意,这里没有 CPU 隔离;目前槽仅将任务的托管内存分开。

通过调整任务槽的数量,用户可以定义子任务如何相互隔离。每个 TaskManager 有一个槽意味着每个任务组在单独的 JVM 中运行(例如,可以在单独的容器中启动)。拥有多个槽意味着更多子任务共享同一个 JVM。同一个 JVM 中的任务共享 TCP 连接(通过多路复用)和心跳消息。它们还可以共享数据集和数据结构,从而减少每个任务的开销。

默认情况下,Flink 允许子任务共享 slot,即使它们是不同任务的子任务,只要它们来自同一个作业即可。结果是一个 slot 可能容纳该作业的整个管道。允许这种slot 共享有两个主要好处:

  • Flink 集群需要的任务槽数量与作业中使用的最高并行度完全相同。无需计算程序总共包含多少个任务(具有不同的并行度)。
  • 更容易获得更好的资源利用率。如果没有插槽共享,非密集型source/map()子任务将阻塞与资源密集型窗口子任务一样多的资源。有了插槽共享,将示例中的基本并行度从 2 增加到 6,可以充分利用插槽资源,同时确保繁重的子任务在 TaskManager 之间公平分配。

参考文献:
Apache Flink 官网
Apache Flink 文档
亚马逊云-什么是 Apache Flink?

相关推荐
TDengine (老段)1 小时前
TDengine 新功能 通过 UID 删除不可见表
大数据·数据库·物联网·时序数据库·tdengine
ccc_9wy2 小时前
Apache Solr RCE(CVE-2017-12629)--vulhub
apache·solr·lucene·burp suite·vulhub·远程命令执行漏洞rce·cve-2017-12629
Ekine2 小时前
【Flink-scala】DataStream编程模型之状态编程
大数据·flink·scala
m0_672449603 小时前
Java前后端分离实现登陆
java·大数据·开发语言
老板多放点香菜3 小时前
AI、大数据、机器学习、深度学习、神经网络之间的关系
大数据·人工智能·深度学习·神经网络·机器学习
隔着天花板看星星4 小时前
Spark-Streaming receiver模式源码解析
大数据·分布式·spark
Font Tian5 小时前
联邦学习防止数据泄露
大数据·人工智能·数据治理·数据科学·联邦学习
美林数据Tempodata5 小时前
夯实数字技术,培育创新人才:数据科学与大数据技术专业人才培养实践
大数据·高校大数据人才·数智人才培养
ccc_9wy6 小时前
Apache Solr RCE(CVE-2019-0193)--vulhub
网络安全·apache·solr·lucene·vulhub·cve-2019-0193·远程命令执行漏洞rce
新加坡内哥谈技术6 小时前
OpenAI 第七日 推出了一项新功能——ChatGPT的“Projects”
大数据·人工智能·语言模型·自然语言处理·chatgpt