Docs 菜单

Docs 主页开发应用程序MongoDB Manual

UNIX ulimit设置

在此页面上

  • 资源利用
  • 审查和设置资源限制

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

mongodmongos 分别使用线程和文件描述符来跟踪连接和管理内部操作。本节概述了 MongoDB 的一般资源利用模式。将这些数字与有关您的部署及其用途的实际信息相结合,以确定理想的 ulimit 设置。

一般来说,所有的 mongodmongos 实例都会:

  • 使用两个文件描述符一个线程跟踪每个传入连接。

  • 像系统进程那样跟踪每个内部线程或 pthread

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

  • mongod 实例使用的每个日志文件都有 1 个文件描述符。

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

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

除了用于客户端连接的线程和文件描述符外,mongos 还必须与所有配置服务器和所有分片(包括所有副本集的所有节点)保持连接。

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

  • mongos 实例维护一个与每个分片的连接池,这样 mongos 就可以重复使用连接并快速完成请求,而无需创建新的连接。

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

您可以在系统提示符使用 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 启动 mongodsystemd 将会覆盖一些 ulimit 设置。例如,如果按以下命令中的方式启动 mongod,则会使用用户切片(例如 user-1000.slicesystemd 设置:

mongod --config ~/mongod.conf

注意

systemd 用户切片限制了用户进程的资源。

对于使用 brew 安装方法安装了 MongoDB 社区版的 macOS 系统,当通过 brew services 启动 MongoDB 时,会自动设置推荐的打开文件数。

对于运行 MongoDb 企业或使用 TGZ 安装方法的 macOS 系统,请使用 ulimit 命令设置 推荐值。请参阅操作系统文档,了解在正在运行的系统上更改系统限制的详细过程。

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值,请使用新的soft nprochard nproc值创建一个名为/etc/security/limits.d/99-mongodb-nproc.conf的文件,以增加进程限制。有关推荐值,请参阅推荐的ulimit设置。

对于 RHEL/CentOS 8,不再需要单独设置 nproc 值。在 RHEL/CentOS 8 上,ulimit 命令足以配置所需的最大进程数。

每个部署都可能有独特的要求和设置,但以下阈值和设置对 mongodmongos 部署尤为重要:

  • -f (文件大小): unlimited

  • -t (CPU 时间): unlimited

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

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

  • -n (打开文件): 64000

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

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

请谨记,更改 ulimit 设置后,务必要重启 mongodmongos 实例,以确保更改生效。

  • mongodmongos实例的传入连接需要两个文件描述符。

  • 对于 macOS 平台,建议的进程限制为 2500,这是该平台可以配置的最大值。

对于使用 Upstart 的 Linux 发行版,如果将 和/或mongodmongos 实例作为 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>

如果您将 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>

注意

如果是通过软件包管理器(例如 yumapt)安装的 MongoDB,则自动安装的服务文件中已包含这些 ulimit 值。

注意

本节仅适用于 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](12) 如果在运行 MongoDB 的系统上限制虚拟内存或常驻内存大小,操作系统将会拒绝满足额外的分配请求。
[2] ulimit-m 参数对内核版本高于 2.4.30 的 Linux 系统不起作用。如果您愿意,可以省略 -m
← 使用健康管理器管理分片集群健康状况