我的编程空间,编程开发者的网络收藏夹
学习永远不晚

「Flink」理解流式处理重要概念

短信预约 信息系统项目管理师 报名、考试、查分时间动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

「Flink」理解流式处理重要概念

「Flink」理解流式处理重要概念

什么是流式处理呢?

这个问题其实我们大部分时候是没有考虑过的,大多数,我们是把流式处理和实时计算放在一起来说的。我们先来了解下,什么是数据流。

数据流(事件流)

  • 数据流是无边界数据集的抽象
    • 我们之前接触的数据处理,大多都都是有界的。例如:处理某天的数据、某个季度的数据等
    • 无界意味着数据是无限地、持续增长的
    • 数据流会随着时间的推移,源源不断地加入进来
  • 数据流无处不再
    • 信息卡交易
    • 电商购物
    • 快递
    • 网络交换机的流向数据
    • 设备传感器发出的数据
    • 这些数据都是无穷无尽的
    • 每一件事情,都可以看成事件序列
  • 数据流是有序的
    • 数据的到来总是有个先后顺序
  • 数据流是不可变的
    • 事件一旦发生,就不能被改变
    • 它陈述了某一个时刻的事实
  • 数据流是可以重播的
    • 为了处理的一些问题、纠正过去的错误,可以重跑数据流
    • 借助于Kafka,我们可以重新消费几个月之前的原始数据流

流式处理

流式处理就是指实时地处理一个或多个事件流。它是一种编程范式。其他编程领域,主要有3种编程范式:

  1. 请求与响应
    • 延迟最小的一种方式,响应时间要求亚毫秒级到毫秒之间
    • 响应时间一般分稳定
    • 发出请求,等待响应(大部分的JavaEE同学,都是开发这一类编程范式的应用),其实就是OLTP
  2. 批处理
    • 特点:高延迟、高吞吐
    • 一般是固定某个时刻开始启动执行,读取所有的数据,然后输出接口
    • 每次读取到的都是旧数据
    • 主要应用在DWH或BI中
  3. 流式处理
    • 特点:介于上述两者之间
    • 流式处理可以让业务报告保持更新,持续响应

流的定义不依赖某个框架,只要储蓄从一个无边界数据集中读取数据,并对它们进行处理生成结果,就是进行流式处理。重点是:整个过程必须是持续的。

流式处理中的时间

上述我们已经说过了,数据流都是有序的。某一时刻的数据是确定的。时间是流式处理中非常重要的概念。大部分流式应用的操作都是基于时间窗口的。

流式系统一般包含以下几个时间概念(熟悉Flink的同学应该会很熟悉):

  • 事件时间(Eventtime)
    • 事件实际发生的时间
    • 用户一般只对事件发生时间感兴趣
  • 日志追加时间
    • 日志追加时间是指事件保存到事件存储源的时间
    • 例如:数据是什么到达Kafka的(Kafka是可以启用自动添加时间戳功能的)
  • 处理时间
    • 流式处理应用接收到事件后,要对齐进行处理的时间
    • 处理时间取决于流式处理应用何时读取到这个时间
    • 如果应用程序使用了两个线程来读取同一个事件,这个时间戳可能会不一样
    • 这个时间戳非常不可靠,应该避免使用它

状态

如果流式处理是来一个事件就处理一个事件,那么流式处理就很简单。但如果操作中包含了多个事件,流式处理就有意思了。例如:我们想在流式处理中统计北京用户的订单数量、消费金额等等。此时,就不能光处理单个事件了,我们需要获取更多的事件。事件与事件之间的信息就称之为状态。例如简单的,求某个类型的订单数等。


这些状态一般就保存在流式处理程序本地变量(本地内存)中,例如:使用HashMap来保存计数。但这种做法是很不可靠的,流式处理处理的是无界数据集,一旦应用程序出现异常,就会出现状态丢失,这是我们说不能接受的。所以,每一种流式计算框架都会很小心地持久化状态。如果应用程序重启,需要将这些数据恢复。


