尽管使用 rocksdb 状态后端,Flink 作业仍需要大量内存
Flink job requiring a lot of memory despite using rocksdb state backend
我在 Flink 1.14.3 (Java 11) 上有一份工作 运行ning,它使用 rocksdb 作为状态后端。问题是作业需要的内存量与整体状态大小非常相似。
确实,为了使其稳定(并且能够拍摄快照)这就是我正在使用的:
- 4 个 TM,30 GB RAM 和 7 个 CPU
- 一切都 运行 在 AWS 上的 Kubernetes 之上,使用具有 32 GB RAM 和本地连接的 SSD 磁盘的节点(M5ad 实例物有所值)
我有这些设置:
state.backend: rocksdb
state.backend.incremental: 'true'
state.backend.rocksdb.localdir: /opt/flink/rocksdb <-- SSD volume (see below)
state.backend.rocksdb.memory.managed: 'true'
state.backend.rocksdb.predefined-options: FLASH_SSD_OPTIMIZED
taskmanager.memory.managed.fraction: '0.9'
taskmanager.memory.framework.off-heap.size: 512mb
taskmanager.numberOfTaskSlots: '4' (parallelism: 16)
还有这个:
- name: rocksdb-volume
volume:
emptyDir:
sizeLimit: 100Gi
name: rocksdb-volume
volumeMount:
mountPath: /opt/flink/rocksdb
这为每个任务管理器提供了大量磁盘 space。通过这些设置,作业 运行 很顺利,特别是有一个相对较大的内存余量。问题是内存消耗缓慢增加,而且内存余量较少时快照会失败。我尝试减少任务管理器的数量,但我需要 4 个。与 RAM 数量相同,我尝试提供例如16 GB 而不是 30 GB 但同样的问题。另一个对我们有用的设置是使用 8 个 TM,每个 16 GB RAM,但同样,这导致总体内存量与当前设置相同。即使有那么大的内存,我也能看到内存在不断增长,很可能会导致一个糟糕的结局...
此外,最新的快照占用了大约 120 GB,因此您可以看到我使用的 RAM 量与总状态的大小相似,这违背了使用 disk-based 状态的全部目的后端 (rocksdb) 加上本地 SSD。
是否有一种有效的方法来限制 rocksdb 占用的内存(限制在 运行ning pods 上可用的内存)?到目前为止,我的 found/tried 没有任何效果。理论上,我正在使用的图像有 jemalloc
用于内存分配,这应该避免过去使用 malloc 观察到的内存碎片问题。
更新 1:随附请找到内存演化,其中“taskmanager.memory.managed.fraction”等于 0.25 和 0.1。显然,该作业继续需要长 运行.
中的所有可用内存
更新 2:按照 David 的建议,我尝试降低 taskmanager.memory.managed.fraction
的值以及内存总量。特别是,如果将托管分数设置为 0.2,该作业似乎可以 运行 顺利地使用每个 TM 8 GB。但是,如果设置为 0.9,作业将无法启动(由于内存不足),除非为每个 TM 提供 30 GB。以下屏幕截图显示了托管分数设置为 0.2 且 TM 内存设置为 8 GB 时的内存演变。在 13 点 50 分左右,由于拍摄快照(效果很好),释放了大量内存。总的来说现在的工作看起来很稳定...
RocksDB 旨在使用您授予它访问权限的所有内存——因此,如果它可以在内存中容纳您的所有状态,它就会。鉴于您已将 taskmanager.memory.managed.fraction
从 0.4 增加到 0.9,随着时间的推移,您的整体内存使用量接近其限制也就不足为奇了。
如果你给 RocksDB 相当少的内存,它应该可以应付。你试过了吗?
我在 Flink 1.14.3 (Java 11) 上有一份工作 运行ning,它使用 rocksdb 作为状态后端。问题是作业需要的内存量与整体状态大小非常相似。
确实,为了使其稳定(并且能够拍摄快照)这就是我正在使用的:
- 4 个 TM,30 GB RAM 和 7 个 CPU
- 一切都 运行 在 AWS 上的 Kubernetes 之上,使用具有 32 GB RAM 和本地连接的 SSD 磁盘的节点(M5ad 实例物有所值)
我有这些设置:
state.backend: rocksdb
state.backend.incremental: 'true'
state.backend.rocksdb.localdir: /opt/flink/rocksdb <-- SSD volume (see below)
state.backend.rocksdb.memory.managed: 'true'
state.backend.rocksdb.predefined-options: FLASH_SSD_OPTIMIZED
taskmanager.memory.managed.fraction: '0.9'
taskmanager.memory.framework.off-heap.size: 512mb
taskmanager.numberOfTaskSlots: '4' (parallelism: 16)
还有这个:
- name: rocksdb-volume
volume:
emptyDir:
sizeLimit: 100Gi
name: rocksdb-volume
volumeMount:
mountPath: /opt/flink/rocksdb
这为每个任务管理器提供了大量磁盘 space。通过这些设置,作业 运行 很顺利,特别是有一个相对较大的内存余量。问题是内存消耗缓慢增加,而且内存余量较少时快照会失败。我尝试减少任务管理器的数量,但我需要 4 个。与 RAM 数量相同,我尝试提供例如16 GB 而不是 30 GB 但同样的问题。另一个对我们有用的设置是使用 8 个 TM,每个 16 GB RAM,但同样,这导致总体内存量与当前设置相同。即使有那么大的内存,我也能看到内存在不断增长,很可能会导致一个糟糕的结局...
此外,最新的快照占用了大约 120 GB,因此您可以看到我使用的 RAM 量与总状态的大小相似,这违背了使用 disk-based 状态的全部目的后端 (rocksdb) 加上本地 SSD。
是否有一种有效的方法来限制 rocksdb 占用的内存(限制在 运行ning pods 上可用的内存)?到目前为止,我的 found/tried 没有任何效果。理论上,我正在使用的图像有 jemalloc
用于内存分配,这应该避免过去使用 malloc 观察到的内存碎片问题。
更新 1:随附请找到内存演化,其中“taskmanager.memory.managed.fraction”等于 0.25 和 0.1。显然,该作业继续需要长 运行.
中的所有可用内存更新 2:按照 David 的建议,我尝试降低 taskmanager.memory.managed.fraction
的值以及内存总量。特别是,如果将托管分数设置为 0.2,该作业似乎可以 运行 顺利地使用每个 TM 8 GB。但是,如果设置为 0.9,作业将无法启动(由于内存不足),除非为每个 TM 提供 30 GB。以下屏幕截图显示了托管分数设置为 0.2 且 TM 内存设置为 8 GB 时的内存演变。在 13 点 50 分左右,由于拍摄快照(效果很好),释放了大量内存。总的来说现在的工作看起来很稳定...
RocksDB 旨在使用您授予它访问权限的所有内存——因此,如果它可以在内存中容纳您的所有状态,它就会。鉴于您已将 taskmanager.memory.managed.fraction
从 0.4 增加到 0.9,随着时间的推移,您的整体内存使用量接近其限制也就不足为奇了。
如果你给 RocksDB 相当少的内存,它应该可以应付。你试过了吗?