Flink(Flink原理、实战与性能优化)
简述flink:核心是一个分布式、高性能、高可用、实时性的流式框架,支持实时流处理和批处理;flink统一了批处理和流处理,把批处理当做流处理的一种特殊情况(和spark的区别),流处理数据无解,批处理数据有界。flink根据固定缓存快进行网络数据传输,用户通过设定固定缓存块的超时值指定缓存块的传输时机(为0则是流处理标准模型,获得低的延迟,无穷大则为批处理模式,获得大的吞吐量);
flink流处理特性:1、支持高吞吐、高性能、低延时的流处理;2、支持高度灵活的窗口机制(window);3、支持轻量级分布式快照技术(Snapshot)实现容错机制,支持exactly-once语义;4、支持具有反压功能的持续流模型;5、flink在jvm内部实现自己的内存管理;6、支持程序自动优化,避免特定情况下shuffle、排序等昂贵操作,对中间结果进行缓存;、
flink架构:1、基本组成模块:流(stream)和转换(transformation)。流是中间的转化结果,transformation是中间的一个操作,流可以一对一也可以一对多的在两个操作之间传输数据;2、调度管理:分布式执行进程:job manager和task manager;jobmanager是Master进程,管理调整程序的执行,调度任务,失败重试等。task manager:worker节点,每个worker都是一个jvm进程,每个worker开辟多个slot,每个slot可以有多个线程;
window机制和时间机制:通过按照固定时间长度将数据切分成不同的窗口,然后对数据进行聚合运算,得到一定时间范围内的统计结果:1、tumbling Windows(滚动窗口):根据一定时间间隔或者数据数量进行窗口分割,不会出现窗口覆盖;2、sliding Windows(滑动窗口,类似于spark的滑动窗口):以一定间隔滑动,取一定时间的窗口数据(窗口时间大于滑动时间,出现数据覆盖);3、session Windows(会话窗口):用于取出相邻时间不大于gap的活跃数据,比如数据流入,当连续数据暂停时间大于gap后窗口停止;4、全局窗口:将全局数据中拥有相同key的数据放在同一个窗口,借助触发器触发;典型的时间字段是:event time(事件时间)、process time(处理时间)、ingestion(注入时间)用于触发器判断触发机制;
flink容错机制:是一种轻量级分布式快照实现的容错机制,支持exactly-once语义(一次),也可以降级为at-last-once语义(至少一次);需要数据源具有重放机制,允许数据流重放(kafka):1、barrier机制:当数据流中出现一个barrier,该barrier之前出现的记录都属于该barrier对应的snapslot(快照/检查点),之后出现的记录都属于下一个快照。来自不同快照的barrier可能会同时出现在数据流中,代表着数据流同一时间会并发进行多次快照,当一个中间操作接收到一个barrier之后会将它发送至属于该barrier的快照的数据流中去,等到汇总操作接收到之后会向检查点协调者(checkpoint coordinator)汇报确认收到该快照,直到所有的汇总操作都收到了该快照才算完成了该快照;2、exactly-once语义:当操作收到多个数据流时,需要对所有数据流进行排列对齐,也就是数据流之间的barrier要对齐;(1)首先接到数据流1的barrier n,便不能继续处理该数据流的数据了,直到operator接到其余所有数据流的barrier;(2)将barrier的数据流放置在接收缓存里面;(3)当后一个流读取到barrier的时候,operator会发射出所有等待向后发送的数据,后发射快照n的barrier;(4)后恢复所有输入流的处理;3、at least once:对齐操作会增加流程序处理的延迟,flink允许checkpoint时关闭对齐的操作,当一个操作接收到barrier时,就会打一个快照,而不会等待其他的barrier,也就是说操作cheekpointn时已经在处理Cheekpoint(n+1)的数据了,产生异常时需要对这部分数据重新处理,因为已经包含在Cheekpointn里面了;
flink反压机制:flink利用自身作为纯数据流的特性优雅的实现反压机制,flink采用了有界的分布式阻塞队列,类似生产者消费者模式,一个较慢的接受者会减慢发送者的发送速率,因为一旦队列满了,发送者就会被阻塞:分布式缓冲队列使用缓冲池localBufferPoll实现,每个生产者和被消费者的流都会分配一个缓冲池,缓冲池管理者一组缓冲,缓冲被消费之后可以循环使用。任务之间的缓冲感知,本地传输:如果taska和taskb都在同一个taskmanager节点上,a是b的上游,一旦b消费缓存的速度小于a生产缓存的速度,那么会造成a中缓冲池的缓存堆积,从而导致task1的降速;网络传输,如果taska和taskb工作在不同的节点,那么缓冲通过传输到网络(tcp)中被回收,实现缓冲池释放,而且网络中可以通过设置水位值防止网络中数据太多;当接收端消费速度小于生产端的生产速度时,会逐渐导致生产端缓冲池空间无法回收从而实现task1的降速。
flink如何使用jvm实现内存管理:大数据框架不得不面对的jvm问题:1、Java对象存储密度低,造成大量的内存资源浪费;2、full GC会导致长时间的延迟,影响性能;3、会时长出现OOM的情况;基于此,大数据框架需要自己管理jvm;主要内容包括积极地内存管理、定制的序列化工具、堆外内存等:1、积极地内存管理:Flink 并不是将大量对象存在堆上,而是将对象都序列化到一个预分配的内存块上,这个内存块叫做 MemorySegment,它代表了一段固定长度的内存(默认大小为 32KB),也是 Flink 中小的内存分配单元,并且提供了非常高效的读写方法。你可以把 MemorySegment 想象成是为 Flink 定制的 java.nio.ByteBuffer。它的底层可以是一个普通的 Java 字节数组(byte[]),也可以是一个申请在堆外的 ByteBuffer。每条记录都会以序列化的形式存储在一个或多个MemorySegment中。Flink 中的 Worker 名叫 TaskManager,是用来运行用户代码的 JVM 进程。TaskManager 的堆内存主要被分成了三个部分:Network Buffers: 一定数量的32KB大小的 buffer,主要用于数据的网络传输。Memory Manager Pool: 这是一个由 MemoryManager 管理的,由众多MemorySegment组成的超大集合。Remaining (Free) Heap: 这部分的内存是留给用户代码以及 TaskManager 的数据结构使用的。Flink 采用类似 DBMS 的 sort 和 join 算法,直接操作二进制数据,从而使序列化/反序列化带来的开销达到小。积极内存管理的好处:减少GC压力;避免了OOM;节省内存空间;高效的二进制操作 & 缓存友好的计算;2、Flink 量身定制的序列化框架: Flink 中处理的数据流通常是同一类型,由于数据集对象的类型固定,对于数据集可以只保存一份对象Schema信息,节省大量的存储空间。同时,对于固定大小的类型,也可通过固定的偏移位置存取。当我们需要访问某个对象成员变量的时候,通过定制的序列化工具,并不需要反序列化整个Java对象,而是可以直接通过偏移量,只是反序列化特定的对象成员变量。如果对象的成员变量较多时,能够大大减少Java对象的创建开销,以及内存数据的拷贝大小。3、采用堆外内存:启动超大内存(上百GB)的JVM需要很长时间,GC停留时间也会很长(分钟级)。使用堆外内存的话,可以极大地减小堆内存(只需要分配Remaining Heap那一块),使得 TaskManager 扩展到上百GB内存不是问题。高效的 IO 操作。堆外内存在写磁盘或网络传输时是 zero-copy,而堆内存的话,至少需要 copy 一次。
堆外内存是进程间共享的。也就是说,即使JVM进程崩溃也不会丢失数据。这可以用来做故障恢复(Flink暂时没有利用起这个,不过未来很可能会去做)。
spark streaming和flink之间的区别:1、流处理模型:sparkstreaming是微批处理,flink是完全流处理;2、反压机制:spark streaming是动态调整接受率;flink是基于缓存感知的自动调整;
相关文章