流式处理一般包含两种状态:

  • 本地状态
    • 这种状态只能被应用程序实例访问(不过Flink 1.9版本是可以外部来访问本地状态的)
    • 内嵌到应用程序的数据库中进行维护和管理
    • 特点:速度快,但受内存大小的限制,所以,很多流式处理系统都将数据拆分到多个子流中处理
  • 外部状态
    • 用外部存储来处理,一般使用NoSQL系统,例如:Cassadra
    • 特点:没有大小限制,可以被应用程序多个实例访问、甚至外部应用访问,但引入额外的系统会造成延迟、复杂性(例如:要维护内部和外部状态一致性问题)

时间窗口

大部分针对流的操作都是基于时间窗口的。例如:计算一周内销量最好的产品。两个流的合并也是基于时间窗口的。流式系统会合并发生在相同时间段上的事件。窗口是有类型的。以下几点是我们设计窗口需要考虑的:

  • 窗口的大小
    • 是基于5分钟计算还是基于15分钟、甚至是一天
    • 窗口越小,就能越快地发现变更,不过噪声也就越多
    • 窗口越大,变更就跟平滑,不过延迟也越严重
  • 窗口的移动频率(移动间隔)
    • 5分钟的窗口,可以1分钟计算一次,或者每秒钟计算一次,或者每当有新事件到达时计算一次
    • 如果“移动频率”与窗口大小相等,这种称为滚动窗口(tumbling window)
    • 如果窗口随着每一条记录移动,这种情况称为滑动窗口(sliding window)
  • 窗口的可更新时长
    • 假设:计算了 00:00 – 00:05 之间的订单总数,一个小时后,又得到了一些“事件时间”是 00:02的事件(例如:因为网络通信故障,这个消息晚到了一段时间),这种情况,是否需要更新 00:00 – 00:05 这个窗口的结果呢?或者就不处理了?
    • 理想情况下,可以定义一个时间段,只要在这个时间段内,事件可以被添加到对应的时间片段里。例如:如果事件处于4个小时以内,就更新,否则,就忽略掉。
  • 窗口时间对齐
    • 窗口可以与时间对齐,例如:5分钟的窗口如果每分钟移动一次,那么第一个分片可以是:00:00 – 00:05,第二个就是 00:01 – 00:06
    • 窗口也可以不与时间对齐,例如:应用可以在任何时间启动,那么第一个分片有可能是03:17 – 03:22
    • 滑动窗口永远不会与时间对齐,只要有新的记录到达,就会发生移动


下面这张图,说明了滚动窗口与滑动窗口的区别。

滚动窗口:假设窗口的大小为5分钟,这里确定的3个时间窗口

滑动窗口:假设每分钟滑动一次,那么这个时候会有5个时间窗口,计算结果会发生重叠

image

流式处理的设计模式

单个事件处理

这是流式处理最基本的模式。这种模式也叫:map或filter模式。经常被用来过滤无用的事件或者用于转换事件。


这种模式,应用程序读取流中的数据,修改数据,然后把事件生成到另一个流上。这一类应用程序无需在程序内部维护状态,每一个事件都是独立处理的。这种错误恢复和进行负载均衡都很容易。因为无需进行状态恢复操作。


使用本地状态

大部分流式处理应用关系如何聚合数据。特别是:基于时间窗口进行聚合。例如:找到每天最低、最高的交易价格。要实现这种操作,就需要维护流的状态。例如:我们需要将最小值、最大值保存下来,用它们与每一个新值对比。这类操作,可以通过本地状态来实现。例如:每一个分组都维护自己分组的状态。


一旦流式处理中包含了本地状态,就需要解决以下问题。

  • 内存使用
    • 必须要有足够的内存来保存本地状态
  • 持久化
    • 确保应用程序关闭时,不会丢失状态
    • 例如:我们可以使用RocksDB将本地状态保存到内存里、同时持久化到磁盘上,以便重启后恢复。而且需要将本地状态的变更发送到Kafka的主题上
  • 重新负载均衡
    • 有时候,分区被重新分配给不同的消费者。这种情况,失去分区的实例必须把最后的状态保存下来,或得分区的实例必须要知道如何恢复到正确的状态


