本文主要介绍了Flink项目的一些关键特性,Flink是一个拥有诸多特色的项目,包括其统一的批处理和流处理执行引擎,通用大数据计算框架与传统数据库系统的技术结合,以及流处理系统的诸多技术创新等

Apache Flink(下简称Flink)项目是大数据处理范畴最近冉冉升起的一颗新星,其不同于其他大数据项意图许多特性招引了越来越多人的重视。本文将深化剖析Flink的一些要害技能与特性,期望可以协助读者对Flink有愈加深化的了解,对其他大数据体系开发者也能有所裨益。本文假定读者已对MapReduce、Spark及Storm等大数据处理结构有所了解,一起了解流处理与批处理的根本概念。

Flink简介

Flink中心是一个流式的数据流履行引擎,其针对数据流的散布式核算供给了数据散布、数据通信以及容错机制等功用。依据流履行引擎,Flink供给了许多更高笼统层的API以便用户编写散布式使命:

  • DataSet API, 对静态数据进行批处理操作,将静态数据笼统成散布式的数据集,用户可以方便地运用Flink供给的各种操作符对散布式数据集进行处理,支撑Java、Scala和Python。
  • DataStream API,对数据流进行流处理操作,将流式的数据笼统成散布式的数据流,用户可以方便地对散布式数据流进行各种操作,支撑Java和Scala。
  • Table API,对结构化数据进行查询操作,将结构化数据笼统成联系表,并经过类SQL的DSL对联系表进行各种查询操作,支撑Java和Scala。

此外,Flink还针对特定的运用范畴供给了范畴库,例如:

  • Flink ML,Flink的机器学习库,供给了机器学习Pipelines API并完成了多种机器学习算法。
  • Gelly,Flink的图核算库,供给了图核算的相关API及多种图核算算法完成。

Flink的技能栈如图1所示:

深化了解Apache Flink核心技术(Apache Flink)  Apache Flink 大数据 第1张
图1 Flink技能栈

此外,Flink也可以方便地和Hadoop生态圈中其他项目集成,例如Flink可以读取存储在HDFS或HBase中的静态数据,以Kafka作为流式的数据源,直接重用MapReduce或Storm代码,或是经过YARN请求集群资源等。

共同的批处理与流处理体系

在大数据处理范畴,批处理使命与流处理使命一般被认为是两种不同的使命,一个大数据项目一般会被规划为只能处理其间一种使命,例如Apache Storm、Apache Smaza只支撑流处理使命,而Aapche MapReduce、Apache Tez、Apache Spark只支撑批处理使命。Spark Streaming是Apache Spark之上支撑流处理使命的子体系,看似一个特例,实则否则——Spark Streaming选用了一种micro-batch的架构,即把输入的数据流切分红细粒度的batch,并为每一个batch数据提交一个批处理的Spark使命,所以Spark Streaming本质上仍是依据Spark批处理体系对流式数据进行处理,和Apache Storm、Apache Smaza等彻底流式的数据处理办法彻底不同。经过其灵敏的履行引擎,Flink可以一起支撑批处理使命与流处理使命。

在履行引擎这一层,流处理体系与批处理体系最大不同在于节点间的数据传输办法。关于一个流处理体系,其节点间数据传输的规范模型是:当一条数据被处理完成后,序列化到缓存中,然后马上经过网络传输到下一个节点,由下一个节点持续处理。而关于一个批处理体系,其节点间数据传输的规范模型是:当一条数据被处理完成后,序列化到缓存中,并不会马上经过网络传输到下一个节点,当缓存写满,就耐久化到本地硬盘上,当一切数据都被处理完成后,才开端将处理后的数据经过网络传输到下一个节点。这两种数据传输形式是两个极点,对应的是流处理体系对低推迟的要求和批处理体系对高吞吐量的要求。Flink的履行引擎选用了一种十分灵敏的办法,一起支撑了这两种数据传输模型。Flink以固定的缓存块为单位进行网络数据传输,用户可以经过缓存块超时值指定缓存块的传输机遇。假如缓存块的超时值为0,则Flink的数据传输办法相似上文所说到流处理体系的规范模型,此刻体系可以获得最低的处理推迟。假如缓存块的超时值为无限大,则Flink的数据传输办法相似上文所说到批处理体系的规范模型,此刻体系可以获得最高的吞吐量。一起缓存块的超时值也可以设置为0到无限大之间的恣意值。缓存块的超时阈值越小,则Flink流处理履行引擎的数据处理推迟越低,但吞吐量也会下降,反之亦然。经过调整缓存块的超时阈值,用户可依据需求灵敏地权衡体系推迟和吞吐量。

