flink 随笔 2-实践练习

0. 有国外的flink的好书吗?

幂等

1. 先整理,慢慢看

实践练习
	流处理
		在 Flink 中,应用程序由用户自定义算子转换而来的流式 dataflows 所组成。这些流式 dataflows 形成了有向图,以一个或多个源(source)开始,并以一个或多个汇(sink)结束。
		通常,程序代码中的 transformation 和 dataflow 中的算子(operator)之间是一一对应的。但有时也会出现一个 transformation 包含多个算子的情况,如上图所示。
	并行Dataflows
		Flink 程序本质上是分布式并行程序。在程序执行期间,一个流有一个或多个流分区(Stream Partition),每个算子有一个或多个算子子任务(Operator Subtask)。每个子任务彼此独立,并在不同的线程中运行,或在不同的计算机或容器中运行。
		算子子任务数就是其对应算子的并行度。在同一程序中,不同算子也可能具有不同的并行度。
		传输数据的模式
			一对一模式(直传)(例如上图中的 Source 和 map() 算子之间)可以保留元素的分区和顺序信息。这意味着 map() 算子的 subtask[1] 输入的数据以及其顺序与 Source 算子的 subtask[1] 输出的数据和顺序完全相同,即同一分区的数据只会进入到下游算子的同一分区。
			重新分发模式 keyBy/window 和 Sink 算子之间数据的重新分发时,不同键(key)的聚合结果到达 Sink 的顺序是不确定的。
	自定义时间流处理
		我们通常会使用记录在数据流中的事件时间的时间戳,而不是处理数据的机器时钟的时间戳。
	有状态流处理
		有状态算子的并行实例组在存储其对应状态时通常是按照键(key)进行分片存储的。每个并行实例算子负责处理一组特定键的事件数据,并且这组键对应的状态会保存在本地。
		Flink 应用程序的状态访问都在本地进行,因为这有助于其提高吞吐量和降低延迟。通常情况下 Flink 应用程序都是将状态存储在 JVM 堆上,但如果状态太大,我们也可以选择将其以结构化数据格式存储在高速磁盘中。
	通过状态快照实现的容错
		通过状态快照和流重放两种方式的组合,Flink 能够提供可容错的,精确一次计算的语义。
		它会将数据源中消费数据的偏移量记录下来,并将整个 job graph 中算子获取到该数据(记录的偏移量对应的数据)时的状态记录并存储下来。当发生故障时,Flink 作业会恢复上次存储的状态,重置数据源从状态中记录的上次消费的偏移量开始重新进行消费处理。而且状态快照在执行时会异步获取状态并存储,并不会阻塞正在进行的数据处理逻辑。
		
					
DataStream API 简介
	 什么能被转化成流?
		Flink 的 Java 和 Scala DataStream API 可以将任何可序列化的对象转化为流。Flink 自带的序列化器有:基本类型、复合类型
	Stream 执行环境
		DataStream API 将你的应用构建为一个 job graph,并附加到 StreamExecutionEnvironment 。
		当调用 env.execute() 时此 graph 就被打包并发送到 JobManager 上,后者对作业并行处理并将其子任务分发给 Task Manager 来执行。
		每个作业的并行子任务将在 task slot 中执行。
	基本的 stream sink
	调试
		Flink 支持在 IDE 内部进行本地调试
		