多阶段处理和重分区

有些时候,我们要通过所有可用的数据来获得结果。例如:要发布每天的“前10支”股票,这10支股票需要从每天的交易股票中挑选出来。如果仅仅在单个实例上处理是不够的,因为10支股票分布在多个实例上。


此种,我们分为多个阶段来处理。

计算每支股票当天的涨跌。这个计算可以在每个实例上执行

将结果写入到单个分区

再用一个实例找出当天的前10支股票


这一类操作就与MapReduce很像了。


使用外部查找——流和表的连接

有时候,流式处理需要将外部数据和流集成在一日。例如:外部数据中保存了一些规则、或者将完整完整地用户信息拉取到流中。

这种case最大的问题,外部查找会带来严重的延迟,一般在 5-15 ms之间,这在很多情况下是不可行的。而且,外部系统也无法承受这种额外的负载——流式处理系统每秒可以处理10-50W个事件,而数据库正常情况下每秒只能处理1W个事件,所以需要伸缩性更强的解决方案。


为了获取更好的性能和更强的伸缩性,需要将外部数据库的信息缓存到流式处理应用中。但考虑以下问题:

如何保证缓存里的数据是最新的?

如果刷新太频繁,仍然会对数据库造成很大压力,缓存也就无用了。

如果刷新不及时,那么流式处理中所用的数据就会过时。

如果能够捕捉数据库的变更事件,并形成事件流,流式处理作业就可以监听事件流,并及时更新缓存。捕捉数据库的变更事件并形成数据流,这个过程称为CDC(Change Data Capture)。例如:我们可以通过Canal来捕获MySQL数据库的变化、可以通过ogg来捕获Oracle数据库的变化


流与流的连接

有时候需要连接两个真实的事件流。要连接两个流,就是连接所有的历史事件(将两个妞中具有相同键、发生在相同时间窗口内的事件匹配起来),这种流和流的连接称为:基于时间窗口的连接(windowed-join)。连接两个流,通常包含一个滑动时间窗口

image


乱序事件

不管对于流式处理、还是传统的ETL系统,处理乱序事件都是一个挑战。物联网领域经常发生乱序事件:一个移动设备断开Wifi连接几个小时,在重新连上WiFi后,将几个小时堆积的事件一并发出去。要让流式处理应用处理好这些场景,需要做到几下:

  • 识别乱序事件
    • 应用程序需要检查事件的时间,并将其与当前时间进行比较
  • 规定一个时间段用于重排乱序事件
    • 例如:3个小时以内的事件可以重排,但3个小时以外的事件就可以直接扔掉
  • 具有一定时间段内重排事件的能力
    • 这是流式处理应用和批处理的重要不同点
    • 假设有一个每天运行的作业,一些事件在作业结束之后才到达,那么可以重新运行昨天的作业来更新
    • 而在流式处理中,重新运行昨天的作业是不存在的,乱序事件和新到达的事件必须一起处理
  • 具备更新结果的能力
    • 如果处理的结果保存在数据库你,那么可以通过put或update对结果进行更新


重新处理

该重要模式是重新处理事件:

  • 流式处理应用更新了,要使用新版本应用处理同一个事件流,生成新的结果,并比较两种版本的结果,然后某个时间点将客户端切换到新的结果流
  • 现有的流式处理出现了缺陷,修复后,需要重新处理并重新计算结果

第一种情况,需要Kafka将事件流长时间地保存在可伸缩的数据存储中

  • 将新版本的应用作为一个新的消费者组
  • 新的版本从输入主题的第一个偏移量开始读取数据
  • 检查结果流,在新版本的处理作业赶上进度时,将客户端应用程序切换到新的结果流上

