常见问题:MongoDB 诊断

在本页面

本文档提供了常见诊断问题的解答。

如果找不到所需的答案,请检查常见问题解答的完整列表或将问题发布到MongoDB Community

在哪里可以找到有关意外停止的 mongod 进程的信息?

如果mongod在 UNIX 或基于 UNIX 的平台上意外关闭,并且mongod未能记录关闭消息或错误消息,请检查系统日志中与 MongoDB 有关的消息。例如,对于位于/var/log/messages的日志,请使用以下命令:

sudo grep mongod /var/log/messages
sudo grep score /var/log/messages

TCP 保持活动时间是否会影响 MongoDB 部署?

如果在 Client 端和服务器之间,或在分片群集或副本集的成员之间的通信中遇到网络超时或套接字错误,请检查受影响系统的* TCP keepalive 值*。

默认情况下,许多 os 将此值设置为7200秒(两个小时)。对于 MongoDB,您通常会以120秒(两分钟)的数量级使用较短的 keepalive 值来获得更好的结果。

如果您的 MongoDB 部署遇到与 keepalive 相关的问题,则必须更改所有受影响的系统上的 keepalive 值。这包括运行mongodmongos进程的所有计算机以及托管连接到 MongoDB 的 Client 端进程的所有计算机。

调整 TCP Keepalive 值:

Linux
Windows
macOS
  • To view the keepalive setting on Linux, use one of the following commands:
sysctl net.ipv4.tcp_keepalive_time

Or:

cat /proc/sys/net/ipv4/tcp_keepalive_time

The value is measured in seconds.

Note

Although the setting name includes ipv4 , the tcp_keepalive_time value applies to both IPv4 and IPv6.

  • To change the tcp_keepalive_time value, you can use one of the following commands, supplying a <value> in seconds:
sudo sysctl -w net.ipv4.tcp_keepalive_time=<value>

Or:

echo <value> | sudo tee /proc/sys/net/ipv4/tcp_keepalive_time

These operations do not persist across system reboots. To persist the setting, add the following line to /etc/sysctl.conf , supplying a <value> in seconds, and reboot the machine:

net.ipv4.tcp_keepalive_time = <value>

Keepalive values greater than 300 seconds, (5 minutes) will be overridden on mongod and mongos sockets and set to 300 seconds.

  • To view the keepalive setting on Windows, issue the following command:
reg query HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters /v KeepAliveTime

The registry value is not present by default. The system default, used if the value is absent, is 7200000 milliseconds or 0x6ddd00 in hexadecimal.

  • To change the KeepAliveTime value, use the following command in an Administrator Command Prompt, where <value> is expressed in hexadecimal (e.g. 120000 is 0x1d4c0 ):
reg add HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\ /t REG_DWORD /v KeepAliveTime /d <value>

Windows users should consider the Windows Server Technet Article on KeepAliveTime for more information on setting keepalive for MongoDB deployments on Windows systems. Keepalive values greater than or equal to 600000 milliseconds (10 minutes) will be ignored by mongod and mongos.

  • To view the keepalive setting on macOS, issue the following command:
sysctl net.inet.tcp.keepidle

The value is measured in milliseconds.

  • To change the net.inet.tcp.keepidle value, you can use the following command, supplying a <value> in milliseconds:
sudo sysctl net.inet.tcp.keepidle=<value>

This operation does not persist across system reboots, and must be set each time your system reboots. See your operating system's documentation for instructions on setting this value persistently. Keepalive values greater than or equal to 600000 milliseconds (10 minutes) will be ignored by mongod and mongos.

Note

In macOS 10.15 Catalina, Apple no longer allows for configuration of the net.inet.tcp.keepidle option.

您需要重新启动mongodmongos进程,才能使新的系统范围的 Keepalive 设置生效。

为什么 MongoDB 记录这么多“连接已接受”事件?

