翻译或纠错本页面

UNIX系统下 ulimit 的设置

大多类似UNIX的操作系统,包括Linux和OS X,都提供了限制每个进程和每个基本用户使用线程,文件和网络连接等系统资源的一些方法。 “ulimits” 防止单个用户使用太多的系统资源。有时,这些限制的默认值太小,这会导致正常MongoDB操作过程中出现一系列问题。

注解

Red Hat Enterprise Linux和 CentOS 6设置最大进程数为1024,超出了 ulimit 设置。新建一个 /etc/security/limits.d/99-mongodb-nproc.conf 文件,重新设置 soft nprochard nproc 的值来增加进程限制。具体例子参见 /etc/security/limits.d/90-nproc.conf

资源利用

mongodmongos 每次使用线程和文件描述符来跟踪连接和管理内部操作。这部分概述了MongoDB中一般的资源利用形式。利用这部分内容,并结合实际的部署和使用来决定合适的 ulimit 设置。

通常情况下,所有的 mongodmongos 实例:

  • 利用一个文件描述符 线程来跟踪每个即将到来的连接。

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

mongod

  • mongod 实例使用的每个数据文件都有一个文件描述符。

  • storage.journal.enabledtrue 时, mongod 进程实例使用的每个日志文件都有一个文件描述符。

  • 在复制集中,每个 mongod 保持一个连接复制集中的所有其他集合成员的连接。

mongod 为一些内部进程,如 TTL collections ,复制和复制集健康检查,开启了后台线程。因为这些内部进程需要一部分额外资源。

mongos

除了客户端连接的线程和文件描述符, mongos 还必须与所有配置服务器和分片保持连接,该进程包含了所有复制集成员。

关于 mongos 进程,考虑如下行为:

  • mongos 实例与每个分片都保持一个连接池,所以 mongos 可以重用连接,这样因为不用建立新连接,从而能快速的满足请求。

  • 通过限制连接数,可以防止 mongos 因在 mongod 实例上创建太多连接而产生级联效应。

    注解

    在 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) 40000
-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 是指每个 user 使用各种资源的限制值。因此,无论你的 mongod 实例是以单个用户多进程执行,还是以多 mongod 进程执行,都可以看到对这些资源的连接。同样,要了解到 processes 值(比如 -u )是指不同进程和子进程线程之和。

你可以按下面形式的命令修改 ulimit 的设置。

ulimit -n <value>

There are both “hard” and the “soft” ulimits that affect MongoDB’s performance. The “hard” ulimit refers to the maximum number of processes that a user can have active at any time. This is the ceiling: no non-root process can increase the “hard” ulimit. In contrast, the “soft” ulimit is the limit that is actually enforced for a session or process, but any process can increase it up to “hard” ulimit maximum.

A low “soft” ulimit can cause can't create new thread, closing connection errors if the number of connections grows too high. For this reason, it is extremely important to set both ulimit values to the recommended values.

ulimit will modify both “hard” and “soft” values unless the -H or -S modifiers are specified when modifying limit values.

对许多版本的Linux来说,您可以通过 -n 选项代替 ulimit -a 输出的任何值来改变值。在OS X上,使用 launchctl limit 命令。参看您的操作系统文档来改变运行系统的系统限制值。

改变 ulimit 设置之后, 重启进程修改值才会有效。通过 /proc 文件可以查看运行进程当前的限制值。

Depending on your system’s configuration, and default settings, any change to system limits made using ulimit may revert following system a system restart. Check your distribution and operating system documentation for more information.

注解

根据您系统配置和默认的设置值,任何使用 ulimit 对系统限制的改变在系统重启后都会恢复到默认值。更多相关信息请参考您的版本和操作系统文档。

您可以复制粘贴该函数到当前shell下,或者作为脚本的一部分。通过下列调用形式调用该函数。

Linux distributions using Upstart

For Linux distributions that use Upstart, you can specify limits within service scripts if you start mongod and/or mongos instances as Upstart services. You can do this by using limit stanzas.

Specify the Recommended ulimit Settings, as in the following example:

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

Each limit stanza sets the “soft” limit to the first value specified and the “hard” limit to the second.

After changing limit stanzas, ensure that the changes take effect by restarting the application services, using the following form:

restart <service name>

Linux distributions using systemd

For Linux distributions that use systemd, you can specify limits within the [Service] sections of service scripts if you start mongod and/or mongos instances as systemd services. You can do this by using resource limit directives.

Specify the Recommended ulimit Settings, as in the following example:

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

Each systemd limit directive sets both the “hard” and “soft” limits to the value specified.

After changing limit stanzas, ensure that the changes take effect by restarting the application services, using the following form:

systemctl restart <service name>

/proc File System

注解

This section applies only to Linux operating systems.

The /proc file-system stores the per-process limits in the file system object located at /proc/<pid>/limits, where <pid> is the process’s PID or process identifier. You can use the following bash function to return the content of the limits object for a process or processes with a given name:

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

}

You can copy and paste this function into a current shell session or load it as part of a script. Call the function with one the following invocations:

return-limits mongod
return-limits mongos
return-limits mongod mongos
[1](1, 2) If you limit virtual or resident memory size on a system running MongoDB the operating system will refuse to honor additional allocation requests.
[2]The -m parameter to ulimit has no effect on Linux systems with kernel versions more recent than 2.4.30. You may omit -m if you wish.