深化了解Apache Flink核心技术(Apache Flink)  Apache Flink 大数据 第2张
图2 Flink履行引擎数据传输形式

在共同的流式履行引擎基础上,Flink一起支撑了流核算和批处理,并对功用(推迟、吞吐量等)有所确保。相关于其他原生的流处理与批处理体系,并没有由于共同履行引擎而受到影响然后大幅度减轻了用户装置、布置、监控、保护等本钱。

Flink流处理的容错机制

关于一个散布式体系来说,单个进程或是节点溃散导致整个Job失利是常常产生的作业,在反常产生时不会丢掉用户数据并能主动康复才是散布式体系有必要支撑的特性之一。本节首要介绍Flink流处理体系使命等级的容错机制。

批处理体系比较简略完成容错机制,由于文件可以重复拜访,当某个使命失利后,重启该使命即可。可是到了流处理体系,由于数据源是无限的数据流,然后导致一个流处理使命履行几个月的状况,将一切数据缓存或是耐久化,留下今后重复拜访根本上是不可行的。Flink依据散布式快照与可部分重发的数据源完成了容错。用户可自界说对整个Job进行快照的时刻距离,当使命失利时,Flink会将整个Job康复到最近一次快照,并从数据源重发快照之后的数据。Flink的散布式快照完成学习了Chandy和Lamport在1985年宣布的一篇关于散布式快照的论文,其完成的首要思维如下:

依照用户自界说的散布式快照距离时刻,Flink会守时在一切数据源中刺进一种特别的快照符号音讯,这些快照符号音讯和其他音讯相同在DAG中活动,可是不会被用户界说的事务逻辑所处理,每一个快照符号音讯都将其地点的数据流分红两部分:本次快照数据和下次快照数据。

深化了解Apache Flink核心技术(Apache Flink)  Apache Flink 大数据 第3张
图3 Flink包含快照符号音讯的音讯流

快照符号音讯沿着DAG流经各个操作符,当操作符处理到快照符号音讯时,会对自己的状况进行快照,并存储起来。当一个操作符有多个输入的时分,Flink会将先抵达的快照符号音讯及其之后的音讯缓存起来,当一切的输入中对应该次快照的快照符号音讯悉数抵达后,操作符对自己的状况快照并存储,之后处理一切快照符号音讯之后的已缓存音讯。操作符对自己的状况快照并存储可以是异步与增量的操作,并不需求堵塞音讯的处理。散布式快照的流程如图4所示:

深化了解Apache Flink核心技术(Apache Flink)  Apache Flink 大数据 第4张
图4 Flink散布式快照流程图

当一切的Data Sink(结尾操作符)都收到快照符号信息并对自己的状况快照和存储后,整个散布式快照就完成了,一起告诉数据源开释该快照符号音讯之前的一切音讯。若之后产生节点溃散等反常状况时,只需求康复之前存储的散布式快照状况,并从数据源重发该快照今后的音讯就可以了。

Exactly-Once是流处理体系需求支撑的一个十分重要的特性,它确保每一条音讯只被流处理体系处理一次,许多流处理使命的事务逻辑都依靠于Exactly-Once特性。相关于At-Least-Once或是At-Most-Once, Exactly-Once特性对流处理体系的要求更为严厉,完成也愈加困难。Flink依据散布式快照完成了Exactly-Once特性。

相关于其他流处理体系的容错计划,Flink依据散布式快照的计划在功用和功用方面都具有许多长处,包含:

低推迟。由于操作符状况的存储可以异步,所以进行快照的进程根本上不会堵塞音讯的处理,因而不会对音讯推迟产生负面影响。

高吞吐量。当操作符状况较少时,对吞吐量根本没有影响。当操作符状况较多时,相关于其他的容错机制,散布式快照的时刻距离是用户自界说的,所以用户可以权衡过错康复时刻和吞吐量要求来调整散布式快照的时刻距离。

与事务逻辑的阻隔。Flink的散布式快照机制与用户的事务逻辑是彻底阻隔的,用户的事务逻辑不会依靠或是对散布式快照产生任何影响。