流式分析
	概要
		事件event time、摄取、处理时间
	使用 Event Time
		如果想要使用事件时间,需要额外给 Flink 提供一个时间戳提取器和 Watermark 生成器,Flink 将使用它们来跟踪事件时间的进度
	Watermarks
		需要一些缓冲,需要一些时间
		最终,我们必须勇于承担责任
		这正是 watermarks 的作用 — 它们定义何时停止等待较早的事件。
		我们可能会思考,如何决定 watermarks 的不同生成策略
		一种简单的方法是假定这些延迟受某个最大延迟的限制。Flink 将此策略称为 最大无序边界 (bounded-out-of-orderness) watermark。
	延迟 VS 正确性
		我们可以把 watermarks 的边界时间配置的相对较短,从而冒着在输入了解不完全的情况下产生结果的风险-即可能会很快产生错误结果。
		或者,你可以等待更长的时间,并利用对输入流的更全面的了解来产生结果。
	延迟
		延迟是相对于 watermarks 定义的。Watermark(t) 表示事件流的时间已经到达了 t; watermark 之后的时间戳 ≤ t 的任何事件都被称之为延迟事件。
	使用 Watermarks 
		如果想要使用基于带有事件时间戳的事件流,Flink 需要知道与每个事件相关的时间戳,而且流必须包含 watermark。
		通过实现一个类来实现的,该类从事件中提取时间戳,并根据需要生成 watermarks。最简单的方法是使用 WatermarkStrategy			
	Windows
		用 Flink 计算窗口分析取决于两个主要的抽象操作:
			Window Assigners,将事件分配给窗口(根据需要创建新的窗口对象)
			Window Functions,处理窗口内的数据。
			
			riggers 确定何时调用窗口函数
			Evictors 则可以删除在窗口中收集的元素。
		窗口分配器
			滚动
			滑动
			会话
		基于时间的窗口分配器
			既可以处理 事件时间,也可以处理 处理时间。
			没有哪一个更好,我们必须折衷。
			使用 处理时间,我们必须接受以下限制:
				无法正确处理历史数据,		
				无法正确处理超过最大无序边界的数据,
				结果将是不确定的
		基于计数的窗口
			只有窗口内的事件数量到达窗口要求的数值时,这些窗口才会触发计算。
			尽管可以使用自定义触发器自己实现该行为,但无法应对超时和处理部分窗口。
		窗口应用函数
			三种用法:
				像批量处理,ProcessWindowFunction 会缓存 Iterable 和窗口内容,供接下来全量计算
				像流处理,每一次有事件被分配到窗口时,都会调用 ReduceFunction 或者 AggregateFunction 来增量计算
				结合两者,通过 ReduceFunction 或者 AggregateFunction 预聚合的增量计算结果在触发窗口时, 提供给 ProcessWindowFunction 做全量计算。
		晚到的事件
			默认场景下,超过最大无序边界的事件会被删除
			Flink 给了我们两个选择去控制这些事件:
				旁路输出 的机制来安排将要删除的事件收集到侧输出流中
				指定 允许的延迟(allowed lateness) 的间隔,
					在这个间隔时间内,延迟的事件将会继续分配给窗口(同时状态会被保留),
					默认状态下,每个延迟事件都会导致窗口函数被再次调用(有时也称之为 late firing )。
		深入了解窗口操作
			滑动窗口是通过复制来实现的
				滑动窗口分配器可以创建许多窗口对象,并将每个事件复制到每个相关的窗口中
			时间窗口会和时间对齐
				动窗口和滚动窗口分配器所采用的 offset 参数可用于改变窗口的对齐方式
			 window 后面可以接 windoW
			 空的时间窗口不会输出结果
			 	事件会触发窗口的创建
			 Late Events Can Cause Late Merges
			 	会话窗口的实现是基于窗口的一个抽象能力,窗口可以 聚合。
			 		时间窗口产生的事件是根据窗口结束时的时间分配时间戳的
			 		后面的窗口内的数据消费和前面的流产生的数据是一致的
			 	会话窗口中的每个数据在初始被消费时,都会被分配一个新的窗口
			 		窗口之间的间隔足够小,多个窗口就会被聚合
			 		延迟事件可以弥合两个先前分开的会话间隔,从而产生一个虽然有延迟但是更加准确地结果。
			 		
数据管道 & ETL
	常见应用场景是 ETL(抽取、转换、加载)管道任务
	(隐式的)状态
		应用中有状态,你就应该考虑状态的大小。
		如果键值的数量是无限的,那 Flink 的状态需要的空间也同样是无限的。
	
