文档菜单
文档首页
/
MongoDB 手册
/ / /

常见问题:自管理 MongoDB 诊断

在本页

  • 我在哪里可以找到关于一个意外停止运行的mongod 进程的信息?
  • TCP keepalive 时间会影响 MongoDB 部署吗?
  • TCP 重传超时会影响 MongoDB 部署吗?
  • 为什么 MongoDB 记录了这么多 "连接已接受" 事件?
  • 有哪些工具可用于监控 MongoDB?
  • WiredTiger 存储引擎的内存诊断
  • 分片集群诊断

本文档提供了对常见诊断问题和问题的答案。

如果您找不到您要找的答案,请检查FAQ 完整列表 或将您的问题发布到MongoDB 社区.

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

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

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

许多操作系统默认将该值设置为 7200 秒(两小时)。对于 MongoDB,通常情况下,更短的 keepalive 值(大约为 120 秒(两分钟))会带来更好的效果。

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

  • 要在Linux上查看保活设置,使用以下命令之一

    sysctl net.ipv4.tcp_keepalive_time

    或者

    cat /proc/sys/net/ipv4/tcp_keepalive_time

    该值以秒为单位。

    注意

    尽管设置名称包含ipv4,但tcp_keepalive_time值适用于IPv4和IPv6。

  • 要更改tcp_keepalive_time值,可以使用以下命令之一,提供<value>(秒)

    sudo sysctl -w net.ipv4.tcp_keepalive_time=<value>

    或者

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

    这些操作在系统重启后不会持续。要持续设置,请将以下行添加到/etc/sysctl.conf,提供<value>(秒),并重启计算机

    net.ipv4.tcp_keepalive_time = <value>

    大于300秒的保活值(5分钟)将在mongodmongos套接字上被覆盖并设置为300秒。

  • 要在Windows上查看保活设置,执行以下命令

    reg query HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters /v KeepAliveTime

    默认情况下,注册表值不存在。如果值不存在,则使用系统默认值,即7200000毫秒或十六进制中的0x6ddd00


  • 要更改KeepAliveTime值,请在管理员命令提示符中使用以下命令命令提示符,其中<value>以十六进制表示(例如,1200000x1d4c0

    reg add HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\ /t REG_DWORD /v KeepAliveTime /d <value>

    Windows用户应考虑查看有关在Windows系统上为MongoDB部署设置keepalive的Windows Server Technet文章关于KeepAliveTime以获取更多信息。大于或等于600000毫秒(10分钟)的keepalive值将被mongodmongos忽略。

  • 要在macOS上查看keepalive设置,请运行以下命令

    sysctl net.inet.tcp.keepidle

    该值以毫秒为单位。


  • 要更改net.inet.tcp.keepidle值,可以使用以下命令,提供一个<value>毫秒

    sudo sysctl net.inet.tcp.keepidle=<value>

    此操作不会在系统重启后保持,每次系统重启时都必须设置。有关设置此值以持久化的说明,请参阅操作系统的文档。大于或等于600000毫秒(10分钟)的keepalive值将被mongodmongos忽略。

    注意

    在macOS 10.15 Catalina中,Apple不再允许配置net.inet.tcp.keepidle选项。

您需要重新启动mongodmongos进程,以便新的系统级keepalive设置生效。

如果您在客户端和服务器之间或在分片集群或副本集的成员之间遇到长时间停滞(超过两分钟的停滞)以及网络超时或套接字错误,请检查受影响系统的 tcp_retries2 值。

大多数 Linux 操作系统将该值默认设置为 15,而 Windows 则设置为 5。对于 MongoDB,较低的 tcp_retries2 值(大约为 5(12 秒)或更低)会产生更好的结果。

如果您的 MongoDB 部署遇到与 TCP 重传超时相关的问题,请更改所有受影响系统的 tcp_retries2 值(Windows 上的 TcpMaxDataRetransmission)。这包括所有运行 mongodmongos 进程的机器,以及所有托管连接到 MongoDB 的客户端进程的机器。

在大多数 Linux 操作系统中,通过调整 net.ipv4.tcp_retries2 sysctl 设置来控制 TCP 重传。

注意

尽管设置名称包含 ipv4,但 tcp_retries2 设置适用于 IPv4 和 IPv6。

  • 要查看当前设置,请使用 sysctl 命令

    sysctl net.ipv4.tcp_retries2
    net.ipv4.tcp_retries = 15
  • 要动态更改 tcp_retries2 设置,请使用 sysctl 命令

    sysctl -w net.ipv4.tcp_retries2=8
  • 要使更改永久生效,请编辑配置文件

    1. 在您喜欢的文本编辑器中打开 /etc/sysctl.conf

      vi /etc/sysctl.conf
    2. 配置 net.ipv4.tcp_retries2 设置

      net.ipv4.tcp_retries2 = 8
    3. 重启系统。

    您的系统现在使用新的 tcp_retries2 设置。

在 Windows 上,通过调整 TcpMaxDataRetransmissions 参数来控制 TCP 重传。

  • 要在 Windows 上查看 TcpMaxDataRetransmissions 设置,请执行以下命令

    reg query HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters /v TcpMaxDataRetransmissions

    默认情况下,该参数未设置。如果不存在值,则使用系统默认值,为 5 次重试。

  • 要更改 TcpMaxDataRetransmissions 的值,请在管理员 命令提示符 中使用以下命令,其中 <value> 是一个整数

    reg add HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\ /t REG_DWORD /v TcpMaxDataRetransmission /d <value>

如果您在 MongoDB 日志中看到大量的连接和重连消息,那么客户端频繁地连接和断开 MongoDB 服务器。这对于不使用请求池的应用程序(如 CGI)来说是正常行为。考虑使用 FastCGI、Apache 模块或其他类型的持久化应用服务器来减少连接开销。

如果这些连接不会影响您的性能,您可以使用运行时 quiet 选项或命令行选项 --quiet 来抑制这些消息从日志中输出。

MongoDB Cloud Manager 和 Ops Manager,MongoDB Enterprise Advanced 中提供的本地解决方案 包含监控功能,该功能从运行的 MongoDB 部署中收集数据,并根据这些数据提供可视化和警报。

有关更多信息,请参阅 MongoDB Cloud Manager 文档Ops Manager 文档。

第三方工具的完整列表作为 监控自管理的 MongoDB 部署 文档的一部分提供。

不。

如果缓存没有足够的空间来加载更多数据,WiredTiger 会从缓存中逐页删除以腾出空间。

注意

storage.wiredTiger.engineConfig.cacheSizeGB 限制了 WiredTiger 内部缓存的大小。操作系统使用可用的空闲内存作为文件系统缓存,这允许压缩的 MongoDB 数据文件保持在内存中。此外,操作系统还使用任何空闲 RAM 来缓冲文件系统块和文件系统缓存。

为了适应额外的 RAM 消费者,您可能需要减小 WiredTiger 内部缓存的大小。

默认的WiredTiger内部缓存大小假设每台机器上只有一个 mongod 实例。如果一台机器上包含多个MongoDB实例,则应降低此设置以适应其他 mongod 实例。

如果您在一个容器(例如,lxccgroups、Docker等)中运行 mongod,而这个容器无法访问系统中的全部RAM,您必须将 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内部缓存大小增加到其默认值以上。

使用WiredTiger,MongoDB同时利用WiredTiger内部缓存和文件系统缓存。

默认的WiredTiger内部缓存大小是以下两者中较大的一个:

  • RAM的50%(减去1 GB),或

  • 256 MB。

例如,在一个总共有4GB RAM的系统上,WiredTiger缓存使用1.5GB的RAM(0.5 * (4 GB - 1 GB) = 1.5 GB)。相反,在一个总共有1.25GB RAM的系统上,WiredTiger将256 MB分配给WiredTiger缓存,因为这比总RAM减去1GB的一半还多(0.5 * (1.25 GB - 1 GB) = 128 MB < 256 MB)。

注意

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

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

默认情况下,WiredTiger为所有集合使用Snappy块压缩,并为所有索引使用前缀压缩。压缩默认值可在全局级别进行配置,也可以在创建集合和索引时按集合和索引设置。

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

  • 文件系统缓存中的数据与磁盘格式相同,包括数据文件压缩的任何好处。文件系统缓存由操作系统用于减少磁盘I/O。

  • 在WiredTiger内部缓存中加载的索引与磁盘格式有不同的数据表示形式,但仍然可以利用索引前缀压缩来减少RAM使用。索引前缀压缩从索引字段中删除常见的公共前缀。

  • WiredTiger内部缓存中的集合数据未压缩,并使用与磁盘格式不同的表示形式。块压缩可以提供显著的磁盘存储节省,但数据必须未压缩才能由服务器进行操作。

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

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

注意

storage.wiredTiger.engineConfig.cacheSizeGB 限制了 WiredTiger 内部缓存的大小。操作系统使用可用的空闲内存作为文件系统缓存,这允许压缩的 MongoDB 数据文件保持在内存中。此外,操作系统还使用任何空闲 RAM 来缓冲文件系统块和文件系统缓存。

为了适应额外的 RAM 消费者,您可能需要减小 WiredTiger 内部缓存的大小。

默认的WiredTiger内部缓存大小假设每台机器上只有一个 mongod 实例。如果一台机器上包含多个MongoDB实例,则应降低此设置以适应其他 mongod 实例。

如果您在一个容器(例如,lxccgroups、Docker等)中运行 mongod,而这个容器无法访问系统中的全部RAM,您必须将 storage.wiredTiger.engineConfig.cacheSizeGB 设置为一个小于容器中可用RAM的值。确切的数量取决于容器中运行的其他进程。请参阅 memLimitMB

要查看缓存和驱逐率的统计信息,请查看wiredTiger.cache字段,该字段由serverStatus命令返回。

维护成功碎片集群的两个最重要因素是

虽然您可以在以后更改您的碎片键,但仔细考虑您的碎片键选择以避免可扩展性和性能问题很重要。继续阅读,了解在生产环境中可能遇到的特定问题。

您的集群必须有足够的数据才能使分片有意义。分片通过在分片之间迁移数据块,直到每个分片具有大致相同数量的数据块来实现。

默认数据块大小为128兆字节。MongoDB将在集群中数据块的不平衡超过迁移阈值之前不会开始迁移。此行为有助于防止不必要的块迁移,这可能会降低集群的整体性能。

如果您刚刚部署了一个分片集群,请确保您有足够的数据使分片有效。如果您没有足够的数据来创建超过八个128兆字节的数据块,则所有数据都将保留在一个分片上。您可以选择降低数据块大小设置,或者向集群添加更多数据。

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

最后,如果您的分片键的基数较低,MongoDB可能无法在数据中创建足够的拆分。

在某些情况下,单个分片或集群的一部分将接收到不成比例的流量和工作负载。在几乎所有情况下,这是由于分片键没有有效地允许写入扩展

还可能存在“热点数据块”。在这种情况下,您可能可以通过拆分并迁移这些数据块的部分来解决该问题。

您可能需要考虑使用不同的分片键重新分片您的集合来纠正此模式。选择不同的分片键

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

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

  • 您已从集群中删除或删除了大量数据。如果您已添加附加数据,它可能具有与分片键相关的不同分布。

  • 您的分片键具有低基数,MongoDB无法进一步分割数据块。

  • 数据集的增长速度快于平衡器在集群中分配数据的能力。这很少见,通常是以下结果

    • 给定数据增长速度,平衡窗口太短。

    • 写入操作的不均匀分布需要更多数据迁移。您可能需要选择不同的分片键来解决此问题。

    • 分片之间的网络连接性差,可能导致迁移数据块耗时过长。调查您的网络配置和分片之间的互连。

如果迁移影响了您的集群或应用程序的性能,请考虑以下选项,具体取决于影响性质

  1. 如果迁移只是偶尔中断您的集群,您可以限制平衡窗口以防止在高峰时段进行平衡活动。确保有足够的时间来防止数据再次变得不平衡。

  2. 如果平衡器总是以损害整体集群性能的方式迁移分片

也可能是因为您的分片键导致您的应用程序将所有写入操作都导向单个分片。这种活动模式可能需要平衡器在写入后不久迁移大部分数据。您可能需要考虑使用重新分片集合并使用提供更好分片键来提供更好的写入扩展性

返回

监控