据我所知,
mem_free
可以指定在具有内存空闲=的主机中提交作业mem_free
,而h_vmem
作业最多可以使用的内存的硬限制是多少?如果作业达到了这个限制h_vmem
,作业会崩溃吗?我认为我们可以将h_vmem
主机的设置为接近总物理内存,这样作业就不会开始使用交换并降低服务器速度。
那是什么h_rss
?它似乎与h_vmem.
或者我误解了h_vmem
?h_vmem
用于保留可能需要的额外内存,而不是所需的最小内存(mem_free
)?但如果超出内存,则不会崩溃,因此作业可以超出h_vmem
?
如果我的第二种解释h_vmem
是正确的,那么我猜,对于在主机中提交的作业,该作业必须满足mem_free
和h_vmem
(假设h_vmem
不是无穷大)。
如果我对的第一个解释h_vmem
是正确的,那么我猜,对于在主机中提交的作业,该作业可以mem_free
单独满足而不需要满足h_vmem
,因为它只保留可用空间,如果没有可用空间,这没关系?
答案1
资源是否可消耗以及系统上可保留多少资源都是可配置的。您可以使用现有值之一,也可以创建新值,由您决定。
虽然设置它无论如何都没有什么坏处,但mem_free
默认情况下是不可消耗的。这意味着虽然当您的作业启动时系统上必须有那么多的内存可用,但如果 10 个作业每个都需要 10GB 的可用内存,则可以同时在具有 11GB 可用内存的服务器上启动。如果它们实际上都使用了 10GB,那么您就会遇到麻烦。
其他两者之间的区别在于执行。rss(物理内存使用)没有被执行。vmem(虚拟内存使用)被执行。不幸的是,Linux 没有提供很好的方法来执行物理内存使用(cgroups 还可以,但 rss ulimit 在现代内核中实际上什么也不做)。
另一方面,认识到这一点非常重要没有正确的方法将 vmem 视为可消耗资源。如果您使用调试选项(在 clang 或 gcc5+ 中可用)用 C 编译“hello world” -fsanitize=address
,它将使用 20TB 的虚拟内存,但物理内存将少于 5MB。垃圾收集运行时(如 Java 和 Go)还将分配大量永远不会反映为物理内存的 vmem,以减少内存碎片。我的 8GB 笔记本电脑上的每个 chrome 标签都使用 2TB 的虚拟内存作为其安全沙盒的一部分。这些都是程序完全合理的事情,设置下限会阻止完全正常运行的程序运行。同样明显的是,在系统上设置 20TB 的 vmem 的可消耗限制是没有意义的。
h_
如果您出于某种原因必须使用 h_vmem,和变体之间的区别在于s_
使用哪个信号来终止超出限制的进程 -h_
使用 SIGKILL 终止进程(例如kill -9
),而s_
使用进程可以处理的信号(允许行为良好的作业干净地关闭,或允许行为不良的作业忽略信号)。最好的建议是先哭,因为 vmem 限制本质上是错误的,然后将 h_vmem 设置为略高于 s_vmem,这样作业就有机会终止并显示有用的错误消息。
我的建议是让集群管理员将 h_rss 配置为可消耗的,在作业模板中设置 h_rss 和 mem_free,完全避免使用 h_vmem,并希望人们不要通过内存预留不足来滥用系统。如果需要强制机制,则很复杂,但可以设置作业管理器将作业放入内存 cgroup 中,并设置 memory.limit_in_bytes 或 memory.soft_limit_in_bytes。后者允许 cgroup 超出其预留,只要系统内存不耗尽。这提高了内核代表这些进程缓存文件的能力,从而提高了所有人的性能,但存在风险,即当系统内存耗尽时,在某些情况下 OOM 终止程序没有时间从超限 cgroup 中寻找要终止的进程,而尝试的分配将失败。
答案2
/proc/<pid>/limits
好的,我通过检查执行服务器中正在运行的作业进程找到了答案。
当我使用 提交作业时
h_rss=10G
,在限制中 的值Max Resident Set
设置为 10737418240 字节(即 10G)。(操作系统的默认值为无限制)因此,该过程不能占用超过此值的内存。并且 也是h_rss
不可消耗的。而当我提交带有 的作业时
h_vmem=50G
,在限制范围内 的值Max Resident Set
等于无限。因此,它可以继续超越50克。然而,它是可消耗的,因此,h_vmem
主机的50克。可以通过运行以下命令来找到答案:
qhost -h <hostname> -F h_vmem
,其中 h_vmem 显示当前 h_vmem 值,qconf -se <hostname>
,其中 complex_values 中的 h_vmem 显示分配的 h_vmem 值。