过错康复价值。散布式快照的时刻距离越短,过错康复的时刻越少,与吞吐量负相关。

Flink流处理的时刻窗口

关于流处理体系来说,流入的音讯不存在上限,所以关于聚合或是衔接等操作,流处理体系需求对流入的音讯进行分段,然后依据每一段数据进行聚合或是衔接。音讯的分段即称为窗口,流处理体系支撑的窗口有许多类型,最常见的便是时刻窗口,依据时刻距离对音讯进行分段处理。本节首要介绍Flink流处理体系支撑的各种时刻窗口。

关于现在大部分流处理体系来说,时刻窗口一般是依据Task地点节点的本地时钟进行切分,这种办法完成起来比较简略,不会产生堵塞。可是或许无法满意某些运用需求,比方:

音讯自身带有时刻戳,用户期望依照音讯自身的时刻特性进行分段处理。

由于不同节点的时钟或许不同,以及音讯在流经各个节点的推迟不同,在某个节点归于同一个时刻窗口处理的音讯,流到下一个节点时或许被切分到不同的时刻窗口中,然后产生不符合预期的成果。

Flink支撑3种类型的时刻窗口,别离适用于用户关于时刻窗口不同类型的要求:

Operator Time。依据Task地点节点的本地时钟来切分的时刻窗口。

Event Time。音讯自带时刻戳,依据音讯的时刻戳进行处理,确保时刻戳在同一个时刻窗口的一切音讯必定会被正确处理。由于音讯或许乱序流入Task,所以Task需求缓存当时时刻窗口音讯处理的状况,直到承认归于该时刻窗口的一切音讯都被处理,才干够开释,假如乱序的音讯推迟很高会影响散布式体系的吞吐量和推迟。

Ingress Time。有时音讯自身并不带有时刻戳信息,但用户仍然期望依照音讯而不是节点时钟区分时刻窗口,例如防止上面说到的第二个问题,此刻可以在音讯源流入Flink流处理体系时主动生成增量的时刻戳赋予音讯,之后处理的流程与Event Time相同。Ingress Time可以看成是Event Time的一个特例,由于其在音讯源处时刻戳必定是有序的,所以在流处理体系中,相关于Event Time,其乱序的音讯推迟不会很高,因而对Flink散布式体系的吞吐量和推迟的影响也会更小。

Event Time时刻窗口的完成Flink学习了Google的MillWheel项目,经过WaterMark来支撑依据Event Time的时刻窗口。

当操作符经过依据Event Time的时刻窗口来处理数据时,它有必要在承认一切归于该时刻窗口的音讯悉数流入此操作符后才干开端数据处理。可是由于音讯或许是乱序的,所以操作符无法直接承认何时一切归于该时刻窗口的音讯悉数流入此操作符。WaterMark包含一个时刻戳,Flink运用WaterMark符号一切小于该时刻戳的音讯都已流入,Flink的数据源在承认一切小于某个时刻戳的音讯都已输出到Flink流处理体系后,会生成一个包含该时刻戳的WaterMark,刺进到音讯流中输出到Flink流处理体系中,Flink操作符依照时刻窗口缓存一切流入的音讯,当操作符处理到WaterMark时,它对一切小于该WaterMark时刻戳的时刻窗口数据进行处理并发送到下一个操作符节点,然后也将WaterMark发送到下一个操作符节点。

为了确保可以处理一切归于某个时刻窗口的音讯,操作符有必要比及大于这个时刻窗口的WaterMark之后才干开端对该时刻窗口的音讯进行处理,相关于依据Operator Time的时刻窗口,Flink需求占用更多内存,且会直接影响音讯处理的推迟时刻。对此,一个或许的优化办法是,关于聚合类的操作符,可以提早对部分音讯进行聚合操作,当有归于该时刻窗口的新音讯流入时,依据之前的部分聚合成果持续核算,这样的话,只需缓存中心核算成果即可,无需缓存该时刻窗口的一切音讯。

关于依据Event Time时刻窗口的操作符来说,流入WaterMark的时刻戳与当时节点的时钟共同是最简略抱负的状况,可是在实践环境中是不或许的,由于音讯的乱序以及前面节点处理功率的不同,总是会有某些音讯流入时刻大于其自身的时刻戳,实在WaterMark时刻戳与抱负状况下WaterMark时刻戳的不同称为Time Skew,如图5所示:

深化了解Apache Flink核心技术(Apache Flink)  Apache Flink 大数据 第5张
图5 WaterMark的Time Skew图

Time Skew决议了该WaterMark与上一个WaterMark之间的时刻窗口一切数据需求缓存的时刻,Time Skew时刻越长,该时刻窗口数据的推迟越长,占用内存的时刻也越长,一起会对流处理体系的吞吐量产生负面影响。

依据时刻戳的排序

在流处理体系中,由于流入的音讯是无限的,所以对音讯进行排序根本上被认为是不可行的。可是在Flink流处理体系中,依据WaterMark,Flink完成了依据时刻戳的大局排序。排序的完成思路如下:排序操作符缓存一切流入的音讯,当其接收到WaterMark时,对时刻戳小于该WaterMark的音讯进行排序,并发送到下一个节点,在此排序操作符中开释一切时刻戳小于该WaterMark的音讯,持续缓存流入的音讯,等候下一个WaterMark触发下一次排序。

由于WaterMark确保了在其之后不会呈现时刻戳比它小的音讯,所以可以确保排序的正确性。需求留意的是,假如排序操作符有多个节点,只能确保每个节点的流出音讯是有序的,节点之间的音讯不能确保有序,要完成大局有序,则只能有一个排序操作符节点。

经过支撑依据Event Time的音讯处理,Flink扩展了其流处理体系的运用规模,使得更多的流处理使命可以经过Flink来履行。

定制的内存办理

Flink项目依据Java及Scala等JVM言语,JVM自身作为一个各种类型运用的履行渠道,其对Java目标的办理也是依据通用的处理战略,其废物收回器经过预算Java目标的生命周期对Java目标进行有功率的办理。

针对不同类型的运用,用户或许需求针对该类型运用的特征,装备针对性的JVM参数更有功率的办理Java目标,然后进步功用。这种JVM调优的黑魔法需求用户对运用自身及JVM的各参数有深化了解,极大地进步了散布式核算渠道的调优门槛。Flink结构自身了解核算逻辑每个过程的数据传输,比较于JVM废物收回器,其了解更多的Java目标生命周期,然后为更有功率地办理Java目标供给了或许。

JVM存在的问题

Java目标开支

相关于c/c++等愈加挨近底层的言语,Java目标的存储密度相对偏低,例如[1],“abcd”这样简略的字符串在UTF-8编码中需求4个字节存储,但选用了UTF-16编码存储字符串的Java则需求8个字节,一起Java目标还有header等其他额定信息,一个4字节字符串目标在Java中需求48字节的空间来存储。关于大部分的大数据运用,内存都是稀缺资源,更有功率地内存存储,意味着CPU数据拜访吞吐量更高,以及更少磁盘落地的存在。

目标存储结构引发的cache miss

为了缓解CPU处理速度与内存拜访速度的距离[2],现代CPU数据拜访一般都会有多级缓存。当从内存加载数据到缓存时,一般是以cache line为单位加载数据,所以当CPU拜访的数据假如是在内存中接连存储的话,拜访的功率会十分高。假如CPU要拜访的数据不在当时缓存一切的cache line中,则需求从内存中加载对应的数据,这被称为一次cache miss。当cache miss十分高的时分,CPU大部分的时刻都在等候数据加载,而不是真实的处理数据。Java目标并不是接连的存储在内存上,一起许多的Java数据结构的数据集合性也欠好。

大数据的废物收回

Java的废物收回机制一向让Java开发者又爱又恨,一方面它免去了开发者自己收回资源的过程,进步了开发功率,削减了内存走漏的或许,另一方面废物收回也是Java运用的不守时炸弹,有时秒级乃至是分钟级的废物收回极大影响了Java运用的功用和可用性。在时下数据中心,大容量内存得到了广泛的运用,乃至呈现了单台机器装备TB内存的状况,一起,大数据剖析一般会遍历整个源数据集,对数据进行转化、清洗、处理等过程。在这个进程中,会产生海量的Java目标,JVM的废物收回履行功率对功用有很大影响。经过JVM参数调优进步废物收回功率需求用户对运用和散布式核算结构以及JVM的各参数有深化了解,并且有时分这也远远不行。

OOM问题