事件驱动应用
	处理函数(Process Functions)
		有几种类型的 ProcessFunctions
			KeyedProcessFunction
			CoProcessFunctions
			BroadcastProcessFunctions 
		open() 方法
			每个窗口都持有托管的 Keyed state 的入口,并且根据窗口的结束时间执行 keyed 策略。
		processElement() 方法
		onTimer()
			这样做的效果是不可能容纳延迟的事件。 
			这相当于在使用 Flink 的时间窗口时将 allowedLateness 设置为零。
		性能考虑
			更建议使用 MapState 和 ListState,
			因为使用 RocksDBStateBackend 的情况下, MapState 和 ListState 比 ValueState 性能更好
		旁路输出(Side Outputs)
			异常情况(exceptions)
			格式错误的事件(malformed events)
			延迟的事件(late events)
			operator 告警(operational alerts),如与外部服务的连接超时
		ProcessFunctions 的另一个常见用例是清理过时 State。

通过状态快照实现容错处理
	由 Flink 管理的 keyed state 是一种分片的键/值存储
	每个 keyed state 的工作副本都保存在负责该键的 taskmanager 本地中
	Operator state 也保存在机器节点本地
	Flink 定期获取所有状态的快照,并将这些快照复制到持久化的位置
	State Backends
		Flink 管理的状态存储在 state backend 中
		两种 state backend 的实现
			基于 RocksDB 内嵌 key/value 存储将其工作状态保存在磁盘上的
			基于堆的 state backend,将其工作状态保存在 Java 的堆内存中(有两种类型)
				FsStateBackend,将其状态快照持久化到分布式文件系统
				MemoryStateBackend,它使用 JobManager 的堆保存状态快照。
		不同state backend性能对比
			当使用基于堆的 state backend 保存状态时,
				访问和更新涉及在堆上读写对象
				保存在 RocksDBStateBackend 中的对象,
					访问和更新涉及序列化和反序列化,所以会有更大的开销
					但 RocksDB 的状态量仅受本地磁盘大小的限制
					只有 RocksDBStateBackend 能够进行增量快照,

		所有这些 state backends 都能够异步执行快照,这意味着它们可以在不妨碍正在进行的流处理的情况下执行快照。
	状态快照
		快照 – 是 Flink 作业状态全局一致镜像的通用术语。
			Checkpoint
				由 Flink 自动执行的快照,其目的是能够从故障中恢复。
				可以是增量的,并为快速恢复进行了优化。
			外部化的 Checkpoint
				通常 checkpoints 不会被用户操纵。
				Flink 只保留作业运行时的最近的 n 个 checkpoints(n 可配置),并在作业取消时删除它们。
				但你可以将它们配置为保留,在这种情况下,你可以手动从中恢复。
			Savepoint
				用户出于某种操作目的(例如有状态的重新部署/升级/缩放操作)手动(或 API 调用)触发的快照。
				Savepoints 始终是完整的,并且已针对操作灵活性进行了优化
	状态快照如何工作
		当 checkpoint coordinator(job manager 的一部分)指示 task manager 开始 checkpoint 时,它会让所有 sources 记录它们的偏移量,并将编号的 checkpoint barriers 插入到它们的流中。这些 barriers 流经 job graph,标注每个 checkpoint 前后的流部分。
		Checkpoint n 将包含每个 operator 的 state,这些 state 是对应的 operator 消费了严格在 checkpoint barrier n 之前的所有事件,并且不包含在此(checkpoint barrier n)后的任何事件后而生成的状态。
		Flink 的 state backends 利用写时复制(copy-on-write)机制允许当异步生成旧版本的状态快照时,能够不受影响地继续流处理。只有当快照被持久保存后,这些旧版本的状态才会被当做垃圾回收。
	确保精确一次(exactly once)
		当流处理应用程序发生错误的时候,结果可能会产生丢失或者重复,可以配置策略:
			Flink 不会从快照中进行恢复(at most once)
			没有任何丢失,但是你可能会得到重复冗余的结果(at least once)
			没有丢失或冗余重复(exactly once)
		Flink 通过回退和重新发送 source 数据流从故障中恢复
			理想情况被描述为精确一次时,这并不意味着每个事件都将被精确一次处理
			相反,这意味着 每一个事件都会影响 Flink 管理的状态精确一次。
	端到端精确一次
		为了sources 中的每个事件都仅精确一次对 sinks 生效,必须满足以下条件:
			sources 必须是可重放的
    			你的 sinks 必须是事务性的(或幂等的)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值