UNIXulimit
设置,用于自管理部署
大多数类似于UNIX的操作系统,包括Linux和macOS,都提供了限制和控制系统资源(如线程、文件和网络连接)使用的方法,这些资源的使用是基于每个进程和每个用户的。这些“ulimits”防止单个用户使用过多的系统资源。有时,这些限制的默认值可能较低,这可能会在MongoDB的正常操作过程中引起许多问题。
资源利用率
mongod
和 mongos
每个都使用线程和文件描述符来跟踪连接和管理内部操作。本节概述了MongoDB的通用资源利用率模式。结合您的部署的实际信息和用途,使用这些图表来确定理想的 ulimit
设置。
使用两个文件描述符 和 一个线程跟踪每个传入的连接。
将每个内部线程或 pthread 作为系统进程跟踪。
mongod
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>
存在影响 MongoDB 性能的“硬”和“软”两种 ulimit
。 “硬” ulimit
指的是用户在任何时候可以拥有的最大进程数。这是上限:没有非 root 进程可以增加“硬” ulimit
。相比之下,“软” ulimit
是实际应用于会话或进程的限制,但任何进程都可以将其增加到“硬” ulimit
的最大值。
如果连接数过高,较低的“软” ulimit
可能会导致“无法创建新线程,关闭连接”错误。因此,将 两个 ulimit
值设置为推荐值非常重要。
除非在修改限制值时指定了 -H
或 -S
修饰符,否则 ulimit
会修改“硬”和“软”值。
对于许多 Linux 发行版,您可以通过将 -n
选项替换为 ulimit -a
输出的任何可能值来更改值。
更改 ulimit
设置后,您必须重新启动进程才能利用修改后的设置。在 Linux 上,您可以使用 /proc
文件系统来查看正在运行的进程的当前限制。
根据您的系统配置和默认设置,使用 ulimit
对系统限制所做的任何更改在系统重启后可能会还原。请查阅您的发行版和操作系统文档以获取更多信息。
通常应使用 systemctl
启动 mongod
,它使用 ulimit
设置
systemctl start mongod.service
如果您不使用 systemctl
启动 mongod
,systemd
会覆盖一些 ulimit
设置。例如,如果您按照以下命令启动 mongod
,则将使用 systemd
的用户分片设置(例如 user-1000.slice
)
mongod --config ~/mongod.conf
注意
systemd
用户分片限制了用户进程的资源。
macOS
对于使用 brew 安装方法安装 MongoDB Community 的 macOS 系统,通过 brew services
启动 MongoDB 时,会自动设置推荐的打开文件值。
对于运行 MongoDB Enterprise 或使用 TGZ 安装方法的 macOS 系统,使用 ulimit
命令设置推荐值。有关更改运行系统上系统限制的精确步骤,请参阅您的操作系统文档。
Red Hat Linux 企业服务器和 CentOS
Red Hat Enterprise Linux 和 CentOS 6 和 7 强制执行单独的最大进程限制 nproc
,它覆盖 ulimit
设置。此值定义在以下配置文件中,具体取决于版本
版本 | 值 | 文件 |
---|---|---|
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
(文件大小):无限
-t
(CPU 时间):无限
-v
(虚拟内存):无限
[1]-l
(锁定内存大小):无限
-n
(打开文件):64000
-u
(进程/线程):64000
始终记得在更改 ulimit
设置后重启你的 mongod
和 mongos
实例,以确保更改生效。
考虑因素
使用 Upstart 的 Linux 发行版
对于使用 Upstart 的 Linux 发行版,如果您以 Upstart 服务启动 mongod
和/或 mongos
实例,您可以在服务脚本中指定限制。您可以通过使用 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>
使用 systemd
的 Linux 发行版
如果您将 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 }
您可以将此函数复制并粘贴到当前会话中,或将它作为脚本的一部分加载。使用以下调用之一来调用函数
return-limits mongod return-limits mongos return-limits mongod mongos
[1] | (1, 2) 如果您在运行 MongoDB 的系统上限制了虚拟或常驻内存大小,则操作系统将拒绝满足额外的分配请求。 |
[2] | ulimit 的 -m 参数对内核版本晚于 2.4.30 的 Linux 系统没有影响。如果您愿意,可以省略 -m 。 |