《Flink实战与性能优化》阅读总结

简介

《Flink实战与性能优化》是一本深入实践Apache Flink实时计算引擎的指南,旨在帮助开发者了解Flink的核心特性,并优化性能以应对大规模数据处理需求。作者从实际应用出发,结合丰富的实例,向读者呈现了如何使用Flink构建高效的实时计算应用的方法和技巧。

内容概述及总结

第一章:实时计算引擎

首章从公司常见的实时计算需求出发,让我们深入了解为什么引入实时计算引擎是如此重要。

作者生动地描述了不同岗位的提问,从监控大屏实时查看促销活动商品总销售额、实时统计网站PV/UV到根据浏览记录实时推荐不同商品等等,这些场景凸显了实时计算在大数据时代的关键作用。

接着,作者详细对比分析了实时计算与传统离线计算之间的差异

强调实时计算需求的复杂性和对性能的高要求。为读者介绍了最火的实时计算引擎Flink的特性,强调其灵活性和高性能,让读者对Flink有了初步了解。

第二章:Flink快速入门

第二章为读者提供了快速上手Flink的指南。

2.1至2.1章从Flink的安装和配置开始,作者手把手地带领读者完成Flink开发环境的搭建。

接着,我们学习了如何编写Flink程序和处理流式数据。2.3通过一个简单的例子,读者了解到如何定义数据转换操作和运行Flink应用。

本章还详细介绍了Flink的运行模式,从本地模式到集群模式,让读者对Flink的部署和运行有了全面了解。

第三章:Flink流处理详解

在本章中,作者带领读者深入了解流处理的核心概念和关键操作,为构建高效的实时计算应用提供了实用的知识和技巧。

首先,作者介绍了事件时间和水位线的概念,帮助读者理解流处理的时间特性。核心的时间有3个,分别为Processing Time、Event Time 和 Ingestion Time。

Processing Time 是指事件被处理时机器的系统时间。

Event Time 是指事件发生的时间。

Ingestion Time 是事件进入 Flink 的时间。

事件时间是指数据实际发生的时间,而水位线则用于处理延迟数据和乱序数据,保证数据的正确性。

假设我们有一个实时日志数据流,其中包含了用户的点击事件,每个事件都有一个时间戳字段表示点击发生的时间。我们希望统计每个用户在过去5分钟内的点击次数,以及每分钟内的点击次数。这就涉及到了窗口操作,需要使用事件时间和水位线来确保数据的准确性。

首先,我们需要定义一个窗口,例如5分钟的滚动窗口和1分钟的滑动窗口。然后,我们需要在数据流中设置事件时间,并为数据流分配水位线。在Flink中,我们可以使用assignTimestampsAndWatermarks函数来实现这一步骤。

DataStream<ClickEvent> clickStream = ... // 获取日志数据流

DataStream<ClickEvent> withTimestampsAndWatermarks = clickStream
    .assignTimestampsAndWatermarks(new BoundedOutOfOrdernessTimestampExtractor<ClickEvent>(Time.seconds(10)) {
        @Override
        public long extractTimestamp(ClickEvent event) {
            return event.getTimestamp();
        }
    });

上面的代码中,我们使用BoundedOutOfOrdernessTimestampExtractor来分配时间戳和水位线。我们指定了一个10秒的延迟,这意味着我们允许数据最多延迟10秒到达,超过这个时间的数据会被视为迟到的数据。

接下来,我们可以使用窗口操作来对数据流进行分组和聚合,统计每个用户在过去5分钟内的点击次数和每分钟内的点击次数。

DataStream<Tuple2<String, Long>> fiveMinuteCounts = withTimestampsAndWatermarks
    .keyBy(ClickEvent::getUserId)
    .timeWindow(Time.minutes(5))
    .aggregate(new CountAggregator());

DataStream<Tuple2<String, Long>> oneMinuteCounts = withTimestampsAndWatermarks
    .keyBy(ClickEvent::getUserId)
    .timeWindow(Time.minutes(1), Time.seconds(30)) // 每30秒滑动一次
    .aggregate(new CountAggregator());

上面的代码中,我们使用timeWindow来定义窗口的大小和滑动间隔。CountAggregator是自定义的聚合函数,用于计算点击次数。

通过以上操作,我们就可以得到每个用户在过去5分钟内的点击次数和每分钟内的点击次数。通过合理使用事件时间和水位线,可以保证数据处理的准确性,即使数据存在乱序和延迟,也能得到准确的统计结果。

通过具体的示例,读者了解到在处理实时数据时,如何应用事件时间和水位线,以确保数据的准确性和一致性。

