UNIX ulimit 设置

在本页面

包括 Linux 和 macOS 在内的大多数类似 UNIX 的 os 都提供了基于每个进程和每个用户来限制和控制系统资源(例如线程,文件和网络连接)使用的方法。这些“ ulimit”可防止单个用户使用过多的系统资源。有时,这些限制的默认值较低,在正常的 MongoDB 操作过程中可能会导致许多问题。

Resource Utilization

mongodmongos各自使用线程和文件 Descriptors 来跟踪连接并 Management 内部操作。本节概述了 MongoDB 的常规资源利用模式。将这些数字与有关您的部署及其使用的实际信息结合使用,以确定理想的ulimit设置。

通常,所有mongodmongos实例:

  • 使用文件 Descriptors跟踪每个传入的连接。

  • 跟踪每个内部线程或* pthread *作为系统进程。

mongod

  • mongod实例正在使用的每个数据文件的 1 文件 Descriptors。

  • storage.journal.enabledtruemongod实例使用的每个日记文件的 1 文件 Descriptors。

  • 在副本集中,每个mongod都保持与该集中所有其他成员的连接。

mongod将后台线程用于许多内部进程,包括TTL collections,复制和副本集运行状况检查,这可能需要少量其他资源。

mongos

除了 Client 端连接的线程和文件 Descriptors 外,mongos还必须维护与所有配置服务器和所有分片(包括所有副本集的所有成员)的连接。

对于mongos,请考虑以下行为:

  • mongos实例维护每个分片的连接池,以便mongos可以重用连接并快速执行请求,而无需创建新的连接。

  • 您可以使用net.maxIncomingConnections运行时选项限制传入连接的数量。通过限制传入连接的数量,可以防止级联效应,即mongosmongod实例上创建太多连接。

Note

在 2.6 版中进行了更改:MongoDB 删除了maxIncomingConnections设置的上限。

查看并设置资源限制

ulimit

您可以在系统提示符下使用ulimit命令来检查系统限制,如以下示例所示:

$ ulimit -a
-t: cpu time (seconds)         unlimited
-f: file size (blocks)         unlimited
-d: data seg size (kbytes)     unlimited
-s: stack size (kbytes)        8192
-c: core file size (blocks)    0
-m: resident set size (kbytes) unlimited
-u: processes                  192276
-n: file descriptors           21000
-l: locked-in-memory size (kb) unlimited
-v: address space (kb)         unlimited
-x: file locks                 unlimited
-i: pending signals            192276
-q: bytes in POSIX msg queues  819200
-e: max nice                   30
-r: max rt priority            65
-N 15:                         unlimited

ulimit是指针对每个用户的各种资源限制。因此,如果您的mongod实例以同时运行多个进程或多个mongod进程的用户身份执行,则可能会看到这些资源的争用。另外,请注意processes值(即-u)是指不同进程和子进程线程的组合数量。

您可以通过发出以下格式的命令来更改ulimit设置:

ulimit -n <value>

影响 MongoDB 性能的“硬”和“软” ulimit都有。 “硬” ulimit表示用户可以随时激活的最大进程数。这是上限:没有非根进程可以增加“硬” ulimit。相反,“软” ulimit是为会话或进程实际实施的限制,但是任何进程都可以将其增加到“硬” ulimit最大值。

如果连接数量过高,则“低”的ulimit可能会导致can't create new thread, closing connection错误。因此,将两个ulimit都设置为推荐值非常重要。

除非修改极限值时指定了-H-S修饰符,否则ulimit将同时修改“硬”和“软”值。

对于许多 Linux 发行版,您可以通过将-n选项替换为ulimit -a输出中的任何可能值来更改值。在 macOS 上,使用launchctl limit命令。有关更改正在运行的系统上的系统限制的确切过程,请参阅 os 文档。

更改ulimit设置后,您必须重新启动该过程以利用修改后的设置。您可以使用/proc文件系统查看正在运行的进程的当前限制。

根据系统的配置和默认设置,使用ulimit对系统限制所做的任何更改都可能在系统重新启动后恢复。查看发行和 os 文档以获取更多信息。

SUSE Linux Enterprise Server

默认情况下,SUSE Linux Enterprise Server 和其他可能的 SUSE 发行版附带的虚拟内存地址空间限制为 8 GB。您必须*对此进行调整,以防止随着数据库的增长而导致虚拟内存分配失败。

