1

从具有 10 个并行线程的 PG 10 表中读取时遇到以下错误:-

错误:无法将共享内存段“/PostgreSQL.1110214013”的大小调整为 3158016 字节:设备上没有剩余空间

似乎是 K8s 将 /dev/shm/ 的最大大小限制为 64MB 的结果。将此值设置得更高会导致 64MB。

Spark 任务正在执行并行读取,并根据标识列的哈希值进行分区。想知道不平衡的分区是否会导致特定任务超过导致写入磁盘的进程的 postgres work_mem的值。

我看到我的每个线程都有一个相应的错误日志,所以这个共享内存段调整大小发生了多次(可能请求的调整大小超过了锁定的 64MB)

尝试将 work_mem从 4MB 增加到 32MB、64MB 和最后 256MB,但在每个阶段都看到了错误。以下是我认为可以调整的全套 PG 设置,以避免出现问题的磁盘使用:-

  • 有效缓存大小:“750MB”
  • 共享缓冲区:“2GB”
  • min_wal_size: "80MB"
  • max_wal_size:“5GB”
  • work_mem: "4MB,32MB,64MB,128MB,256MB"(都试过了)
  • random_page_cost:4(想知道这个设置是否有用?)
  • 最大连接数:100

有一个潜在的解决方法,涉及将目录挂载到 /dev/shm/ 但宁愿避免这种解决方案,因为我将无法限制目录可能增长到的大小,理想情况下会找到一个适用于 64MB 的解决方案。

谢谢。

4

1 回答 1

0

似乎(根据这个解释)如果你想在/dev/shm限制为 64MB 的同时避免这个问题,你需要设置shared_buffers为小于 64MB。但是,如果 Kubernetes 节点有更多的物理可用内存,那么挂载一个 emptyDir 卷/dev/shm可能是最好的选择。

确实,从 Kubernetes 1.21 开始,您无法限制 emptyDir 卷的大小(除非您有权配置功能门:新SizeMemoryBackedVolumes功能门仍处于 alpha 状态),但这对于 Postgres 用例可能无关紧要.

如果 Postgres 是 pod 中运行的唯一应用程序,并且您已按照 Postgres 文档的建议shared_buffers配置了大约 25% 的可用内存,那么在驱逐之前向 emptyDir 卷提供最多 50% 的节点内存的当前行为应该是美好的。您需要在 Postgres 中触发一些错误,以便它消耗比设置更多的内存。shared_buffers

因此,最好的解决方案可能是设置shared_buffers为可用节点内存的约 25%,然后将 emptyDir 卷挂载到/dev/shm.

于 2021-04-18T00:10:19.907 回答