OutOfMemoryError是散布式核算结构常常会遇到的问题,当JVM中一切目标巨细超越分配给JVM的内存巨细时,就会呈现OutOfMemoryError过错,JVM溃散,散布式结构的健壮性和功用都会受到影响。经过JVM办理内存,一起企图处理OOM问题的运用,一般都需求查看Java目标的巨细,并在某些存储Java目标特别多的数据结构中设置阈值进行操控。可是JVM并没有供给官方查看Java目标巨细的东西,第三方的东西类库或许无法精确通用地承认Java目标巨细[6]。侵入式的阈值查看也会为散布式核算结构的完成添加许多额定与事务逻辑无关的代码。

Flink的处理战略

为了处理以上说到的问题,高功用散布式核算结构一般需求以下技能:

定制的序列化东西。显式内存办理的条件过程便是序列化,将Java目标序列化成二进制数据存储在内存上(on heap或是off-heap)。通用的序列化结构,如Java默许运用java.io.Serializable将Java目标及其成员变量的一切元信息作为其序列化数据的一部分,序列化后的数据包含了一切反序列化所需的信息。这在某些场景中十分必要,可是关于Flink这样的散布式核算结构来说,这些元数据信息或许是冗余数据。定制的序列化结构,如Hadoop的org.Apache.hadoop.io.Writable需求用户完成该接口,并自界说类的序列化和反序列化办法。这种办法功率最高,但需求用户额定的作业,不行友爱。

显式的内存办理。一般通用的做法是批量请求和开释内存,每个JVM实例有一个共同的内存办理器,一切内存的请求和开释都经过该内存办理器进行。这可以防止常见的内存碎片问题,一起由于数据以二进制的办法存储,可以大大减轻废物收回压力。

缓存友爱的数据结构和算法。关于核算密布的数据结构和算法,直接操作序列化后的二进制数据,而不是将目标反序列化后再进行操作。一起,只将操作相关的数据接连存储,可以最大化的运用L1/L2/L3缓存,削减Cache miss的概率,进步CPU核算的吞吐量。以排序为例,由于排序的首要操作是对Key进行比照,假如将一切排序数据的Key与Value分隔并对Key接连存储,那么拜访Key时的Cache射中率会大大进步。

定制的序列化东西

散布式核算结构可以运用定制序列化东西的条件是要待处理数据流一般是同一类型,由于数据集目标的类型固定,然后可以只保存一份目标Schema信息,节约许多的存储空间。一起,关于固定巨细的类型,也可经过固定的偏移方位存取。在需求拜访某个目标成员变量时,经过定制的序列化东西,并不需求反序列化整个Java目标,而是直接经过偏移量,然后只需求反序列化特定的目标成员变量。假如目标的成员变量较多时,可以大大削减Java目标的创立开支,以及内存数据的复制巨细。Flink数据集都支撑恣意Java或是Scala类型,经过主动生成定制序列化东西,既确保了API接口对用户友爱(不必像Hadoop那样数据类型需求承继完成org.apache.hadoop.io.Writable接口),也达到了和Hadoop相似的序列化功率。

Flink对数据集的类型信息进行剖析,然后主动生成定制的序列化东西类。Flink支撑恣意的Java或是Scala类型,经过Java Reflection结构剖析依据Java的Flink程序UDF(User Define Function)的回来类型的类型信息,经过Scala Compiler剖析依据Scala的Flink程序UDF的回来类型的类型信息。类型信息由TypeInformation类表明,这个类有许多具体完成类,例如:

  • BasicTypeInfo恣意Java根本类型(装包或未装包)和String类型。
  • BasicArrayTypeInfo恣意Java根本类型数组(装包或未装包)和String数组。
  • WritableTypeInfo恣意Hadoop的Writable接口的完成类。
  • TupleTypeInfo恣意的Flink tuple类型(支撑Tuple1 to Tuple25)。 Flink tuples是固定长度固定类型的Java Tuple完成。
  • CaseClassTypeInfo恣意的 Scala CaseClass(包含 Scala tuples)。
  • PojoTypeInfo恣意的POJO (Java or Scala),例如Java目标的一切成员变量,要么是public修饰符界说,要么有getter/setter办法。
  • GenericTypeInfo恣意无法匹配之前几种类型的类。