如果您在 MongoDB 日志中看到大量的连接和重新连接消息,则说明 Client 端经常连接和断开与 MongoDB 服务器的连接。对于不使用请求池的应用程序(例如 CGI),这是正常的行为。考虑使用 FastCGI,Apache 模块或其他某种持久性应用程序服务器来减少连接开销。

如果这些连接不影响您的性能,则可以使用运行时quiet选项或命令行选项--quiet从日志中禁止显示这些消息。

哪些工具可用于监视 MongoDB?

MongoDB 云 Management 器Ops Manager,MongoDB Enterprise Advanced 中提供的本地解决方案包括监视功能,该功能从正在运行的 MongoDB 部署中收集数据,并基于该数据提供可视化和警报。

有关更多信息,另请参见MongoDB Cloud Manager 文档Ops Manager 文档

监控 MongoDB文档中提供了第三方工具的完整列表。

MMAPv1 存储引擎的内存诊断

我需要配置交换空间吗?

始终将系统配置为具有交换空间。如果不进行交换,则在某些情况下,如果存在极端的内存限制,内存泄漏或使用同一内存的多个程序,您的系统可能就不可靠。将交换空间想像成蒸汽释放阀,它可以使系统释放额外的压力而不会影响系统的整体功能。

但是,运行 MongoDB 的系统不需要进行常规操作的交换。数据库文件为memory-mapped,应构成 MongoDB 内存使用的大部分。因此,在正常操作中mongod不太可能会使用任何交换空间。os 将在不需要交换的情况下从内存 Map 文件释放内存,而 MongoDB 可以在不需要交换系统的情况下将数据写入数据文件。

什么是“工作集”?

“工作集”是 Client 最常访问的数据部分。

我的工作集大小是否必须适合 RAM?

您的工作集应保留在内存中以获得良好的性能。否则会出现许多随机磁盘 IO,除非您使用的是 SSD,否则这可能会很慢。

在 Management 工作集的大小方面需要特别注意的一个领域是索引访问模式。如果您要在随机位置插入索引(就像散列随机生成的 ID 一样),您将不断更新整个索引。相反,如果您能够以大约升序(例如,天与随机 ID 串联)创建 ID,则所有更新将在 b 树的右侧进行,索引页的工作集大小将很大较小。

如果数据库和虚拟大小都比 RAM 大得多,那就很好。

如何计算应用程序需要多少 RAM?

您需要的 RAM 数量取决于几个因素,包括但不限于:

从磁盘将数据加载到内存时,MongoDB 遵从 os。它只是memory maps所有数据文件,并依靠 os 来缓存数据。当内存不足时,os 通常会从 RAM 中清除最近使用的数据。例如,如果 Client 端访问索引的频率比文档访问频率高,那么索引很可能会保留在 RAM 中,但这取决于您的特定用法。

要计算所需的 RAM 数量,必须计算工作集大小或 Client 端最常使用的数据部分。这取决于您的访问模式,拥有的索引以及文档的大小。由于 MongoDB 每个连接模型都使用线程,因此每个数据库连接也将需要多达 1 MB 的 RAM,无论是活动的还是空闲的。

如果很少出现页面错误,则您的工作集适合 RAM。如果故障率上升到更高水平,则可能会降低性能。与旋转磁盘相比,对于 SSD 驱动器而言,这并不重要。

如何在 UNIX top 命令中读取内存统计信息

由于mongod使用memory-mapped files,因此需要以特殊方式解释top中的内存统计信息。在大型数据库上,VSIZE(虚拟字节)往往是整个数据库的大小。如果mongod没有正在运行的其他进程,则RSIZE(驻留字节)是计算机的总内存,因为这会计算文件系统缓存的内容。

对于 Linux 系统,请使用vmstat命令来帮助确定系统如何使用内存。在 macOS 系统上,使用vm_stat

WiredTiger 存储引擎的内存诊断

我的工作集大小是否必须适合 RAM?

No.