接着,本章深入学习了窗口操作,包括滚动窗口、滑动窗口和会话窗口等。

就拿交通传感器的示例:统计经过某红绿灯的汽车数量之和?

假设在一个红绿灯处,我们每隔 15 秒统计一次通过此红绿灯的汽车数量,如下图所示:

可以把汽车的经过看成一个流,无穷的流,不断有汽车经过此红绿灯,因此无法统计总共的汽车数量。但是,我们可以换一种思路,每隔 15 秒,我们都将与上一次的结果进行 sum 操作(滑动聚合),如下图所示:

这个结果似乎还是无法回答我们的问题,根本原因在于流是无界的,我们不能限制流,但可以在有一个有界的范围内处理无界的流数据。因此,我们需要换一个问题的提法:每分钟经过某红绿灯的汽车数量之和?

这个问题,就相当于一个定义了一个 Window(窗口),Window 的界限是 1 分钟,且每分钟内的数据互不干扰,因此也可以称为翻滚(不重合)窗口,如下图所示:

第一分钟的数量为 18,第二分钟是 28,第三分钟是 24……这样,1 个小时内会有 60 个 Window。

再考虑一种情况,每 30 秒统计一次过去 1 分钟的汽车数量之和,如下图所示:

此时,Window 出现了重合。这样,1 个小时内会有 120 个 Window。

窗口操作允许将数据流按照时间或者其他条件进行切分,实现对特定时间范围内的数据进行聚合计算。通过详细的代码演示,读者了解如何在Flink中使用窗口操作,从而实现实时计算任务。

另外,作者还介绍了Flink的状态管理机制和容错机制。

 

在流处理中,由于数据的无序性和延迟性,容易出现数据丢失或者重复处理的情况。为了保证数据处理的准确性和稳定性,Flink提供了强大的状态管理和容错机制。通过实例演示,读者了解如何利用Flink的状态管理功能,对流数据进行状态管理和容错处理。

总的来说,第三章为我们深入探究了Flink流处理的关键概念和操作。通过详细的事例和代码演示,读者可以全面了解Flink流处理的技术细节,为构建高效的实时计算应用提供了重要的指导。

第四章:Flink批处理详解

在本章中,作者重点讲解了Flink批处理的核心概念、API和优化技巧,为读者提供了全面了解和灵活应用Flink进行批处理任务的指导。

 

首先,作者引导读者了解DataSet API和Execution Environment的使用。DataSet API是Flink用于处理有限数据集的API,Execution Environment则是Flink批处理作业的执行环境。通过这两个基础组件,读者可以快速上手使用Flink进行批处理任务。

 

接着,本章深入学习了Flink的批处理转换操作和优化技巧。Flink提供了丰富的转换操作,如map、filter、reduce等,用于对数据进行转换和计算。同时,Flink还支持优化操作顺序、合理设置并行度等方式,以实现高效的数据处理。通过实例演示,读者了解如何使用这些操作和技巧,优化批处理任务的性能。

为了帮助读者更好地应用Flink进行批处理任务,本章还介绍了Flink的迭代计算和自定义函数等高级功能。迭代计算允许对数据进行多次迭代计算,用于解决复杂的批处理问题。自定义函数则可以让用户根据实际需求定义自己的数据处理逻辑,增加了Flink的灵活性和可扩展性。

第五章:Flink表格API

第五章重点介绍了Flink的表格API,这是一种基于SQL语法的高级抽象方式来处理流和批数据。

它有如下几个模块:

  • flink-table-common:table 中的公共模块,可以用于通过自定义 function,format 等来扩展 Table 生态系统

  • flink-table-api-java:支持使用 Java 语言,纯 Table&SQL API

  • flink-table-api-scala:支持使用 Scala 语言,纯 Table&SQL API

  • flink-table-api-java-bridge:支持使用 Java 语言,包含 DataStream/DataSet API 的 Table&SQL API(推荐使用)

  • flink-table-api-scala-bridge:支持使用 Scala 语言,带有 DataStream/DataSet API 的 Table&SQL API(推荐使用)

  • flink-sql-parser:SQL 语句解析层,主要依赖 calcite

  • flink-table-planner:Table 程序的 planner 和 runtime

  • flink-table-uber:将上诉模块打成一个 fat jar,在 lib 目录下

  • flink-table-planner-blink:Blink 的 Table 程序的 planner(阿里开源的版本)

  • flink-table-runtime-blink:Blink 的 Table 程序的 runtime(阿里开源的版本)

  • flink-table-uber-blink:将 Blink 版本的 planner 和 runtime 与前面模块(除 flink-table-planner 模块)打成一个 fat jar,在 lib 目录下,如下图所示。

  • flink-sql-client:SQL 客户端

     

