用于自托管部署的 UNIX 设置ulimit
大多数 UNIX 这样的操作系统(包括 Linux 和 macOS)都提供了基于每个进程和每个用户限制和控制使用系统资源(例如线程、文件和网络连接)的方法。这些“ulimit”可防止单个用户使用过多的系统资源。有时,这些限制的默认值较低,可能会在 MongoDB 正常操作过程中导致许多问题。
资源利用
mongod
和 mongos
分别使用线程和文件描述符来跟踪连接和管理内部操作。本节概述了 MongoDB 的一般资源利用模式。将这些数字与有关您的部署及其用途的实际信息相结合,以确定理想的 ulimit
设置。
一般来说,所有的 mongod
和 mongos
实例都会:
使用两个文件描述符和一个线程跟踪每个传入连接。
像系统进程那样跟踪每个内部线程或 pthread。
mongod
mongos
除了用于客户端连接的线程和文件描述符外,mongos
还必须与所有配置服务器和所有分片(包括所有副本集的所有节点)保持连接。
对于 mongos
,请考虑以下行为:
mongos
实例维护一个与每个分片的连接池,这样mongos
就可以重复使用连接并快速完成请求,而无需创建新的连接。您可以使用
net.maxIncomingConnections
运行时选项来限制传入连接数。通过限制传入连接数,可以防止mongos
在mongod
实例上创建过多连接的级联效应。
审查和设置资源限制
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 64000 -n: file descriptors 64000 -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
)是指不同进程和子进程线程的总数量。
在 Linux 上,您可以通过发出以下形式的命令来更改 ulimit
设置:
ulimit -n <value>
ulimit
有“硬”限制和“软”限制两种,它们都会影响 MongoDB 的性能。“硬”ulimit
是指用户在任何时间都可以拥有的最大活动进程数。这是上限:任何非 root 进程都无法提高“硬”ulimit
。相反,“软”ulimit
是实际强制执行的会话或进程限制,但任何进程都可以将其提高,直到达到“硬”ulimit
允许的最大值。
如果连接数增长过高,较低的“软”ulimit
可能会导致 can't create new thread,
closing connection
错误。因此,请务必将这两种 ulimit
值均设置为推荐值。
ulimit
将同时修改“硬”和“软”值,除非在修改限制值时指定了 -H
或 -S
修饰符。
对于许多 Linux 发行版,您可以通过将 -n
选项替换为 ulimit
-a
输出中任何可能的值来更改值。
更改 ulimit
设置后,您必须重新启动该进程才能使用修改后的设置。在 Linux 上,您可以使用 /proc
文件系统来查看正在运行的进程的当前限制。
使用 ulimit
对系统限制所做的任何更改都可能会在系统重新启动后恢复,取决于您的系统配置和默认设置。检查您的发行版和操作系统文档,了解更多信息。
您通常应该使用 systemctl
启动 mongod
,其中使用了 ulimit
设置:
systemctl start mongod.service
如果不使用 systemctl
启动 mongod
,systemd
将会覆盖一些 ulimit
设置。例如,如果按以下命令中的方式启动 mongod
,则会使用用户切片(例如 user-1000.slice
)systemd
设置:
mongod --config ~/mongod.conf
注意
systemd
用户切片限制了用户进程的资源。
macOS
对于使用 brew 安装方法安装了 MongoDB 社区版的 macOS 系统,当通过 brew services
启动 MongoDB 时,会自动设置推荐的打开文件数。
对于运行 MongoDb 企业或使用 TGZ 安装方法的 macOS 系统,请使用 ulimit
命令设置 推荐值。请参阅操作系统文档,了解在正在运行的系统上更改系统限制的详细过程。
Red Hat Linux Enterprise Server 和 CentOS
Red Hat Enterprise Linux 以及 CentOS 6 和 7 强制实施单独的最大进程限制 nproc
,该限制会覆盖 ulimit
设置。该值在以下配置文件中定义,具体取决于版本:
版本 | 值 | file |
---|---|---|
RHEL / CentOS 7 | 4096 | /etc/security/limits.d/20-nproc.conf |
RHEL / CentOS 6 | 1024 | /etc/security/limits.d/90-nproc.conf |
要为这些版本配置 nproc
值,请创建一个名为 /etc/security/limits.d/99-mongodb-nproc.conf
的文件,并使用新的 soft nproc
和 hard nproc
值来提高进程限制。有关推荐的值,请参阅建议的 ulimit
设置。
对于 RHEL/CentOS 8,不再需要单独设置 nproc
值。在 RHEL/CentOS 8 上,ulimit
命令足以配置所需的最大进程数。
推荐ulimit
设置
每个部署都可能有独特的要求和设置,但以下阈值和设置对 mongod
和 mongos
部署尤为重要:
-f
(文件大小):unlimited
-t
(CPU 时间):unlimited
-v
(虚拟内存):unlimited
[1]-l
(锁定内存大小):unlimited
-n
(打开文件):64000
-u
(进程/线程):64000
请谨记,更改 ulimit
设置后,务必要重启 mongod
和 mongos
实例,以确保更改生效。
Considerations
使用 Upstart 的 Linux 发行版
对于使用 Upstart 的 Linux 发行版,如果您将 mongod
和/或 mongos
实例作为 Upstart 服务启动,则可以在服务脚本内指定限制。可以使用 limit
节段执行此操作。
指定推荐的 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>
使用 的 Linux 发行版 systemd
如果您将 mongod
和/或 mongos
实例作为 systemd
服务启动,则可以在其服务文件的 [Service]
部分中指定限制。服务文件位于类似 /etc/systemd/system/<process-name>.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>
注意
如果是通过软件包管理器(例如 yum
或 apt
)安装的 MongoDB,则自动安装的服务文件中已包含这些 ulimit 值。
/proc
文件系统
注意
本节仅适用于 Linux 操作系统。
/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] | (1、2) 如果在运行 MongoDB 的系统上限制虚拟内存或常驻内存大小,操作系统将会拒绝满足额外的分配请求。 |
[2] | ulimit 的 -m 参数对内核版本高于 2.4.30 的 Linux 系统不起作用。如果您愿意,可以省略 -m 。 |