首页 > 系统相关 >关于Flink内存分配核心知识点

关于Flink内存分配核心知识点

时间:2024-09-02 10:52:41浏览次数:11  
标签:知识点 network Flink taskmanager TM 内存 memory


这个问题同样也是之前辅导过的同学的面试问题,这个问题非常接地气且考察面试者的实践经验。事实上,这也是我们大数据提高班的Flink专项提高部分内容。

下面我列举的这些就是核心,能答出这些重点即可。

内存模型在Flink1.9和Flink1.11版本做了非常大的改动,主要原因是为了统一Batch和Streaming的内存配置。首先我建议大家只看Flink1.11版本的内存配置即可。

有两个FLIP可以参考,这两个FLIP你能看懂的话就能完全掌握Flink的内存配置。

  • FLIP-116: Unified Memory Configuration for Job Managers
  • FLIP-49: Unified Memory Configuration for TaskExecutors

我们分情况来说。

JobManager内存模型

Flink1.11后的JM内存模型如下:

关于Flink内存分配核心知识点_java

两个版本之间最大的变化是:

  • Flink 1.9 中只有堆内、堆外两个内存模块;
  • Flink 1.11 中将 Flink 1.9 的堆外模块细分为 Direct Memory、JVM Metaspace 和 JVM Overhead 三类;

核心的参数如下:

关于Flink内存分配核心知识点_大数据_02

举个例子,假设 JM 配置的总内存大小为 1GB,那么 JM 在启动时,生成的 JVM 命令如下:

-Xmx469762048 
-Xms469762048 
-XX: MaxDirectMemorySize=134217728 
-XX:MaxMetaspaceSize=268435456,

计算结果:

  1. Heap: 1g - 128m - 256m - 192m = 448MB;
  2. DirectMemory:128MB;
  3. Metaspace:256MB;
  4. Overhead:min(max(192m, 0.1 * 1g), 1g) = 192m

JM的内存配置建议是:只需要配置JM的总内存大小,其余全部默认即可。

TaskManager内存模型

Flink1.11后的TM内存模型如下:

关于Flink内存分配核心知识点_.net_03

TaskManager核心配置参数如下:

关于Flink内存分配核心知识点_java_04

TM的内存配置建议:只需要配置TM的总内存大小,其余全部默认即可。

举个例子,假设一个任务的 TM 内存配置为 4196 MB,运行时的 JVM 参数被设置如下:

# JVM 配置
-Xmx973204290  # 928.12MB
-Xms973204290
-XX:MaxDirectMemorySize= 1241639855  # 1184.12MB
-XX:MaxMetaspaceSize=268435456   # 256MB

# 计算的配置
taskmanager.memory.framework.off-heap.size=134217728b
taskmanager.memory.network.max=1107422127b
taskmanager.memory.network.min=1107422127b
taskmanager.memory.task.off-heap.size=0b
taskmanager.memory.framework.heap.size=134217728b
taskmanager.memory.task.heap.size=838986562b
taskmanager.memory.managed.size=1476562799b

注意,这里有个特殊的配置需要注意,如果你的任务TM个数过多,会出现类似如下的错误:

java.io.IOException: Insufficient number of network buffers: required xxx, but only xxx available. The total number of network buffers is currently set to xxx of xxx bytes each. You can increase this number by setting the configuration keys 'taskmanager.network.memory.fraction', 'taskmanager.network.memory.min', and 'taskmanager.network.memory.max'.
        at org.apache.flink.runtime.io.network.buffer.NetworkBufferPool.createBufferPool(NetworkBufferPool.java:363)
        at org.apache.flink.runtime.io.network.partition.ResultPartitionFactory.lambda$createBufferPoolFactory$0(ResultPartitionFactory.java:207)
        at org.apache.flink.runtime.io.network.partition.ResultPartition.setup(ResultPartition.java:131)
        at org.apache.flink.runtime.taskmanager.Task.setupPartitionsAndGates(Task.java:898)
        at org.apache.flink.runtime.taskmanager.Task.doRun(Task.java:648)
        at org.apache.flink.runtime.taskmanager.Task.run(Task.java:539)
        at java.lang.Thread.run(Thread.java:748)

原因是因为作业TM之间shuffle数据时,network buffer不足。通过调整taskmanager.memory.network.min,taskmanager.memory.network.maxtaskmanager.memory.network.fraction即可。

加餐,内存设置和并行度关系

最后,估算一个任务的内存消耗,要和并行度的指定搭配进行。

举个例子,假如我们估算一个任务需要消耗的总内存是20G,这时候资源该怎么分配呢?

我们可以指定TM个数=2,单个TM消耗10G内存,2x10=20G;也可以指定TM个数=10,单个TM消耗2G内存,10x2=20G。

这两种方式有区别吗?当然有。

假设我们TM个数=2,那么如果我的任务数据量较大,例如上游Source端的Kafka Partition数量为128,那么理论上我们需要指定的Flink任务的最大并行度至少是128,那么单个TM的Slot数量就应该是64,因为2x64=128。这会带来什么问题呢?单个TM分配64个Slot明显不太合理。

我们拿出官网的推荐:

关于Flink内存分配核心知识点_java_05

