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 进程会因多种原因将数据存储到本地文件系统,包括:

  1. 接收application JAR 文件
  2. 写日志文件
  3. (若是配置了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系统配置的更多相关文章

  1. Flink 源码解析 —— 深度解析 Flink 是如何管理好内存的?

    前言 如今,许多用于分析大型数据集的开源系统都是用 Java 或者是基于 JVM 的编程语言实现的.最着名的例子是 Apache Hadoop,还有较新的框架,如 Apache Spark.Apach ...

  2. 【源码解析】Flink 是如何基于事件时间生成Timestamp和Watermark

    生成Timestamp和Watermark 的三个重载方法介绍可参见上一篇博客: Flink assignAscendingTimestamps 生成水印的三个重载方法 之前想研究下Flink是怎么处 ...

  3. 第07讲:Flink 常见核心概念分析

    Flink系列文章 第01讲:Flink 的应用场景和架构模型 第02讲:Flink 入门程序 WordCount 和 SQL 实现 第03讲:Flink 的编程模型与其他框架比较 第04讲:Flin ...

  4. CentOS系统配置 iptables防火墙

    阿里云CentOS系统配置iptables防火墙   虽说阿里云推出了云盾服务,但是自己再加一层防火墙总归是更安全些,下面是我在阿里云vps上配置防火墙的过程,目前只配置INPUT.OUTPUT和FO ...

  5. Jenkins插件安装和系统配置

    前面我们只是把Jenkins部署在Tomcat中了,下面来看看Jenkins中的插件和一些基础的系统配置. 1.用户管理 我们一般的项目组肯定是由多名成员组成的,如何向Jenkins添加我们的成员呢? ...

  6. apache flink 入门

    配置环境 包括 JAVA_HOME jobmanager.rpc.address jobmanager.heap.mb 和 taskmanager.heap.mb taskmanager.number ...

  7. Flink 1.1 – ResourceManager

    Flink resource manager的作用如图,   FlinkResourceManager /** * * <h1>Worker allocation steps</h1 ...

  8. Apache Flink初接触

    Apache Flink闻名已久,一直没有亲自尝试一把,这两天看了文档,发现在real-time streaming方面,Flink提供了更多高阶的实用函数. 用Apache Flink实现WordC ...

  9. Flink - InstanceManager

    InstanceManager用于管理JobManager申请到的taskManager和slots资源 /** * Simple manager that keeps track of which ...

随机推荐

  1. 剑指offer-面试题7-重建二叉树-二叉树

    /* 题目: 输入二叉树的前序遍历和中序遍历的结果,重建二叉树.假设输入的前序遍历和中序遍历的结果中不包含重复的数字. */ /* 思路: 使用前序遍历找到根节点,再通过中序遍历找到左子树和右子树. ...

  2. 安全 - CORS(脚本请求等)

    功能概述 出于安全原因,浏览器限制从脚本内发起的跨域HTTP请求 或 拦截了跨域请求的结果. 例如,XMLHttpRequest和Fetch API遵循同源策略. 这意味着使用这些API的Web应用程 ...

  3. H5-设置缓存

    <meta http-equiv="Cache-Control"content="no-cache"/> 手机页面通常在第一次加载后会进行缓存,然后 ...

  4. 0级搭建类006-Oracle Solaris 安装 (10.13) 公开

    项目文档引子系列是根据项目原型,制作的测试实验文档,目的是为了提升项目过程中的实际动手能力,打造精品文档AskScuti. 项目文档引子系列目前不对外发布,仅作为博客记录.如学员在实际工作过程中需提前 ...

  5. jQuery---淘宝精品案例

    淘宝精品案例 <!DOCTYPE html> <html> <head lang="en"> <meta charset="UT ...

  6. Unable to open debugger port (127.0.0.1:13249): java.net.BindException "Address already in use: JVM_Bind"

    这个问题比较简单一点,Tomcat的端口被占用了,我使用的是IDEA里的一个热部署插件JReble,更新了IDEA之后就发现端口被占用了,可能我电脑没有重启过吧, 一直被占用着,所以解决方法就是更换一 ...

  7. 如何与GitHub同步,将本地文件push到到远程仓库

    Run git config --global user.email "you@example.com" git config --global user.name "Y ...

  8. 1080 Graduate Admission

    大致题意就是有N个学生,有M个学校,每个学校的名额都是正整数.每个学生可以填K个学校志愿,N个学生一起排名以后,排名高的学生先挑学校,不保护一志愿. 题目要求: 首先,把所有学生按总成绩SUM(GE+ ...

  9. PHPstorm出现卡顿解决小记

    用的是PHPstorm9,在打开了两个比较大的文件之后,码字反应变得很慢,久不久操作快点还会出现转蓝色小圈圈,最后还给了我这个提示TOT: google了下说是设置的内存不够了,看了下任务管理器php ...

  10. Nginx实现前端访问后端本地接口

    Nginx配置两个地方就行: 先是配置好自己项目的服务,确保自己的项目能运行: location / { root /web/xiangmu/public; // 本地项目的路径 index inde ...