Flink系统配置
Flink 系统配置
Flink 提供了多个配置参数,用于调整Flink的行为与性能,所有参数均在flink-config.yaml 文件中。下面我们介绍一下几个主要配置。
Java and Classloading
默认情况下,Flink启动JVM进程时,会使用系统环境变量里的PATH路径。当然,如果要使用自定义的Java 版本,可以指定JAVA_HOME 环境变量,或是Flink配置文件里的env.java.home 参数。Flink的JVM进程在启动时,也可以配置自定义的JVM 选项(例如 gc 参数),配置的参数为env.java.opts,或者 env.java.opts.jobmanager,以及 env.java.opts.taskmanager.
如果执行的Flink任务使用的是外部依赖(而不是系统本地依赖),则一般不会有Classloading(类加载)的问题。在执行一个Flink应用时,此Flink程序jar包中所有的classes都必须通过一个classloader载入。Flink会将每个job的classes注册到一个独立的user-code classloader中,以确保执行的job的依赖不会与Flink的runtime依赖、或者其他job的依赖产生冲突。User-code class loaders 在job停掉的时候,会被清除。Flink系统的class loader会载入 lib 目录下所有的jar 包文件,而user-code classloaders 亦是源于Flink系统的classloader。
默认情况下,Flink首先在child classloader(也就是user-code classloader)中查询user-code classes,然后在parent classloader(也就是系统classloader)查询classes。此机制可以避免job与Flink系统的版本冲突。不过,我们也可以通过配置classloader.resolve-order 参数转变此顺序,默认为child-first,可以修改为parent-first。
需要注意的是,有些在parent classloader中的类会永远优先于child classloader载入,这些类在参数classloader.parent-first-patterns.default中指定。我们也可以在参数 classloader.parent-first-patterns.additional中指定一组classes,用于优先载入。
CPU
Flink 并不会主动限制它消耗的CPU资源,它通过processing slots来控制一个worker 进程(也就是TaskManager)可以被分配的tasks数。一个TaskManger提供了特定数目的slots,它们注册于ResourceManager,并被其所管理。在执行程序时,一个JobManager会申请一个或多个slots,用于执行任务。一个slot可以运行一个application中任意operator的一个并行任务。所以JobManager需要至少申请operator最大并行度的slots数,才能保证任务正常执行。Task在TaskManager中以线程的方式执行,并且按需使用CPU资源。
TaskManager可提供的slots数量由taskmanager.numberOfTaskSlots 参数指定,默认为1。也就是每个TaskManager会提供一个slot。一般仅会在standalone模式下需要调整此参数,在YARN、Kubernetes、Mesos中不需要调整,因为它们可以根据资源申请更多container,而多个container也可以运行在单个节点上,效果与TaskManager中的slot基本一致。
Main Memory and NetworkBuffers
Flink的master与worker进程有不同的内存需求。Master进程主要管理计算资源(也就是ResourceManager)以及协调applications的执行(也就是JobManager)。而worker进程的需要进行各类计算并处理数据(可能是大量数据)。
一般来说,master进程的内存需求并不是特别大。默认情况下,它使用1GB的JVM堆内存。如果一个master进程需要管理多个applications,或者有多个operators的一个application,则我们可能需要通过jobmanager.heap.size配置增加它的堆内存。
配置worker进程的内存时,考虑的方面会更多,因为其中会有不同的组件分配不同类型的内存资源。最重要的是JVM 堆内存,通过taskmanager.heap.size进行配置。堆内存由所有objects使用,包括TaskManager runtime、operators、application的functions、以及传输的数据。若一个应用使用的是in-memory或是filesystem 的state backend,则state数据也会存储在JVM。需要注意的是单个task也是有可能消耗掉它所处JVM所有堆内存的。为每个TaskManager仅配置一个slot,会有更好的资源分离,并且防止不同application之间的异常干扰。如果一个application有很多依赖包,则JVM noheap内存也可以增长到很大,因为这部分noheap内存存储了所有TaskManager classes与user-code classes。
除了JVM,还有另外两部分内存消耗:Flink的网络栈与RocksDB(若是使用了它作为state backend)。Flink的网络栈基于的是Netty库,它从native memory(也就是off-heap memory)中分配网络缓冲区(network buffers)。Flink需要足够数量的network buffers,用于在worker 进程之间交换records。缓冲区的数量取决于operator tasks之间的网络连接数量。若是一个application有多个partitioning steps,则此数量的总量可能会非常大,并需要大量的内存用于网络传输。
Flink的默认配置仅适用于较小的计算规模,若是集群计算规模较大,则需要做对应参数调整。如果buffers的数量配置的不合适,则job提交后会抛出以下异常:
java.io.IOException: Insufficient number of network buffers
遇到此情况后,需要为网络栈提供更多的内存。
分配给network buffers内存大小的参数由taskmanager.network.memory.fraction 指定,表示的是JVM内存的百分比多少用于network buffers。taskmanager.memory.segment-size参数指定的是一个network buffer的大小,默认是32KB。调小此参数,也就意味了可以增加network buffers数,但是会影响网络栈的效率。当然,也可以设置network buffer使用内存的最小值(taskmanager.network.memory.min)与最大值(taskmanager.network.memory.max),默认分别为 64MB 与 1GB。这两个绝对值可以限制配置的相对值(也就是之前提到的内存比例)。
RocksDB是另一个需要考虑的内存消耗因素(此处仍然是worker 进程中的内存)。但是衡量RocksDB消耗多少内存一般很难有个直接的结果,因为它取决于一个application中keyed states的数量。Flink会为一个keyed operator的每个task均创建一个独立的(也是内嵌的)RocksDB实例。在每个实例内部,每个不同的state均被存储在一个特定的列族(或表)中。在默认配置下,每个列族需要大约200MB到240MB的堆外内存。对于RocksDB的参数调整,暂时没有一个万金油,需要根据业务进行多个参数调整与测试,然后观察性能。
所以我们在配置调整TaskManager的内存时,主要调整的是JVM的堆内存、RocksDB(如果它是作为state backend)、以及用于网络栈的内存。
磁盘
一个Flink worker 进程会因多种原因将数据存储到本地文件系统,包括:
- 接收application JAR 文件
- 写日志文件
- (若是配置了RocksDB为state backend)维护application state
与磁盘相关的配置项有 io.tmp.dirs,我们可以指定一个或多个文件夹(以冒号为分隔符),用于存储数据到本地文件系统。默认情况下,数据会写入到默认的临时文件夹(由Java 的 java.io.tmpdir 指定)或是Linux的临时文件夹(/tmp)。
需要注意的是:请确保临时目录不会被自动清除,有些Linux 发行版会自动清除临时文件夹/tmp。请务必关闭此功能,否则会在job recovery时,由于/tmp文件夹被清理,导致丢失metadata,并最终job 失败。
blob.storage.directory 的参数指定了blob server的本地存储文件夹,用于exchange较大的文件(例如application JAR 文件)。env.log.dir 的参数指定的是TaskManager写入日志的文件夹。最后,RocksDB state backend 会将application的state维持在本地文件系统中。此目录由state.backend.rocksdb.localdir 参数指定。如果此配置文件未显示指定,则RocksDB会使用io.tmp.dirs 参数的值。
Checkpointing 与State Backends
Flink提供几种选项,用于设置:state backends 如何给它们的state做检查点(checkpoint)。一般我们会在application 代码里手动指定。当然我们也可以通过 Flink 的配置文件,提供默认选项。如果未在代码里指定此选项,则会使用默认选项。
State backend 维护的是application的state,所以它也会直接影响到一个application的性能。我们可以通过state.backend 指定默认的state backend。进一步的,我们可以启用异步检查点(state.backend.async)以及增量检查点(state.backend.incremental)。一些backend 并不支持所有的这些选项,所以可能会直接忽视这些配置。我们也可以配置用于检查点(checkpoint)与保存点(savepoint)写入的远端存储根目录。配置参数分别为 state.checkpoint.dir 以及 state.savepoints.dir。
一些检查点的选项是某些state backend 特有的。对于RocksDB state backend来说,我们可以定义一个或多个RocksSB存储它本地文件的路径(state.backend.rocksdb.localdir),以及timer state是存储在堆内存(默认是存堆内存)还是RocksDB(配置的参数项为state.backend.rocksdb.timer-service.factory)。
最后,我们可以为一个Flink集群默认启用并配置本地recovery,参数为 state.backend.local-recovery(设置为true即可)。Local state的副本存储的位置也可以配置,参数为 taskmanager.state.local.root-dirs。
安全
在Flink中,需要对无授权的访问以及数据访问进行安全地限制。对此,Flink支持Kerberos认证,并且可以配置使用SSL对所有网络通信加密。
Flink可以支持Kerberos接入Hadoop生态(YARN,HDFS,HBase)、以及ZooKeeper与Kafka。Flink支持两种认证模式:Keytabs与Hadoop delegation tokens。Keytabs是较好的选择,因为tokens会在一段时间后失效,对长时间流处理应用产生影响。需要注意的是,认证密钥是绑定于Flink集群,而不是一个单独的任务。所有运行在同一个集群上的applications使用同样的认证token。如果需要换另外的credentials,则可以启动一个新集群。配置方法可以参考Flink官方文档。
Flink支持两个通信端的双向认证,并且可以通过SSL对内部或外部网络通信进行加密。对于内部的通信(RPC调用,数据传输,以及blob 服务通信(用于分发libraries等文件),所有的Flink 进程(Dispathcer、ResourceManager、JobManager以及TaskManager)均可以执行双向认证 – 也就是发送端与服务端可以通过SSL证书进行验证。此证书作为一个共享密钥,可以内嵌到containers或附加到YARN启动项里。
对于所有外部与Flink服务的通信(提交任务、控制任务、以及访问REST 接口等),我们也可以启用SSL为这些通信进行加密。双向认证也可以被启用。不过,较为推荐的方法是:配置一个代理服务,用于控制对REST终端节点的访问。因为代理服务可以提供更多的认证与配置选项(相对于Flink来说)。
默认情况下,SSL认证与加密未启用,因为需要额外的手动配置项(如证书、设置KeyStores与TrustStores等)。若有需要,可以参考Flink官方文档进行配置。
References:
Vasiliki Kalavri, Fabian Hueske. Stream Processing With Apache Flink. 2019
Flink系统配置的更多相关文章
- Flink 源码解析 —— 深度解析 Flink 是如何管理好内存的?
前言 如今,许多用于分析大型数据集的开源系统都是用 Java 或者是基于 JVM 的编程语言实现的.最着名的例子是 Apache Hadoop,还有较新的框架,如 Apache Spark.Apach ...
- 【源码解析】Flink 是如何基于事件时间生成Timestamp和Watermark
生成Timestamp和Watermark 的三个重载方法介绍可参见上一篇博客: Flink assignAscendingTimestamps 生成水印的三个重载方法 之前想研究下Flink是怎么处 ...
- 第07讲:Flink 常见核心概念分析
Flink系列文章 第01讲:Flink 的应用场景和架构模型 第02讲:Flink 入门程序 WordCount 和 SQL 实现 第03讲:Flink 的编程模型与其他框架比较 第04讲:Flin ...
- CentOS系统配置 iptables防火墙
阿里云CentOS系统配置iptables防火墙 虽说阿里云推出了云盾服务,但是自己再加一层防火墙总归是更安全些,下面是我在阿里云vps上配置防火墙的过程,目前只配置INPUT.OUTPUT和FO ...
- Jenkins插件安装和系统配置
前面我们只是把Jenkins部署在Tomcat中了,下面来看看Jenkins中的插件和一些基础的系统配置. 1.用户管理 我们一般的项目组肯定是由多名成员组成的,如何向Jenkins添加我们的成员呢? ...
- apache flink 入门
配置环境 包括 JAVA_HOME jobmanager.rpc.address jobmanager.heap.mb 和 taskmanager.heap.mb taskmanager.number ...
- Flink 1.1 – ResourceManager
Flink resource manager的作用如图, FlinkResourceManager /** * * <h1>Worker allocation steps</h1 ...
- Apache Flink初接触
Apache Flink闻名已久,一直没有亲自尝试一把,这两天看了文档,发现在real-time streaming方面,Flink提供了更多高阶的实用函数. 用Apache Flink实现WordC ...
- Flink - InstanceManager
InstanceManager用于管理JobManager申请到的taskManager和slots资源 /** * Simple manager that keeps track of which ...
随机推荐
- PIE-SDK For C++矢量数据空间索引的创建
1.功能简介 空间索引的使用便于数据的查询:所以在创建矢量数据的时候创建空间索引,下面对矢量数据如何创建空间索引进行功能介绍. 2.功能实现说明 2.1 实现思路及原理说明 第一步 创建矢量要素数据集 ...
- sqli-labs less-5 --> less-6
盲注笔记: SQL盲注攻击:只有两种回显结果,错误和正确:无法用url查询爆出数据库的信息:回显注入语句中加入判断方式,使得回显结果为true或者false: SQL盲注分类:布尔盲注,时间盲注,报错 ...
- Maven的作用
Maven的作用 1.在开发中,为了保证编译通过,我们会到处去寻找jar包,当编译通过了,运行的时候,却发现"ClassNotFoundException",我们想到的是,难道还差 ...
- sql server针对字符串型数字排序(针对此字符串的长度不一致)
对于不规则的字符串数字排序,无法按照数字大的大小排序的原因是,字符串数字在数据库中按照ASCII码排序,从字符的第一个数字对比,首先就会将为首个数字相同的排在一起,在从这些字符串里面对比第二个数字,如 ...
- IDEA 解决Number objects are compared using '==', not 'equals()' 警告
当代码被工具标黄色高亮时,代表需要优化或重构了 == 是值相等.对于Integer这样的数据类型而言,意义是两个Integer对象的内存地址相等.也就是说如果你有两个不同的Integer的对象, 如果 ...
- WeUI基础样式库——写一个移动端界面
WeUI是一套基础样式库,同微信原生视觉体验一致,由微信官方设计团队为微信内网页和微信小程序量身设计的.我们来看看这个基础库样式到底长什么样. 这些密密麻麻的就是压缩后的样式库.密密麻麻地看起来简直要 ...
- 0级搭建类010-Oracle Linux 6.x安装(OEL 6.10) 公开
项目文档引子系列是根据项目原型,制作的测试实验文档,目的是为了提升项目过程中的实际动手能力,打造精品文档AskScuti. 项目文档引子系列目前不对外发布,仅作为博客记录.如学员在实际工作过程中需提前 ...
- 文件分配表(FAT)及其结构
原链接:https://blog.csdn.net/qianjintianguo/article/details/712590?utm_source=blogxgwz6 文件分配表(FAT)是文件管理 ...
- 844. 走迷宫(bfs模板)
给定一个n*m的二维整数数组,用来表示一个迷宫,数组中只包含0或1,其中0表示可以走的路,1表示不可通过的墙壁. 最初,有一个人位于左上角(1, 1)处,已知该人每次可以向上.下.左.右任意一个方向移 ...
- 曼孚科技:数据标注,AI背后的百亿市场
1. 两年前,来自山东农村的王磊成为了一位数据标注员.彼时的他,工作内容非常简单且枯燥:识别图片中人的性别. 然而,一段时间之后,他注意到分配给他的任务开始变得越来越复杂:从识别性别到年龄,从框选 ...