常见问题:自管理 MongoDB 诊断
在本页
本文档提供了对常见诊断问题和问题的答案。
如果您找不到您要找的答案,请检查FAQ 完整列表 或将您的问题发布到MongoDB 社区.
我在哪里可以找到关于一个意外停止运行的mongod
进程突然停止运行了?
如果 mongod
在 UNIX 或基于 UNIX 的平台上意外关闭,并且如果 mongod
无法记录关闭或错误消息,那么请检查您的系统日志中与 MongoDB 相关的消息。例如,对于位于 /var/log/messages
的日志,请使用以下命令
sudo grep mongod /var/log/messages sudo grep score /var/log/messages
TCP keepalive
时间会影响 MongoDB 部署吗?
如果您在客户端和服务器之间,或分片集群或副本集成员之间遇到网络超时或套接字错误,请检查受影响系统的 TCP keepalive 值。
许多操作系统默认将该值设置为 7200
秒(两小时)。对于 MongoDB,通常情况下,更短的 keepalive 值(大约为 120
秒(两分钟))会带来更好的效果。
如果您的 MongoDB 部署遇到与 keepalive 相关的问题,您必须更改所有受影响系统的 keepalive 值。这包括运行 mongod
或 mongos
进程的所有机器,以及所有托管连接到 MongoDB 的客户端进程的机器。
调整TCP保活值:
要在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分钟)将在mongod
和mongos
套接字上被覆盖并设置为300
秒。
要在Windows上查看保活设置,执行以下命令
reg query HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters /v KeepAliveTime 默认情况下,注册表值不存在。如果值不存在,则使用系统默认值,即
7200000
毫秒或十六进制中的0x6ddd00
。要更改
KeepAliveTime
值,请在管理员命令提示符中使用以下命令命令提示符,其中<value>
以十六进制表示(例如,120000
是0x1d4c0
)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值将被
mongod
和mongos
忽略。
要在macOS上查看keepalive设置,请运行以下命令
sysctl net.inet.tcp.keepidle 该值以毫秒为单位。
要更改
net.inet.tcp.keepidle
值,可以使用以下命令,提供一个<value>毫秒sudo sysctl net.inet.tcp.keepidle=<value> 此操作不会在系统重启后保持,每次系统重启时都必须设置。有关设置此值以持久化的说明,请参阅操作系统的文档。大于或等于
600000
毫秒(10分钟)的keepalive值将被mongod
和mongos
忽略。注意
在macOS 10.15 Catalina中,Apple不再允许配置
net.inet.tcp.keepidle
选项。
TCP 重传超时是否会影响 MongoDB 部署?
如果您在客户端和服务器之间或在分片集群或副本集的成员之间遇到长时间停滞(超过两分钟的停滞)以及网络超时或套接字错误,请检查受影响系统的 tcp_retries2
值。
大多数 Linux 操作系统将该值默认设置为 15
,而 Windows 则设置为 5
。对于 MongoDB,较低的 tcp_retries2
值(大约为 5
(12 秒)或更低)会产生更好的结果。
如果您的 MongoDB 部署遇到与 TCP 重传超时相关的问题,请更改所有受影响系统的 tcp_retries2
值(Windows 上的 TcpMaxDataRetransmission
)。这包括所有运行 mongod
或 mongos
进程的机器,以及所有托管连接到 MongoDB 的客户端进程的机器。
调整 TCP 重传超时
在大多数 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 要使更改永久生效,请编辑配置文件
在您喜欢的文本编辑器中打开
/etc/sysctl.conf
vi /etc/sysctl.conf 配置
net.ipv4.tcp_retries2
设置net.ipv4.tcp_retries2 = 8 重启系统。
您的系统现在使用新的
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 日志中看到大量的连接和重连消息,那么客户端频繁地连接和断开 MongoDB 服务器。这对于不使用请求池的应用程序(如 CGI)来说是正常行为。考虑使用 FastCGI、Apache 模块或其他类型的持久化应用服务器来减少连接开销。
如果这些连接不会影响您的性能,您可以使用运行时 quiet
选项或命令行选项 --quiet
来抑制这些消息从日志中输出。
有哪些工具可以用于监控 MongoDB?
MongoDB Cloud Manager 和 Ops Manager,MongoDB Enterprise Advanced 中提供的本地解决方案 包含监控功能,该功能从运行的 MongoDB 部署中收集数据,并根据这些数据提供可视化和警报。
有关更多信息,请参阅 MongoDB Cloud Manager 文档 和 Ops Manager 文档。
第三方工具的完整列表作为 监控自管理的 MongoDB 部署 文档的一部分提供。
我的工作集大小是否必须适合 RAM?
不。
如果缓存没有足够的空间来加载更多数据,WiredTiger 会从缓存中逐页删除以腾出空间。
注意
storage.wiredTiger.engineConfig.cacheSizeGB
限制了 WiredTiger 内部缓存的大小。操作系统使用可用的空闲内存作为文件系统缓存,这允许压缩的 MongoDB 数据文件保持在内存中。此外,操作系统还使用任何空闲 RAM 来缓冲文件系统块和文件系统缓存。
为了适应额外的 RAM 消费者,您可能需要减小 WiredTiger 内部缓存的大小。
默认的WiredTiger内部缓存大小假设每台机器上只有一个 mongod
实例。如果一台机器上包含多个MongoDB实例,则应降低此设置以适应其他 mongod
实例。
如果您在一个容器(例如,lxc
、cgroups
、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 cache
和 wiredTiger.cache.tracked dirty bytes in the cache
,请参阅 wiredTiger.cache
。
要调整WiredTiger内部缓存的大小,请参阅 storage.wiredTiger.engineConfig.cacheSizeGB
和 --wiredTigerCacheSizeGB
。避免将WiredTiger内部缓存大小增加到其默认值以上。
我该如何计算我应用程序需要的多少RAM?
使用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
实例。
如果您在一个容器(例如,lxc
、cgroups
、Docker等)中运行 mongod
,而这个容器无法访问系统中的全部RAM,您必须将 storage.wiredTiger.engineConfig.cacheSizeGB
设置为一个小于容器中可用RAM的值。确切的数量取决于容器中运行的其他进程。请参阅 memLimitMB
。
要查看缓存和驱逐率的统计信息,请查看wiredTiger.cache
字段,该字段由serverStatus
命令返回。
碎片集群诊断
维护成功碎片集群的两个最重要因素是
虽然您可以在以后更改您的碎片键,但仔细考虑您的碎片键选择以避免可扩展性和性能问题很重要。继续阅读,了解在生产环境中可能遇到的特定问题。
在一个新的分片集群中,为什么所有数据都保留在一个分片上?
您的集群必须有足够的数据才能使分片有意义。分片通过在分片之间迁移数据块,直到每个分片具有大致相同数量的数据块来实现。
默认数据块大小为128兆字节。MongoDB将在集群中数据块的不平衡超过迁移阈值之前不会开始迁移。此行为有助于防止不必要的块迁移,这可能会降低集群的整体性能。
如果您刚刚部署了一个分片集群,请确保您有足够的数据使分片有效。如果您没有足够的数据来创建超过八个128兆字节的数据块,则所有数据都将保留在一个分片上。您可以选择降低数据块大小设置,或者向集群添加更多数据。
作为一个相关问题,系统仅在插入或更新时拆分数据块,这意味着如果您配置了分片但不继续执行插入和更新操作,数据库将不会创建任何数据块。您可以选择等待您的应用程序插入数据或 手动拆分数据块。
最后,如果您的分片键的基数较低,MongoDB可能无法在数据中创建足够的拆分。
为什么在分片集群中一个分片会收到不成比例的流量?
在某些情况下,单个分片或集群的一部分将接收到不成比例的流量和工作负载。在几乎所有情况下,这是由于分片键没有有效地允许写入扩展。
还可能存在“热点数据块”。在这种情况下,您可能可以通过拆分并迁移这些数据块的部分来解决该问题。
您可能需要考虑使用不同的分片键重新分片您的集合来纠正此模式。选择不同的分片键。
什么可以阻止分片集群平衡?
如果您刚刚部署了您的分片集群,您可能需要考虑针对数据仍然保留在单个分片的新集群的故障排除建议。
如果集群最初是平衡的,但后来数据分布不均,请考虑以下可能的原因
为什么分片迁移会影响分片集群的性能?
如果迁移影响了您的集群或应用程序的性能,请考虑以下选项,具体取决于影响性质
如果迁移只是偶尔中断您的集群,您可以限制平衡窗口以防止在高峰时段进行平衡活动。确保有足够的时间来防止数据再次变得不平衡。
如果平衡器总是以损害整体集群性能的方式迁移分片
也可能是因为您的分片键导致您的应用程序将所有写入操作都导向单个分片。这种活动模式可能需要平衡器在写入后不久迁移大部分数据。您可能需要考虑使用重新分片集合并使用提供更好分片键来提供更好的写入扩展性。