- MongoDB官方文档中文版
- MongoDB中文手册说明
- MongoDB简介
- 安装 MongoDB
- The mongo Shell
- MongoDB CRUD 操作
- 聚合
- 数据模型
- 事务
- 索引
- 安全
- 安全检查列表
- 启用访问控制
- 身份验证
- 基于角色的访问控制
- TLS / SSL(传输加密)
- 静态加密
- 客户端字段级加密
- 审计
- 网络和配置强化
- 实现字段级别修订
- 安全参考
- 附录
- 变更流
- 复制
- 分片
- 分片键
- 哈希分片
- 范围分片
- 区
- 管理分片区
- 按位置细分数据
- 用于更改SLA或SLO的分层硬件
- 按应用或客户细分数据
- 仅插入工作负载的分布式本地写入
- 管理分片区
- 使用块进行数据分区
- 在分片集群中拆分数据块
- 管理
- 存储
- 存储引擎
- 日志记录
- 管理日志记录
- GridFS
- FAQ:MongoDB 存储
- 存储引擎
- 参考
- 运算符
- 查询与映射运算符
- 更新运算符
- 聚合管道阶段
- 聚合管道操作符
- $abs (aggregation)
- $acos (aggregation)
- $acosh (aggregation)
- $add (aggregation)
- $addToSet (aggregation)
- $allElementsTrue (aggregation)
- $and (aggregation)
- $anyElementTrue (aggregation)
- $arrayElemAt (aggregation)
- $arrayToObject (aggregation)
- $asin (aggregation)
- $asinh (aggregation)
- $atan (aggregation)
- $atan2 (aggregation)
- $atanh (aggregation)
- $avg (aggregation)
- $ceil (aggregation)
- $cmp (aggregation)
- $concat (aggregation)
- $concatArrays (aggregation)
- $cond (aggregation)
- $convert (aggregation)
- $cos (aggregation)
- $dateFromParts (aggregation)
- $dateToParts (aggregation)
- $dateFromString (aggregation)
- $literal (aggregation)
- 查询修饰符
- 数据库命令
- 聚合命令
- 地理空间命令
- 查询和写操作命令
- 查询计划缓存命令
- 认证命令
- 用户管理命令
- 角色管理命令
- 复制命令
- 分片命令
- 会话命令
- 管理命令
- 诊断命令
- 免费监控命令
- 系统事件审计命令
- mongo Shell 方法
- 集合方法
- db.collection.aggregate()
- db.collection.bulkWrite()
- db.collection.copyTo()
- db.collection.count()
- db.collection.countDocuments()
- db.collection.estimatedDocumentCount()
- db.collection.createIndex()
- db.collection.createIndexes()
- db.collection.dataSize()
- db.collection.deleteOne()
- db.collection.deleteMany()
- db.collection.distinct()
- db.collection.drop()
- db.collection.dropIndex()
- db.collection.dropIndexes()
- db.collection.ensureIndex()
- db.collection.explain()
- db.collection.find()
- db.collection.findAndModify()
- db.collection.findOne()
- db.collection.findOneAndDelete()
- db.collection.findOneAndReplace()
- db.collection.findOneAndUpdate()
- db.collection.getIndexes()
- db.collection.getShardDistribution()
- db.collection.getShardVersion()
- db.collection.insert()
- db.collection.insertOne()
- db.collection.insertMany()
- db.collection.isCapped()
- db.collection.latencyStats()
- db.collection.mapReduce()
- db.collection.reIndex()
- db.collection.remove()
- db.collection.renameCollection()
- db.collection.replaceOne()
- db.collection.save()
- db.collection.stats()
- db.collection.storageSize()
- db.collection.totalIndexSize()
- db.collection.totalSize()
- db.collection.update()
- db.collection.updateOne()
- db.collection.updateMany()
- db.collection.watch()
- db.collection.validate()
- 词汇表
- 默认的MongoDB端口
- 默认的MongoDB读/写关注
- 服务器会话
- MongoDB驱动
- FAQ
- 联系我们
- 更多资料
- [快学Mongo]
- [Mongo问题讨论区]
- [Mongo 驱动使用手册]
- 本书使用 GitBook 发布
FAQ: MongoDB 诊断
常见问题解答:MongoDB诊断
在本页面
- 在哪里可以找到有关
mongod
进程意外停止运行的信息? - TCP
keepalive
时间会影响MongoDB部署吗? - 为什么MongoDB会记录这么多“Connection Accepted”事件?
- 哪些工具可用于监视MongoDB?
- WiredTiger存储引擎的内存诊断
- 分片集群诊断
本文档提供了常见诊断问题的答案。
如果找不到所需的答案,请查看常见问题解答的完整列表或将问题发布到 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时间设置,主要用来探测连接对端是否还存活。当你建立一个TCP连接的时候,便有一组定时器与之绑定在一起。其中的一些定时器就用于处理keepalive过程。当keepalive定时器到0的时候,我们便会给对端发送一个不包含数据部分的keepalive探测包。如果我们收到了keepalive探测包的回复消息,那么我们就可以断定连接依然是OK的。如果我们没有收到对端keepalive探测包的回复消息,我们便可以断定连接已经不可用,进而可以采取一些措施。)
在客户端和服务器之间或者分片集群或副本集的成员之间,如果通信中遇到网络超时或套接字错误,请检查受影响系统的TCP keepalive值。
许多操作系统默认将TCP keepalive值设置为7200
秒(两个小时)。对于MongoDB,通常情况下,保持较短时间值(120
几秒钟(两分钟)),您将获得更好的结果。
如果您的MongoDB部署遇到与keepalive相关的问题,则必须更改所有受影响系统上的keepalive价值。这些系统包括所有正在运行mongod
或mongos
的计算机以及连接到MongoDB的客户端进程的所有计算机。
调整TCP keepalive值:¶
Linux
Windows
macOS
要在Linux上查看keepalive设置,请使用以下命令之一:
复制
sysctl net.ipv4.tcp_keepalive_time
Or:
复制
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
,在几秒钟内提供一个
复制
net.ipv4.tcp_keepalive_time = <value>
mongod
和 mongos
进程将设置Keepalive值为300
秒(5分钟),来重写覆盖大于5分钟的设置。
- 要在Windows上查看keepalive设置,请使用以下命令之一:
复制
reg query HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters /v KeepAliveTime
注册表值默认情况下不存在。如果没有该值,则使用系统默认值,以7200000
毫秒为单位或 0x6ddd00
以十六进制表示。
- 要改变
KeepAliveTime
值,在管理员使用以下命令提示符,其中以十六进制(例如,表示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的更多信息。mongod
和mongos
会忽略大于或等于600000毫秒(10分钟)的 keepalive值 。
- 要在macOS上查看keepalive设置,请使用以下命令之一:
复制
sysctl net.inet.tcp.keepidle
该值以秒为单位测量。
- 要更改该
net.inet.tcp.keepidle
值,可以使用以下命令,以毫秒为单位提供一个 :
复制
sudo sysctl net.inet.tcp.keepidle=<value>
此操作不会在系统重新启动后持续存在,必须在每次系统重新启动时进行设置。请参阅操作系统的文档,以获取有关持久设置此值的说明。mongod
和mongos
会忽略大于或等于600000
毫秒(10分钟)的keepalive值。
注意
在macOS 10.15 Catalina中,Apple不再允许配置该net.inet.tcp.keepidle
选项。
您将需要重新启动mongod
并mongos
进程,新的Keepalive系统设置才能生效。
为什么MongoDB记录这么多“Connection Accepted” 事件?¶
如果您在MongoDB日志中看到大量的连接和重新连接消息,则说明客户端与MongoDB服务器经常连接和断开。对于不使用请求池的应用程序(例如CGI),这是正常的行为。考虑使用FastCGI,Apache模块或其他某种持久性应用程序服务器来减少连接开销。
如果这些连接不影响性能,则可以使用运行时quiet
选项或命令行选项 --quiet
从日志中禁止显示这些消息。
哪些工具可用于监视MongoDB?¶
从版本4.0开始,MongoDB 为单机部署和副本集提供免费的云监控。免费监控可提供如下部署的信息:
- 操作执行时间
- 内存使用情况
- CPU使用率
- 操作计数
有关更多信息,请参见免费监控。
在MongoDB Cloud Manager和 在MongoDB的企业提供先进的内部部署解决方案的Ops Manager包括监控功能,其收集运行的MongoDB部署数据,并提供基于数据的可视化和警报。
有关更多信息,另请参阅MongoDB Cloud Manager文档和 Ops Manager文档。
Monitoring for MongoDB文档中提供了完整的第三方工具列表。
WiredTiger存储引擎的内存诊断
我的working set必须适合内存吗?
不需要。
如果缓存没有足够的空间来加载其他数据,则WiredTiger会将页面从缓存中逐出以释放空间。
注意
该storage.wiredTiger.engineConfig.cacheSizeGB
限制WiredTiger内部缓存的大小。操作系统将使用可用的空闲内存进行文件系统缓存,从而允许压缩的MongoDB数据文件保留在内存中。此外,操作系统将使用任何可用的RAM来缓冲文件系统块和文件系统缓存。
为了容纳更多的内存使用者,您可能必须减小WiredTiger内部缓存的大小。
默认的WiredTiger内部缓存大小值假定每台计算机有一个mongod
实例。如果一台机器包含多个MongoDB实例,则您应减小设置以容纳其他mongod
实例。
如果你在一个容器(例如lxc
, cgroups
,Docker,等等)运行mongod
,它没有访问所有系统中可用的RAM,您必须设置storage.wiredTiger.engineConfig.cacheSizeGB
的值小于容器使用的内存量。确切的数量取决于容器中运行的其他进程。请参阅 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内部缓存的大小增加到其默认值以上。
如何计算应用程序需要多少内存?¶
通过WiredTiger,MongoDB可以利用WiredTiger内部缓存和文件系统缓存。
从MongoDB 3.4开始,默认的WiredTiger内部缓存大小是以下两者中的较大者:
- 50% of (RAM - 1 GB), or
- 256 MB.
例如,在总共有4GB内存的系统上,WiredTiger缓存将使用1.5GB 内存(0.5 * (4 GB - 1 GB) = 1.5
)。相反,总内存为1.25 GB的系统将为WiredTiger高速缓存分配256 MB,因为这是总内存的一半以上减去1 GB 。(0.5 * (1.25 GB - 1 GB) = 128 MB < 256 MB
).
注意
在某些情况下,例如在容器中运行时,数据库的内存限制可能低于系统总内存。在这种情况下,此内存限制而不是系统总内存将用作最大可用内存。
要查看内存限制,请参阅hostInfo.system.memLimitMB
。
默认情况下,WiredTiger对所有集合使用Snappy块压缩,对所有索引使用前缀压缩。压缩默认设置可在全局级别配置,也可以在每个集合和每个索引创建期间单独进行设置。
WiredTiger内部缓存中的数据与磁盘上的格式使用不同的形式的数据格式:
- 文件系统缓存中的数据与磁盘格式相同,包括对数据文件进行任何压缩的好处。操作系统使用文件系统缓存来减少磁盘I / O。
- 加载到WiredTiger内部缓存中的索引的数据表示形式与磁盘格式不同,但是仍可以利用索引前缀压缩来减少n内存使用量。索引前缀压缩可从索引字段中删除通用前缀。
- WiredTiger内部缓存中的集合数据是未压缩的,并使用与磁盘格式不同的表示形式。块压缩可以节省大量的磁盘存储空间,但数据解压缩才能由服务器操作。
通过文件系统缓存,MongoDB自动使用WiredTiger缓存或其他进程未使用的所有可用内存。
要调整WiredTiger内部缓存的大小,请参阅 storage.wiredTiger.engineConfig.cacheSizeGB
和 --wiredTigerCacheSizeGB
。避免将WiredTiger内部缓存的大小增加到其默认值以上。
注意
该storage.wiredTiger.engineConfig.cacheSizeGB
限制WiredTiger内部缓存的大小。操作系统将使用可用的空闲内存进行文件系统缓存,从而允许压缩的MongoDB数据文件保留在内存中。此外,操作系统将使用任何可用的内存来缓冲文件系统块和文件系统缓存。
为了容纳更多的内存使用者,您可能必须减小WiredTiger内部缓存的大小。
默认的WiredTiger内部缓存大小值假定每台计算机有一个mongod
实例。如果单个机器包含多个MongoDB实例,则应减小设置以容纳其他mongod
实例。
如果你在一个容器(例如lxc
, cgroups
,Docker,等等)运行mongod
,它没有访问所有系统中可用的内存,您必须将storage.wiredTiger.engineConfig.cacheSizeGB`的值设置为小于容器可用内存大小的值。确切的大小取决于容器中运行的其他进程。参见 memLimitMB
。
要查看有关缓存和缓存淘汰率的统计信息,请参阅wiredTiger.cache
命令返回的serverStatus
字段。
分片群集诊断
成功维护分片集群的两个最重要的因素是:
通过确保为部署选择最佳的片键,并确保始终在当前资源饱和之前为集群添加额外的容量,可以避免分片遇到的大多数问题。继续阅读,查看您在生产环境中可能遇到的特定问题。
在新的分片集群中,为什么所有数据都保留在一个分片上?
您的集群必须具有足够的数据才能进行分片。分片的工作原理是在分片之间迁移数据块,直到每个分片具有大致相同数量的分块。
默认的块大小为64 MB。在集群中的大块不平衡量超过迁移阈值之前,MongoDB不会开始迁移 。此行为有助于防止不必要的块迁移降低整个集群的性能。
如果您刚刚部署了分片集群,请确保您有足够的数据使分片有效。如果没有足够的数据来创建八个以上的64 MB数据块,则所有数据将保留在一个分片上。降低块大小设置,或向集群添加更多数据。
作为一个相关问题,系统将仅在插入或更新时拆分块,这意味着,如果您配置了分片并且不继续执行插入和更新操作,则数据库将不会创建任何块。您可以等待,直到应用程序插入数据或 手动拆分块。
最后,如果片键的基数较低,则MongoDB可能无法在数据之间创建足够的拆分(chunk将无法继续分裂)。
为什么一个分片会在分片集群中会收到不均衡的流量?
在某些情况下,单个分片或集群的子集将接收不均衡的流量和工作负载。在几乎所有情况下,这都是因为片键无法高效地允许写缩放。
您也可能有“hot chunks”。在这种情况下,您可以通过拆分然后迁移部分块来解决问题。
在最坏的情况下,您可能必须考虑重新分拆数据并选择其他片键 来更正此模式。
什么可以阻止分片集群均衡?¶
如果您刚刚部署了分片群集,则可能需要考虑针对新集群数据仍保留在单个分片上的故障排除建议。
如果集群最初是均衡的,但后来却出现了数据分布不均的情况,请考虑以下可能的原因:
- 您已从集群中删除或移除了大量数据。如果添加了其他数据,则其片键的分配可能会有所不同。
- 您的片键具有较低的基数, 并且MongoDB无法进一步拆分块。
您的数据集增长速度超过了均衡器可以在集群中分发数据的速度。这种情况并不常见,通常是由于以下原因造成的:
为什么块迁移会影响分片集群的性能?
如果迁移会影响您的集群或应用程序的性能,请根据影响的性质考虑以下选项:
1.如果迁移仅偶尔中断集群,则可以限制均衡窗口以防止高峰时段进行均衡活动。确保有足够的时间来防止数据再次失去均衡。
2.如果均衡器始终在迁移块而不利于整体集群性能:
您的片键还可能导致应用程序将所有写入指向单个分片。这种活动模式可能要求均衡器在写入数据后立即迁移大部分数据。请考虑使用提供更好写入扩展的片键重新部署集群。
原文链接:https://docs.mongodb.com/manual/faq/diagnostics/
译者:钟秋
update:小芒果
Copyright © 上海锦木信息技术有限公司 all right reserved,由 MongoDB汉化小组 提供技术支持文件修订时间: 2020-10-11 20:53:05