前6种类型数据集简直覆盖了绝大部分的Flink程序,针对前6种类型数据集,Flink皆可以主动生成对应的TypeSerializer定制序列化东西,十分有功率地对数据集进行序列化和反序列化。关于第7种类型,Flink运用Kryo进行序列化和反序列化。此外,关于可被用作Key的类型,Flink还一起主动生成TypeComparator,用来辅佐直接对序列化后的二进制数据直接进行compare、hash等操作。关于Tuple、CaseClass、Pojo等组合类型,Flink主动生成的TypeSerializer、TypeComparator同样是组合的,并把其成员的序列化/反序列化署理给其成员对应的TypeSerializer、TypeComparator,如图6所示:

深化了解Apache Flink核心技术(Apache Flink)  Apache Flink 大数据 第6张
图6 Flink组合类型序列化

此外如有需求,用户可经过集成TypeInformation接口定制完成自己的序列化东西。

显式的内存办理

废物收回是JVM内存办理逃避不了的问题,JDK8的G1算法改进了JVM废物收回的功率和可用规模,但关于大数据处理实践环境还远远不行。这也和现在散布式结构的开展趋势有所抵触,越来越多的散布式核算结构期望尽或许多地将待处理数据集放入内存,而关于JVM废物收回来说,内存中Java目标越少、存活时刻越短,其功率越高。经过JVM进行内存办理的话,OutOfMemoryError也是一个很难处理的问题。一起,在JVM内存办理中,Java目标有潜在的碎片化存储问题(Java目标一切信息或许在内存中接连存储),也有或许在一切Java目标巨细没有超越JVM分配内存时,呈现OutOfMemoryError问题。Flink将内存分为3个部分,每个部分都有不同用处:

Network buffers: 一些以32KB Byte数组为单位的buffer,首要被网络模块用于数据的网络传输。

Memory Manager pool许多以32KB Byte数组为单位的内存池,一切的运行时算法(例如Sort/Shuffle/Join)都从这个内存池请求内存,并将序列化后的数据存储其间,完毕后开释回内存池。

Remaining (Free) Heap首要留给UDF中用户自己创立的Java目标,由JVM办理。

Network buffers在Flink中首要依据Netty的网络传输,无需多讲。Remaining Heap用于UDF中用户自己创立的Java目标,在UDF中,用户一般是流式的处理数据,并不需求许多内存,一起Flink也不鼓舞用户在UDF中缓存许多数据,由于这会引起前面说到的许多问题。Memory Manager pool(今后以内存池代指)一般会装备为最大的一块内存,接下来会具体介绍。

在Flink中,内存池由多个MemorySegment组成,每个MemorySegment代表一块接连的内存,底层存储是byte[],默许32KB巨细。MemorySegment供给了依据偏移量拜访数据的各种办法,如get/put int、long、float、double等,MemorySegment之间数据复制等办法和java.nio.ByteBuffer相似。关于Flink的数据结构,一般包含多个向内存池请求的MemeorySegment,一切要存入的目标经过TypeSerializer序列化之后,将二进制数据存储在MemorySegment中,在取出时经过TypeSerializer反序列化。数据结构经过MemorySegment供给的set/get办法拜访具体的二进制数据。Flink这种看起来比较复杂的内存办理办法带来的长处首要有:

二进制的数据存储大大进步了数据存储密度,节约了存储空间。

一切的运行时数据结构和算法只能经过内存池请求内存,确保了其运用的内存巨细是固定的,不会由于运行时数据结构和算法而产生OOM。关于大部分的散布式核算结构来说,这部分由于要缓存许多数据最有或许导致OOM。

内存池尽管占有了大部分内存,但其间的MemorySegment容量较大(默许32KB),所以内存池中的Java目标其实很少,并且一向被内存池引证,一切在废物收回时很快进入耐久代,大大减轻了JVM废物收回的压力。

Remaining Heap的内存尽管由JVM办理,可是由于其首要用来存储用户处理的流式数据,生命周期十分短,速度很快的Minor GC就会悉数收回掉,一般不会触发Full GC。

Flink当时的内存办理在最底层是依据byte[],所以数据终究仍是on-heap,最近Flink添加了off-heap的内存办理支撑。Flink off-heap的内存办理相关于on-heap的长处首要在于:

