尽管使用 rocksdb 状态后端,Flink 作业仍需要大量内存

Flink job requiring a lot of memory despite using rocksdb state backend

我在 Flink 1.14.3 (Java 11) 上有一份工作 运行ning,它使用 rocksdb 作为状态后端。问题是作业需要的内存量与整体状态大小非常相似。

确实,为了使其稳定(并且能够拍摄快照)这就是我正在使用的:

我有这些设置:

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 相当少的内存,它应该可以应付。你试过了吗?