赞
踩
原文:https://www.cnblogs.com/huanghanyu/p/16644882.html
阅读目录
Apache Flink 是一个开源的基于流的有状态计算框架。它是分布式地执行的,具备低延迟、高吞吐的优秀性能,并且非常擅长处理有状态的复杂计算逻辑场景。
Flink 的核心概念主要有四个:Event Streams、State、Time 和 Snapshots。
Flink 基于 Chandy-Lamport 算法,会把分布式的每一个节点的状态保存到分布式文件系统里面作为 Checkpoint(检查点),过程大致如下。首先,从数据源端开始注入 Checkpoint Barrier,它是一种比较特殊的消息。
然后它会跟普通的事件一样随着数据流去流动,当 Barrier 到达算子之后,这个算子会把它当前的本地状态进行快照保存,当 Barrier 流动到 Sink,所有的状态都保存完整了之后,它就形成一个全局的快照。
这样当作业失败之后,就可以通过远程文件系统里面保存的 Checkpoint 来进行回滚:先把 Source 回滚到 Checkpoint 记录的 offset,然后把有状态节点当时的状态回滚到对应的时间点,进行重新计算。这样既可以不用从头开始计算,又能保证数据语义的一致性。
1) 作业管理器(JobManager)
2) 任务管理器(TaskManager)
3) 资源管理器(ResourceManager)
4) 分发器(Dispatcher)
Flink中的执行图可以分成四层: Streamgraph -> Jobgraph -> Executiongraph -> 物理执行图
作为对状态支持比较好的系统,Flink内部提供了可以使用的很多种可选的状态原语。从大的角度看, 所有状态原语可以分为KeyedState和OperatorState 两类。
Keyed State 可以进一步划分为下面的 5 类,它们分别是
watermark是一种衡量Event Time进展的机制,它是数据本身的一个隐藏属性。通常基于Event Time的数据,自身都包含一个timestamp.watermark是用于处理乱序事件的,而正确的处理乱序事件,通常用watermark机制结合window来实现。
流处理从事件产生,到流经source,再到operator,中间是有一个过程和时间的。虽然大部分情况下,流到operator的数据都是按照事件产生的时间顺序来的,但是也不排除由于网络、背压等原因,导致乱序的产生(out-of-order或者说late element)。
但是对于late element,我们又不能无限期的等下去,必须要有个机制来保证一个特定的时间后,必须触发window去进行计算了。这个特别的机制,就是watermark。
全局快照首先是一个分布式应用,它有多个进程分布在多个服务器上;其次,它在应用内部有自己的处理逻辑和状态;第三,应用间是可以互相通信的;第四,在这种分布式的应用,有内部状态,硬件可以通信的情况下,某一时刻的全局状态,就叫做全局的快照。
Flink通过状态和两次提交协议来保证了端到端的exactly-once语义
可以是内存,文件系统,或者 RocksDB。
如果是海量数据的话,Set结构是不现实的,可以考虑使用布隆过滤器来去重。
spark streaming 的 checkpoint 仅仅是针对 driver 的故障恢复做了数据和元数据的 checkpoint。而 flink 的 checkpoint 机制 要复杂了很多,它采用的是轻量级的分布式快照,实现了每个算子的快照,及流动中的数据的快照。
在 Flink CEP 的处理逻辑中,状态没有满足的和迟到的数据,都会存储在一个 Map 数据结构中,也就是说,如果我们限定判断事件序列的时长为 5 分钟,那么内存中就会存储 5 分钟的数据。
使用大容量的 Kafka 把数据先放到消息队列里面作为数据源,再使用Flink 进行消费,不过这样会影响到一点实时性。
Flink可以完全独立于Hadoop,在不依赖Hadoop组件下运行。但是做为大数据的基础设施,Hadoop体系是任何大数据框架都绕不过去的。Flink可以集成众多Hadooop 组件,例如Yarn、Hbase、HDFS等等。例如,Flink可以和Yarn集成做资源调度,也可以读写HDFS,或者利用HDFS做检查点。
在Flink架构角色中我们提到,TaskManager是实际负责执行计算的Worker,TaskManager 是一个 JVM 进程,并会以独立的线程来执行一个task或多个subtask。为了控制一个 TaskManager 能接受多少个 task,Flink 提出了 Task Slot 的概念。
简单的说,TaskManager会将自己节点上管理的资源分为不同的Slot:固定大小的资源子集。这样就避免了不同Job的Task互相竞争内存资源,但是需要主要的是,Slot只会做内存的隔离。没有做CPU的隔离。
固定延迟重启策略(Fixed Delay Restart Strategy)
故障率重启策略(Failure Rate Restart Strategy)
没有重启策略(No Restart Strategy)
Fallback重启策略(Fallback Restart Strategy)
我们知道Flink是并行的,计算过程可能不在一个 Slot 中进行,那么有一种情况即:当我们需要访问同一份数据。那么Flink中的广播变量就是为了解决这种情况。
我们可以把广播变量理解为是一个公共的共享变量,我们可以把一个dataset 数据集广播出去,然后不同的task在节点上都能够获取到,这个数据在每个节点上只会存在一份。
1.keyBy之前发生数据倾斜
如果keyBy之前就存在数据倾斜,上游算子的某些实例可能处理的数据较多,某些实例可能处理的数据较少,产生该情况可能是因为数据源的数据本身就不均匀,例如由于某些原因Kafka的topic中某些partition的数据量较大,某些partition的数据量较少。对于不存在keyBy的Flink任务也会出现该情况。
这种情况,需要让Flink任务强制进行shuffle。使用shuffle、rebalance、rescale算子即可将数据均匀分配,从而解决数据倾斜的问题。
2.keyBy之后无开窗聚合数据倾斜
map端使用状态先预聚合,达到一定时间或者一定size后再同一输出(localkeyby)。
3.keyBy后的窗口聚合操作存在数据倾斜
因为使用了窗口,变成了有界数据的处理,窗口默认是触发时才会输出一条结果发往下游,所以可以使用两阶段聚合的方式:
第一阶段聚合:key拼接随机数前缀或后缀,进步keyby、开窗、聚合。
第二阶段聚合:去掉随机数前缀或后缀,按照原来的key及windowEnd作keyby、聚合。
1.yarn-session模式:
这种方式需要先启动集群,然后在提交作业,接着会向yarn申请一块空间后,资源永远保持不变。如果资源满了,下一个就任务就无法提交,只能等到yarn中其中一个作业完成后,释放了资源,那下一个作业才会正常提交,这种方式资源被限制在session中,不能超过,比较适合特定的运行环境或测试环境。
2.per-job模式:
这种方式直接在yarn上提交任务运行Flink作业,这种方式的好处是一个任务会对应一个job,即每提交一个作业会根据自身的情况,向yarn中申请资源,直到作业执行完成,并不会影响下一个作业的正常运行,除非是yarn上面没有任何资源的情况下。一般生产环境是采用此方式运行。这种方式需要保证集群资源足够。
在Flink的后台任务管理中,我们可以看到Flink的那个算子和task出现了反压。最主要的手段是资源调优和算子调优。例如调大并发,增加运行任务的资源。缩短窗口时长。
为了更高效地分布式执行,Flink会尽可能地将operator的subtask链接(chain)在一起形成task。每个task在一个线程中执行。将operators链接成task是非常有效的优化:它能减少线程之间的切换,减少消息的序列化/反序列化,减少数据在缓冲区的交换,减少了延迟的同时提高整体的吞吐量。这就是我们所说的算子链。其实就是尽量把操作逻辑放入到同一个subtask里面也就是一个槽TaskSolt。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。