目录
为什么需要限制作业的最大内存?
不少LSF用户都可能碰到这样的情况:提交到LSF的作业或程序,有时会出现内存泄漏,或者有意想不到的内存分配情况,使得其它进程因无法分配到足够的内存而出现异常。尽管有的客户也采用了bsub -R “rusage[mem=$number]”来为作业预留内存,以保证计算节点有足够的内存来启动和运行作业,但是用户往往对作业程序使用的内存预估不足,结果作业实际所耗内存远远大于预留内存,导致计算节点运行缓慢,甚至对系统造成影响,引发宕机。
站在一个普通的LSF用户角度,如果能通过LSF控制作业所能使用的内存大小,那么就算作业进程有内存泄漏也不会对系统造成影响(可以设置内存使用上限,当到达这个上限值后LSF自动将作业杀掉)。
站在一个LSF系统管理员的角度,如果能通过LSF限制作业所能使用的内存量,不管用户对自己的作业使用内存评估是否准确,即使作业使用内存大大超过了预留内存,都能将它们对系统的影响降到最低,从而保证整个系统的稳定性。
那么LSF内部是如何实现对作业的内存限制呢?
在不使用Linux cgroup的情况下(后文介绍Linux cgroup),LSF有两种强制内存限制的方法:
-
由操作系统强制执行每个进程的内存限制。在这种情况下,LSF将配置的内存限制传递给操作系统,由操作系统通过setrlimit()系统调用来进行内存限制。
-
由LSF强制执行每个作业的内存限制。LSF获取作业所有进程消耗的内存之和,以确定作业是否已达到所指定的内存限制。当作业所有进程的总内存超过内存限制时,LSF会依次发送以下信号来终止作业进程:SIGINT、SIGTERM和SIGKILL。
LSF内存限制如何配置?
LSF有关内存限制的设置,有两个参数:
-
LSB_JOB_MEMLIMIT,该参数用来设置内存限制是由操作系统强制执行还是由LSF强制执行。当LSB_JOB_MEMLIMIT设为Y时,由LSF强制执行(作业级);当LSB_JOB_MEMLIMIT设为N或未定义时,由操作系统强制执行(进程级)。
-
LSB_MEMLIMIT_ENFORCE,使能这个参数可以同时启用LSF强制执行(作业级)和操作系统强制执行(进程级)。
这两个参数的关系说明如下:
参数名 |
参数值 |
LSF强制执行(作业级) |
操作系统强制执行(进程级) |
LSB_JOB_MEMLIMIT |
Y|y |
Enabled |
Disabled |
N|n 或未定义 |
Disabled |
Enabled |
|
LSB_MEMLIMIT_ENFORCE |
Y|y |
Enabled |
Enabled |
基于Linux cgroup的内存限制
LSF还支持通过Linux cgroup来进行作业的内存限制。如果想通过Linux cgroup进行内存强制,需要在lsf.conf文件中配置:
-
LSB_RESOURCE_ENFORCE="memory"