如果缓存没有足够的空间来加载其他数据,则 WiredTiger 会将页面从缓存中逐出以释放空间。

Note

storage.wiredTiger.engineConfig.cacheSizeGB限制了 WiredTiger 内部缓存的大小。os 将可用的可用内存用于文件系统缓存,从而允许压缩的 MongoDB 数据文件保留在内存中。此外,os 将使用任何可用的 RAM 来缓冲文件系统块和文件系统缓存。

为了容纳更多的 RAM 使用者,您可能必须减小 WiredTiger 内部缓存的大小。

默认的 WiredTiger 内部缓存大小值假定每台计算机只有一个mongod实例。如果一台机器包含多个 MongoDB 实例,则应减小设置以容纳其他mongod实例。

如果您在不能访问系统中所有可用 RAM 的容器(例如lxccgroups,Docker 等)中运行mongod,则必须将storage.wiredTiger.engineConfig.cacheSizeGB的值设置为小于该容器中可用 RAM 的值。容器。确切的数量取决于容器中运行的其他进程。参见memLimitMB

要查看有关缓存和逐出的统计信息,请使用serverStatus命令。 wiredTiger.cache字段保存有关缓存和逐出的信息。

...
"wiredTiger" : {
   ...
   "cache" : {
      "tracked dirty bytes in the cache" : <num>,
      "bytes currently in the cache" : <num>,
      "maximum bytes configured" : <num>,
      "bytes read into cache" :<num>,
      "bytes written from cache" : <num>,
      "pages evicted by application threads" : <num>,
      "checkpoint blocked page eviction" : <num>,
      "unmodified pages evicted" : <num>,
      "page split during eviction deepened the tree" : <num>,
      "modified pages evicted" : <num>,
      "pages selected for eviction unable to be evicted" : <num>,
      "pages evicted because they exceeded the in-memory maximum" : <num>,,
      "pages evicted because they had chains of deleted items" : <num>,
      "failed eviction of pages that exceeded the in-memory maximum" : <num>,
      "hazard pointer blocked page eviction" : <num>,
      "internal pages evicted" : <num>,
      "maximum page size at eviction" : <num>,
      "eviction server candidate queue empty when topping up" : <num>,
      "eviction server candidate queue not empty when topping up" : <num>,
      "eviction server evicting pages" : <num>,
      "eviction server populating queue, but not evicting pages" : <num>,
      "eviction server unable to reach eviction goal" : <num>,
      "pages split during eviction" : <num>,
      "pages walked for eviction" : <num>,
      "eviction worker thread evicting pages" : <num>,
      "in-memory page splits" : <num>,
      "percentage overhead" : <num>,
      "tracked dirty pages in the cache" : <num>,
      "pages currently held in the cache" : <num>,
      "pages read into cache" : <num>,
      "pages written from cache" : <num>,
   },
   ...

有关某些关键高速缓存和逐出统计信息(例如wiredTiger.cache.bytes currently in the cachewiredTiger.cache.tracked dirty bytes in the cache)的说明,请参见wiredTiger.cache

要调整 WiredTiger 内部缓存的大小,请参见storage.wiredTiger.engineConfig.cacheSizeGB--wiredTigerCacheSizeGB。避免将 WiredTiger 内部缓存的大小增加到其默认值以上。

如何计算应用程序需要多少 RAM?

通过 WiredTiger,MongoDB 可以利用 WiredTiger 内部缓存和文件系统缓存。

从 MongoDB 3.4 开始,默认的 WiredTiger 内部缓存大小是以下两者中的较大者:

Note

在某些情况下,例如在容器中运行时,数据库的内存限制可能低于系统总内存。在这种情况下,此内存限制而不是系统总内存将用作最大可用 RAM。

要查看内存限制,请参阅hostInfo.system.memLimitMB

默认情况下,WiredTiger 对所有集合使用 Snappy 块压缩,对所有索引使用前缀压缩。压缩默认值是可以在全局级别配置的,也可以在收集和索引创建期间基于每个集合和每个索引进行设置。

WiredTiger 内部缓存中的数据与磁盘格式使用不同的表示形式:

通过文件系统缓存,MongoDB 自动使用 WiredTiger 缓存或其他进程未使用的所有可用内存。

要调整 WiredTiger 内部缓存的大小,请参见storage.wiredTiger.engineConfig.cacheSizeGB--wiredTigerCacheSizeGB。避免将 WiredTiger 内部缓存的大小增加到其默认值以上。

Note

storage.wiredTiger.engineConfig.cacheSizeGB限制了 WiredTiger 内部缓存的大小。os 将可用的可用内存用于文件系统缓存,从而允许压缩的 MongoDB 数据文件保留在内存中。此外,os 将使用任何可用的 RAM 来缓冲文件系统块和文件系统缓存。

为了容纳更多的 RAM 使用者,您可能必须减小 WiredTiger 内部缓存的大小。

默认的 WiredTiger 内部缓存大小值假定每台计算机只有一个mongod实例。如果一台机器包含多个 MongoDB 实例,则应减小设置以容纳其他mongod实例。

如果您在不能访问系统中所有可用 RAM 的容器(例如lxccgroups,Docker 等)中运行mongod,则必须将storage.wiredTiger.engineConfig.cacheSizeGB的值设置为小于该容器中可用 RAM 的值。容器。确切的数量取决于容器中运行的其他进程。参见memLimitMB

要查看有关缓存和逐出速率的统计信息,请参阅serverStatus命令返回的wiredTiger.cache字段。

分片群集诊断

维持成功的分片群集的两个最重要的因素是:

您可以通过确保为部署选择最佳的shard key来确保避免分片遇到的大多数问题,并确保始终在当前资源饱和之前为集群添加额外的容量。continue 阅读您在生产环境中可能遇到的特定问题。

在新的分片群集中,为什么所有数据都保留在一个分片上?

您的集群必须具有足够的数据才能进行分片。分片的工作原理是在分片之间迁移块,直到每个分片具有大致相同数量的块。

默认的块大小是 64 MB。直到集群中的块不平衡超过migration threshold时,MongoDB 才会开始迁移。此行为有助于防止不必要的块迁移,这可能会降低整个群集的性能。

如果您刚刚部署了分片群集,请确保具有足够的数据以使分片有效。如果没有足够的数据来创建八个以上的 64 MB 块,则所有数据将保留在一个分片上。降低chunk size设置,或向群集添加更多数据。

作为一个相关问题,系统将仅在插入或更新时拆分块,这意味着如果配置分片并且不 continue 执行插入和更新操作,则数据库将不会创建任何块。您可以等到应用程序插入数据 手动分割块

最后,如果分片键的cardinality低,则 MongoDB 可能无法在数据之间创建足够的拆分。

为什么一个分片在分片群集中会收到不成比例的流量?

在某些情况下,单个分片或集群的子集将收到不成比例的流量和工作负载部分。在几乎所有情况下,这都是由于分片键无法有效地允许write scaling导致的。

您也可能有“热块”。在这种情况下,您可以通过拆分然后迁移这些块的一部分来解决问题。

在最坏的情况下,您可能必须考虑重新分拆数据和选择其他分片密钥以更正此模式。

什么可以阻止分片群集平衡?

如果您刚刚部署了分片群集,则可能需要考虑针对新群集的故障排除建议,该群集中的数据保留在单个碎片上

如果群集最初是平衡的,但后来却出现了数据分布不均的情况,请考虑以下可能的原因:

为什么块迁移会影响分片群集的性能?

如果迁移会影响群集或应用程序的性能,请根据影响的性质考虑以下选项:

分片密钥还可能导致应用程序将所有写入定向到单个分片。这种活动模式可能要求平衡器在写入数据后立即迁移大多数数据。考虑使用提供更好write scaling的分片键重新部署群集。

首页