第二种情况,需要应用程序回到输入流的起始位置开始处理,同时重置本地状态,还要清理之前的输出流。这种方式处理起来比较困难。建议还是使用第一种方案。


参考文献:

《Kafka全文指南》

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

「Flink」理解流式处理重要概念

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

「Flink」理解流式处理重要概念

什么是流式处理呢?这个问题其实我们大部分时候是没有考虑过的,大多数,我们是把流式处理和实时计算放在一起来说的。我们先来了解下,什么是数据流。数据流(事件流)数据流是无边界数据集的抽象我们之前接触的数据处理,大多都都是有界的。例如:处理某天的数据、某个季度的数据
「Flink」理解流式处理重要概念
2022-03-16

Java流的概念怎么理解

本篇内容主要讲解“Java流的概念怎么理解”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java流的概念怎么理解”吧!昨天寝室同学问了我个关于Java流的问题,在解答完后很有感触,我认为可能所有
2023-06-17

flink 流式处理中如何集成mybatis框架

flink 中自身虽然实现了大量的connectors,如下图所示,也实现了jdbc的connector,可以通过jdbc 去操作数据库,但是flink-jdbc包中对数据库的操作是以ROW来操作并且对数据库事务的控制比较死板,有时候操作关系型数据库我们会非常
flink 流式处理中如何集成mybatis框架
2019-08-15

Hive数据倾斜的概念及处理方式

本篇内容主要讲解“Hive数据倾斜的概念及处理方式”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Hive数据倾斜的概念及处理方式”吧!Hive数据倾斜及处理① 数据倾斜的概念及原因1.1 数据倾
2023-06-19

从重绘到回流:掌握网页渲染原理的关键概念

从回流到重绘:理解网页渲染原理的关键概念,需要具体代码示例随着互联网的迅猛发展,网页设计和开发的重要性日益凸显。在网页设计的过程中,一个重要的概念是网页渲染。了解网页渲染的原理和相关的关键概念对于优化网页性能和用户体验至关重要。网页渲染
从重绘到回流:掌握网页渲染原理的关键概念
2024-01-26

理解响应式布局的重要性和原理

了解响应式布局的重要性及原理随着移动设备的普及和互联网的快速发展,人们越来越多地使用手机、平板电脑等移动设备来浏览网页和使用应用程序。传统的固定布局已不能满足人们在不同设备上的浏览需求,因此响应式布局逐渐成为了互联网设计和开发的重要趋势。
理解响应式布局的重要性和原理
2024-01-29

Java单例模式与破坏单例模式概念原理深入讲解

单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建
2023-02-21

.ibd文件在MySQL中的重要性及处理方式

.ibd文件在MySQL中的重要性及处理方式在MySQL中,数据存储是通过多个文件来实现的,其中最核心的是数据文件和索引文件。其中,对于MyISAM存储引擎来说,数据文件一般以.MYD为扩展名,而索引文件以.MYI为扩展名;而对于Inno
.ibd文件在MySQL中的重要性及处理方式
2024-03-14

详解C++异常处理三个重要组成部分

这篇文章主要为大家介绍了C++异常处理的三个重要组成部分示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2023-05-17

深入理解Java责任链模式实现灵活的请求处理流程

本文详细介绍了Java中的责任链模式,帮助您理解其工作原理,以及如何在代码中实现。该模式可以将请求沿着处理链路传递,实现灵活的请求处理流程。通过本文的学习,您将获得在Java应用程序中使用责任链模式的知识和技能
2023-05-17

【Java练习题汇总】《第一行代码JAVA》异常处理篇,汇总Java练习题——异常的概念及处理标准格式(try、catch、finally、throws、throw)、断言机制 Assertion ~

Java练习题 · 异常处理篇 1️⃣ 异常处理篇 1️⃣ 异常处理篇 一、填空题 Throwable 下的两个子类是______________ 、______________ 。ArthmeticException 类表示_
2023-08-16

编程热搜

目录