MongoDB 的 SLES 软件包会在其默认初始化脚本中自动调整这些限制。如果您在没有提供的初始化脚本的情况下手动启动 MongoDB,正在使用自己的自定义初始化脚本或正在使用 TGZ tarball 版本,则必须自己进行这些更改。

Red Hat Linux 企业服务器和 CentOS

红帽企业版 Linux 和 CentOS 6 和 7 强制实施单独的最大进程限制nproc,该限制将覆盖ulimit设置。该值在以下配置文件中定义,具体取决于版本:

VersionValueFile
RHEL/CentOS 74096/etc/security/limits.d/20-nproc.conf
RHEL/CentOS 61024/etc/security/limits.d/90-nproc.conf

要为这些版本配置nproc值,请创建一个名为/etc/security/limits.d/99-mongodb-nproc.conf的文件,并使用新的soft nprochard nproc值来增加处理限制。有关推荐值,请参见推荐的 ulimit 设置

建议的 ulimit 设置

每个部署都可能具有独特的要求和设置。但是,以下阈值和设置对于mongodmongos部署特别重要:

  • -f(文件大小):unlimited

  • -t(CPU 时间):unlimited

  • -v(虚拟内存):unlimited [1]

  • -l(锁定的内存大小):unlimited

  • -n(打开的文件):64000

  • -m(内存大小):unlimited [1] [2]

  • -u(进程/线程):64000

使用 Upstart 的 Linux 发行版

对于使用 Upstart 的 Linux 发行版,如果您将mongod和/或mongos实例作为 Upstart 服务启动,则可以在服务脚本中指定限制。您可以使用limit stanzas进行此操作。

指定推荐的 ulimit 设置,如以下示例所示:

limit fsize unlimited unlimited    # (file size)
limit cpu unlimited unlimited      # (cpu time)
limit as unlimited unlimited       # (virtual memory size)
limit memlock unlimited unlimited  # (locked-in-memory size)
limit nofile 64000 64000           # (open files)
limit nproc 64000 64000            # (processes/threads)

每个limit节将“软”限制设置为指定的第一个值,将“硬”限制设置为第二个值。

更改limit节后,请使用以下格式重新启动应用程序服务,以确保更改生效:

restart <service name>

使用 systemd 的 Linux 发行版

对于使用systemd的 Linux 发行版,如果您将mongod和/或mongos实例作为systemd服务启动,则可以在服务脚本的[Service]部分中指定限制。您可以使用资源限制指令完成此操作。

指定推荐的 ulimit 设置,如以下示例所示:

[Service]
# Other directives omitted
# (file size)
LimitFSIZE=infinity
# (cpu time)
LimitCPU=infinity
# (virtual memory size)
LimitAS=infinity
# (locked-in-memory size)
LimitMEMLOCK=infinity
# (open files)
LimitNOFILE=64000
# (processes/threads)
LimitNPROC=64000

每个systemd限制指令将“硬”和“软”限制都设置为指定的值。

更改limit节后,请使用以下格式重新启动应用程序服务,以确保更改生效:

systemctl restart <service name>

Note

如果您通过yumapt之类的程序包 Management 器安装了 MongoDB,则在安装过程中安装的服务文件已包含这些 ulimit 值。

/proc 文件系统

Note

本部分仅适用于 Linuxos。

/proc文件系统将每个进程的限制存储在位于/proc/<pid>/limits的文件系统对象中,其中<pid>是进程的PID或进程标识符。您可以使用以下bash函数为给定名称的一个或多个进程返回limits对象的内容:

return-limits(){

     for process in $@; do
          process_pids=`ps -C $process -o pid --no-headers | cut -d " " -f 2`

          if [ -z $@ ]; then
             echo "[no $process running]"
          else
             for pid in $process_pids; do
                   echo "[$process #$pid -- limits]"
                   cat /proc/$pid/limits
             done
          fi

     done

}

您可以将此函数复制并粘贴到当前的 Shell 会话中,也可以将其作为脚本的一部分加载。通过以下调用之一调用该函数:

return-limits mongod
return-limits mongos
return-limits mongod mongos
[1]*(12)*如果您在运行 MongoDB 的系统上限制虚拟或常驻内存大小,则 os 将拒绝接受其他分配请求。
[2]ulimit-m参数对内核版本高于 2.4.30 的 Linux 系统无效。如果愿意,您可以省略-m