官网给出的建议值是:TakManager所拥有的cpu核数的整数倍(proportional to the number of physical CPU cores that the TaskManager's machine has)。

实际中我们单个TM分配的cpu一般是1的整数倍,例如2、4...,那么这时候单个TM的slot个数建议是20、40、80...。最好是cpu数量的整数倍,至于是多少倍,大家可以根据经验判断,一般来说建议是10-20倍左右。

当然,在Flink1.14版本后,对于希望更精细化调节资源消耗的用户,基于对特定场景的了解,Flink提供了细粒度资源管理。我们直接拿官网的图做对比:

关于Flink内存分配核心知识点_大数据_06

对于细粒度资源管理,Slot 资源请求包含用户指定的特定的资源配置文件。Flink 会遵从这些用户指定的资源请求并从 TaskManager 可用的资源中动态地切分出精确匹配的 slot。如上图所示,对于一个 slot,0.25Core 和 1GB 内存的资源申请,Flink 为它分配 slot 1。

对于没有指定资源配置的资源请求,Flink会自动决定资源配置,如上所示,TaskManager 的总资源是 1Core 和 4GB 内存,task 的 slot 数设置为2,Slot 2 被创建,并申请 0.5 Core和 2GB 的内存而没有指定资源配置。 在分配 Slot 1和 Slot 2后,在 TaskManager 留下 0.25 Core 和 1GB 的内存作为未使用资源。

所以你看这个问题其实是一环套一环的,有经验的面试官会继续往下追问。当然如果你掌握的足够好,也可以给出超出面试官期望的回答。

关于Flink内存分配核心知识点_大数据_07

标签:知识点,network,Flink,taskmanager,TM,内存,memory
From: https://blog.51cto.com/u_9928699/11895903

相关文章

  • Python知识点:如何使用Python实现图像分类
    使用Python实现图像分类通常涉及使用深度学习库,如TensorFlow或PyTorch。以下是使用TensorFlow和Keras来实现一个简单图像分类模型的步骤。1.安装所需的库首先,确保已安装必要的Python库。使用以下命令安装TensorFlow和其他必需的库:pipinstalltensorflown......
  • 多线程篇(ThreadLocal & 内存模型 & 伪共享(ThreadLocal ))(持续更新迭代)
    目录一、ThreadLocal1.前言2.简介3.与Synchronized的区别4.简单使用5.原理5.1.set5.2.get5.3.remove5.4.与Thread,ThreadLocalMap之间的关系5.常见使用场景场景一:存储用户Session场景二、数据库连接,处理数据库事务场景三、数据跨层传递(controller,servi......
  • 多线程篇(ThreadLocal & 内存模型 & 伪共享(内存可见性))(持续更新迭代)
    目录一、内存可见性问题(并发编程之美)二、Java内存模型(深入理解JVM第三版)1.简介2.硬件的效率与一致性3.Java内存模型3.1主内存与工作内存3.2内存间交互操作3.3对于volatile型变量的特殊规则3.4针对long和double型变量的特殊规则3.5原子性、可见性与有序性原......
  • 15、java 面向对象之二:对象的创建和使用(对象内存解析和匿名对象)、再谈方法(方法的重
    java面向对象之二:Ⅰ、对象的创建和使用:1、对象的内存解析:其一、描述:其二、内存解析代码1为:其三、内存解析截图1为:其四、内存解析代码2为:其五、内存解析截图2为:2、匿名对象的使用:其一、描述:其二、代码为:其三、截图为:3、自定义数组的工具类:其一、描述:其二、代码为:A、Arr......
  • android 模拟器 内存修改, 用winshark 抓包,修改数据包
    1.其实我们自己也可以开发软件,对系统线性内存地址做归纳,2.对所有内存系统地址的值,做遍历。(很快,大概32GB2s~5s),如果能找到进程对应内存堆栈,大概100ms就可以查找完毕。参考摆脱八门神器,继续利用CE在安卓游戏做上帝https://zhuanlan.zhihu.com/p/470805411不需要root在Win......
  • 深入理解Flink窗口
    引言我们已经了解了Flink中事件时间和水位线的概念,那它们有什么具体应用呢?当然是做基于时间的处理计算了。其中最常见的场景,就是窗口聚合计算。在流处理中,我们往往需要面对的是连续不断、无休无止的无界流,不可能等到所有所有数据都到齐了才开始处理。所以聚合计算其实只......
  • 深入理解Java内存模型:对并发编程的影响
    深入理解Java内存模型:对并发编程的影响大家好,我是微赚淘客返利系统3.0的小编,是个冬天不穿秋裤,天冷也要风度的程序猿!在Java并发编程中,内存模型是一个至关重要的概念,它定义了程序中各个变量的访问规则,以及在多线程环境下如何正确地处理这些变量。Java内存模型(JMM)是Java规范中定义的......
  • Shell编程:一篇讲透数组全知识点
    文章目录数组数组参数的使用$*$@$#数组展开示例数组定义方法数组包含的数据类型获取数组长度读取特定索引的值数组遍历数组切片数组替换删除数组追加数组元素插入数组元素向函数传递数组参数数组在Bash脚本中,数组是一种存储多个元素的变量结构,可以使用不同的......
  • IO进程day06(进程间通信、信号、共享内存)
    目录【1】进程间通信IPC1》进程间通信方式2》无名管道1>特点2>函数接口3>注意事项练习:父子进程实现通信,父进程循环从终端输入数据,子进程循环打印数据,当输入quit结束。3》有名管道 1>特点2>函数接口3>注意事项 练习:通过两个进程实现cp功能 4>有名管......
  • 记一次Hyperf定时任务内存异常问题
    背景最近时不时收到K8S告警提示项目POD出现OOM问题,只要触发了项目重新部署或者把POD删掉,内存就恢复了,过了一段时间才缓慢增长(基本上要隔几天,这也是这个问题比较难定位和复现的原因)分析起初以为是某一个SQL没有限制limit或者是程序有死循环把内存跑满了,后面从日志看到......