为什么选择 Table API & SQL:

  • 声明式语言表达业务逻辑

  • 无需代码编程 —— 易于上手

  • 查询能够被有效的优化

  • 查询可以高效的执行

通过学习Flink的表格API,读者可以使用简洁的SQL语句进行数据的查询、转换和聚合操作,从而简化开发流程。

此外,本章还介绍了如何将表格API与流处理和批处理进行集成,让读者了解如何将表格API与已有Flink应用相结合,以及如何更好地应用于实际项目。

第六章:Flink应用开发

第六章带领读者深入学习Flink应用开发的实际应用。我们学习如何将Flink与其他数据存储和消息队列进行集成,如何优化Flink应用以提高性能。

 

作者通过案例演示,详细介绍了如何进行Flink性能调优、内存管理和并行度设置等方面的优化技巧。

这里通过 Chrome 浏览器的控制台来查看一下有哪些 REST API 是用来提供监控数据的。

1.在 Chrome 浏览器中打开 http://localhost:8081/overview 页面,可以获取到整个 Flink 集群的资源信息:TaskManager 个数(TaskManagers)、Slot 总个数(Total Task Slots)、可用 Slot 个数(Available Task Slots)、Job 运行个数(Running Jobs)、Job 运行状态(Finished 0 Canceled 0 Failed 0)等,如下图所示。

2.通过 http://localhost:8081/taskmanagers 页面查看 TaskManager 列表,可以知道该集群下所有 TaskManager 的信息(数据端口号(Data Port)、上一次心跳时间(Last Heartbeat)、总共的 Slot 个数(All Slots)、空闲的 Slot 个数(Free Slots)、以及 CPU 和内存的分配使用情况,如下图所示。

3.通过 http://localhost:8081/taskmanagers/tm_id 页面查看 TaskManager 的具体情况(这里的 tm_id 是个随机的 UUID 值)。在这个页面上,除了上一条的监控信息可以查看,还可以查看该 TaskManager 的 JVM(堆和非堆)、Direct 内存、网络、GC 次数和时间,如下图所示。内存和 GC 这些信息非常重要,很多时候 TaskManager 频繁重启的原因就是 JVM 内存设置得不合理,导致频繁的 GC,最后使得 OOM 崩溃,不得不重启。

另外如果你在 /taskmanagers/tm_id 接口后面加个 /log 就可以查看该 TaskManager 的日志,注意,在 Flink 中的日志和平常自己写的应用中的日志是不一样的。

最后,本章还介绍了Flink的故障排查和监控,帮助读者了解如何应对Flink应用中出现的各种问题,并保障应用的稳定运行。

第七章:Flink生态系统

在本章,我们将了解Flink生态系统和扩展。作者向读者介绍了Flink的数据连接器,以及如何使用Flink连接不同的数据源和数据接收器。

此外,本章还展示了Flink的集成和拓展,如与Hadoop、Hive、Elasticsearch等的集成,以及如何自定义Flink的函数、算子和插件等。通过本章的学习,详细了解了Flink的生态系统,深入挖掘Flink的扩展性和灵活性。

第八章:性能优化与实践

在本章,我们深入探讨了Flink性能优化的实践方法。

1. 性能优化的必要性

本节首先阐述了性能优化在实时计算中的重要性。随着数据量的增长和计算任务的复杂性,性能问题可能成为影响作业稳定性和处理效率的关键因素。因此,了解性能优化的必要性是第一步,鼓励读者对性能问题进行深入研究和改进。

2. 优化数据倾斜

如下图所示,通过 Flink Web UI 中 Job 页面的第一个 Subtasks 选项卡,可以看到任务的两个 Task,点击 Task,可以看到 Task 相应的 Subtask 详情。例如 Subtask 的启动时间、结束时间、持续时长、接收数据量的字节数以及接收数据的个数。图中可以看到,相同 Task 的多个 Subtask 中,有的 Subtask 接收到 1.69 TB 的数据量,有的 Subtask 接收到 17.6 TB 的数据量,通过 Flink Web UI 可以精确地看到每个 Subtask 处理了多少数据,即可判断出 Flink 任务是否存在数据倾斜,接下来学习 Flink 中如何来解决数据倾斜。

 

