Docs 菜单
Docs 主页
/
MongoDB Manual
/ / /

常见问题解答:自管理MongoDB诊断

在此页面上

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

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

如果您没有找到所需的回答,请查看 常见问题解答的完整列表或将您的问题帖子到MongoDB Community

如果 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 上查看 keepalive 设置,请使用以下命令之一:

    sysctl net.ipv4.tcp_keepalive_time

    或者:

    cat /proc/sys/net/ipv4/tcp_keepalive_time

    该值以秒为单位。

    注意

    尽管该设置名称包含 ipv4,但 tcp_keepalive_time 值会同时应用于 IPv4 和 IPv6。

  • 要更改 tcp_keepalive_time 值,可使用以下命令之一,并提供以秒为单位的 <值>

    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>

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

  • 要在 Windows 上查看 keepalive 设置,请发出以下命令:

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

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


  • 要更改 KeepAliveTime 值,请在管理员 Command Prompt 中使用以下命令,其中 <value> 以十六进制表示(例如120000 表示为 0x1d4c0):

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

    Windows用户应考虑 有关 KeepAliveTime 的 Windows Server Technet 文章 了解有关在Windows系统上为MongoDB部署设置 keepalive 的更多信息。大于或等于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选项。

为使新的系统范围的 keepalive 设置生效,需要重新启动 mongodmongos 进程。

如果客户端与服务器之间或分片集群或副本集成员之间出现长时间暂停(暂停时间超过两分钟),随后出现网络超时或套接字错误,请检查受影响系统的 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值,请在管理员Command Prompt中使用以下命令,其中<value>是整数:

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

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

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

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

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

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

No.

如果缓存没有足够的空间来加载额外数据,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 大小 - 1 GB)的 50%,或

  • 256 MB.

例如,在总 RAM 为 4GB 的系统上,WiredTiger 缓存使用 1.5GB RAM (0.5 * (4 GB - 1 GB) = 1.5 GB)。相反,在总 RAM 为 1.25GB 的系统上,WiredTiger 为 WiredTiger 缓存分配了 256 MB,因为这大于总 RAM 的一半减去 1 GB (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

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

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

虽然您可在后续更改分片键,但请务必仔细考虑分片键的选择,以免出现可扩展性与性能问题。 继续阅读您在生产环境中可能遇到的具体问题。

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

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

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

与此相关的问题是,系统只会在插入或更新时分割数据段,这意味着如果配置分片,但不继续进行插入和更新操作,则数据库将不会创建任何数据段。您可以等待应用程序插入数据,也可以手动分割数据段

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

在某些情况下,单个分片或集群的子集会收到不成比例的流量和工作负载。在几乎所有情况下,这都是由于分片键无法有效允许写入扩展而造成的。

您也有可能有“热数据段”。在这种情况下,您也许可以通过分割然后迁移这些数据段的部分内容,来解决问题。

您可能需要考虑使用不同的分片键对集合进行重新分片,以纠正这种模式。

如果刚刚部署了分片集群,您可能希望考虑数据保留在单个分片上的新集群的故障排除建议。

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

  • 您已从集群中删除大量数据。如果您添加了其他数据,其分片键可能具有不同的分配情况。

  • 您的分片键具有较低的关联基数,MongoDB 无法进一步拆分数据段。

  • 数据集增长速度超过了负载均衡器向集群分发数据的速度。这种情况并不常见,通常由以下原因所致:

    • 考虑到数据增长率,负载均衡窗口太短。

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

    • 分片之间的网络连接较差,这可能导致数据段迁移需要太长时间才能完成。调查您的网络配置以及分片之间的互连。

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

  1. 如果迁移只是偶尔导致集群中断,则可以限制均衡窗口,防止在高峰时段进行均衡活动。确保留出足够的剩余时间,以防数据再次失衡。

  2. 如果均衡器始终会迁移数据段,导致集群整体性能受损:

您的分片键也可能导致您的应用程序将所有写入定向到单个分片。 这种活动模式可能要求负载均衡器在写入数据后立即迁移大多数数据。 您可能需要考虑使用不同的分片键对您的集合进行重新分片,以提供更好的写入扩展比例。

后退

监控