发动分配了大内存(例如100G)的JVM很消耗时刻,废物收回也很慢。假如选用off-heap,剩余的Network buffer和Remaining heap都会很小,废物收回也不必考虑MemorySegment中的Java目标了。

更有功率的IO操作。在off-heap下,将MemorySegment写到磁盘或是网络可以支撑zeor-copy技能,而on-heap的话则至少需求一次内存复制。

off-heap可用于过错康复,比方JVM溃散,在on-heap时数据也随之丢掉,但在off-heap下,off-heap的数据或许还在。此外,off-heap上的数据还可以和其他程序同享。

缓存友爱的核算

磁盘IO和网络IO之前一向被认为是Hadoop体系的瓶颈,可是跟着Spark、Flink等新一代散布式核算结构的开展,越来越多的趋势使得CPU/Memory逐步成为瓶颈,这些趋势包含:

更先进的IO硬件逐步遍及。10GB网络和SSD硬盘等现已被越来越多的数据中心运用。

更高效的存储格局。Parquet,ORC等列式存储被越来越多的Hadoop项目支撑,其十分高效的紧缩功用大大削减了落地存储的数据量。

更高效的履行计划。例如许多SQL体系履行计划优化器的Fliter-Push-Down优化会将过滤条件尽或许的提早,乃至提早到Parquet的数据拜访层,使得在许多实践的作业负载中并不需求许多的磁盘IO。

由于CPU处理速度和内存拜访速度的距离,进步CPU的处理功率的要害在于最大化的运用L1/L2/L3/Memory,削减任何不必要的Cache miss。定制的序列化东西给Flink供给了或许,经过定制的序列化东西,Flink拜访的二进制数据自身,由于占用内存较小,存储密度比较大,并且还可以在规划数据结构和算法时尽量接连存储,削减内存碎片化对Cache射中率的影响,乃至更进一步,Flink可以仅仅将需求操作的部分数据(如排序时的Key)接连存储,而将其他部分的数据存储在其他当地,然后最大或许地进步Cache射中的概率。

以Flink中的排序为例,排序一般是散布式核算结构中一个十分重的操作,Flink经过特别规划的排序算法获得了十分好的功用,其排序算法的完成如下:

将待排序的数据经过序列化后存储在两个不同的MemorySegment会集。数据悉数的序列化值存放于其间一个MemorySegment会集。数据序列化后的Key和指向第一个MemorySegment会集值的指针存放于第二个MemorySegment会集。

对第二个MemorySegment会集的Key进行排序,如需交流Key方位,只需交流对应的Key+Pointer的方位,第一个MemorySegment会集的数据无需改动。 当比较两个Key巨细时,TypeComparator供给了直接依据二进制数据的比照办法,无需反序列化任何数据。

排序完成后,拜访数据时,依照第二个MemorySegment会集Key的次序拜访,并经过Pointer值找到数据在第一个MemorySegment会集的方位,经过TypeSerializer反序列化成Java目标回来。

深化了解Apache Flink核心技术(Apache Flink)  Apache Flink 大数据 第7张
图7 Flink排序算法

这样完成的长处有:

  • 经过Key和Full data别离存储的办法尽量将被操作的数据最小化,进步Cache射中的概率,然后进步CPU的吞吐量。
  • 移动数据时,只需移动Key+Pointer,而无须移动数据自身,大大削减了内存复制的数据量。
  • TypeComparator直接依据二进制数据进行操作,节约了反序列化的时刻。
  • 经过定制的内存办理,Flink经过充分运用内存与CPU缓存,大大进步了CPU的履行功率,一起由于大部分内存都由结构自己操控,也很大程度进步了体系的健壮性,削减了OOM呈现的或许。

总结

本文首要介绍了Flink项意图一些要害特性,Flink是一个具有许多特征的项目,包含其共同的批处理和流处理履行引擎,通用大数据核算结构与传统数据库体系的技能结合,以及流处理体系的许多技能创新等,由于篇幅有限,Flink还有一些其他很有意思的特性没有具体介绍,比方DataSet API等级的履行计划优化器,原生的迭代操作符等,感兴趣的读者可以经过Flink官网了解更多Flink的具体内容。期望经过本文的介绍可以让读者对Flink有更多的了解,也让更多的人运用乃至参加到Flink项目中去。

转载请说明出处
知优网 » 深化了解Apache Flink核心技术(Apache Flink)

发表评论

您需要后才能发表评论