数据倾斜是指在计算过程中,部分数据分区数据量远大于其他分区,导致部分任务执行速度明显变慢。本节将详细介绍数据倾斜的原因和解决方案,如使用合适的分区策略、增加并行度、使用Combiner等技术来优化数据倾斜问题。

3. 算子链合并与切分

对于一般的作业(无特殊耗性能处),可以尽量让算子的并行度从 Source 端到 Sink 端都保持一致,这样可以尽可能的让 Job 中的算子进行 chain 在一起,形成链,数据在链中可以直接传输,而不需要再次进行序列化与反序列化,这样带来的性能消耗就会得到降低。

在Flink中,算子链是将多个算子连接在一起执行的优化策略。本节将介绍如何通过合并和切分算子链,优化作业的执行计划,减少算子之间的通信开销和状态转换,提高作业的执行效率。

4. 并行度调优

Parallelism 翻译成中文是并行的意思,在 Flink 作业里面代表算子的并行度,适当的提高并行度可以大大提高 Job 的执行效率,比如你的 Job 消费 Kafka 数据过慢,适当调大可能就消费正常了。 

例如,如果 TaskManager 有四个 Slot,那么它将为每个 Slot 分配 25% 的内存。 可以在一个 Slot 中运行一个或多个线程。 同一 Slot 中的线程共享相同的 JVM。 同一 JVM 中的任务共享 TCP 连接和心跳消息。TaskManager 的一个 Slot 代表一个可用线程,该线程具有固定的内存,注意 Slot 只对内存隔离,没有对 CPU 隔离。默认情况下,Flink 允许子任务共享 Slot,即使它们是不同 Task 的 subtask,只要它们来自相同的 Job,这种共享模式可以大大的提高资源利用率。

并行度是影响作业并行计算性能的关键因素。本节将探讨如何通过调整并行度设置,平衡作业的资源利用和数据分发,从而优化作业的整体性能。

 

异常日志实时告警项目架构

实时处理海量日志架构设计


 

本大章,通过实例和经验分享,介绍了如何优化Flink应用的吞吐量、延迟和稳定性。从数据倾斜处理到状态管理和本地优化,本章帮助读者找到针对不同场景的优化方案。同时,作者还详细介绍了Flink的内存管理和任务调度,以及如何利用性能监控和指标来定位问题和进行调优。通过本章的学习,读者可以全面了解Flink性能优化的方法和策略。

小结

《Flink实战与性能优化》是一本深入实践Flink的实时计算引擎的实用指南。通过详细介绍Flink的流处理和批处理功能,以及表格API的使用,读者可以全面掌握Flink的基本概念和操作。同时,本书的重点在于Flink性能优化和实践,通过丰富的实例和经验分享,让读者了解如何优化Flink应用的性能和稳定性。无论是初学者还是有一定经验的开发者,都能从本书中获得实用的知识和技巧,为构建高效的实时计算应用提供强有力的支持。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Flink是一个开源的分布式流处理框架,它的运行原理是将数据流分成不同的子任务,这些子任务会在不同的计算节点上并行执行。Flink将数据流看作是一个无限的事件流,每当有新的事件到来时,Flink会将这些事件收集起来,交给对应的算子进行处理,并将结果传递给下一个算子。Flink的运行原理主要包括以下几个方面: 1. 数据流划分:Flink会将数据流划分为多个子任务,并将这些子任务分配到不同的计算节点上。 2. 算子执行:每个子任务会在对应的计算节点上并行执行,数据会经过一系列的算子进行处理,每个算子都会将处理后的数据再次输出到下一个算子。 3. 状态管理:Flink支持对算子状态的管理,可以将算子的状态存储在内存或外部存储中,以便在出现故障时进行恢复。 4. 检查点:Flink会定期生成检查点,用于保存算子的状态以及数据流的位置信息,以便在出现故障时进行恢复。 5. 任务协调:Flink会对所有子任务进行统一的协调和调度,确保数据流的正确处理。 在实际应用中,为了保证Flink的性能,需要进行性能优化。常见的性能优化包括: 1. 调整并行度:适当调整算子的并行度可以提高Flink的性能。 2. 减少数据倾斜:数据倾斜会导致某些节点的负载过高,可以通过数据重分区等方式来减少数据倾斜。 3. 使用状态后端:选择合适的状态后端可以提高Flink的性能,常用的状态后端包括内存和RocksDB。 4. 减少网络开销:减少网络开销可以提高Flink的性能,可以通过调整数据分区、使用压缩算法等方式来减少网络开销。 5. 避免不必要的计算:避免不必要的计算可以提高Flink的性能,可以通过过滤掉不需要处理的数据等方式来避免不必要的计算。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值