Docs 菜单
Docs 主页
/
MongoDB Manual
/ /

常见问题解答:适用于自管理部署的 MongoDB 存储

在此页面上

  • 存储引擎基础知识
  • 是否可以在副本集中混合使用存储引擎?
  • 存储建议
  • WiredTiger 存储引擎
  • 数据存储诊断

本文档用于解答有关 MongoDB 存储系统的常见问题。

存储引擎是数据库的一部分,它负责管理数据在内存和磁盘上的存储方式。很多数据库支持多种存储引擎,而不同的引擎可为特定工作负载提供更好的性能。例如,一种存储引擎可能会为读取密集型工作负载提供更好的性能,另一种存储引擎则可能为写入操作提供更高的吞吐量。

提示

另请参阅:

用于自管理部署的存储引擎

是的。您可以拥有使用不同存储引擎(WiredTiger 和内存型)的副本集节点。

一旦集合和索引的总数超过 100,000,集群性能可能会下降。此外,大量大型集合对性能的影响要比相同数量小型集合对性能产生的影响更大。

是的,可以。请参阅:

压缩率取决于数据和使用的压缩库。默认情况下,WiredTiger 中的集合数据使用 Snappy 区块压缩;zlibzstd 压缩也可用。索引数据默认使用前缀压缩

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

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

  • (RAM 大小 - 1 GB)的 50%,或

  • 256 MB.

例如,在总 RAM 为4 GB 的系统上,WiredTiger 缓存使用1.5 GB RAM ( 0.5 * (4 GB - 1 GB) = 1.5 GB )。 相反,在总1.25 GB 的 RAM WiredTiger 会分配256 MB 给 WiredTiger 缓存,因为这超过总 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 字段。

每个连接最多使用 1 MB RAM。

要优化连接的内存使用,请确保:

  • 监控部署的打开连接数。打开的连接数过多会导致 RAM 过度使用,进而减少工作集的可用内存。

  • 当不再需要它们时,关闭连接池。连接池是由驱动程序维护的、开放且随时可用的数据库连接的缓存。关闭不需要的连接池可以释放更多内存资源。

  • 管理连接池的大小。maxPoolSize 连接字符串选项指定池中打开的最大连接数。默认情况下,池中最多可有 100 个打开的连接。降低 maxPoolSize 会减少用于连接的最大 RAM 量。

    提示

    要配置连接池,请参阅连接池配置设置。

检查点
MongoDB 配置 WiredTiger 创建检查点,具体而言,就是以 60 秒的间隔将快照数据写入磁盘。
Journal Data
当满足以下任一条件时,WiredTiger 会将缓冲的日志记录同步到磁盘:
  • 对于副本集成员(主节点和从节点成员):

    • 如果写入操作包含或暗示 j: true 的写关注。

    • 此外,对于从节点,在每次批量应用 oplog 条目之后进行。

    注意

    如果 writeConcernMajorityJournalDefault 为真,则写关注 "majority" 暗示为 j: true

  • 每 100 毫秒一次(请参阅 storage.journal.commitIntervalMs)。

  • 当 WiredTiger 创建新的日志文件时。由于 MongoDB 使用上限 100 MB 的日志文件,所以 WiredTiger 大约每 100 MB 数据创建一份新日志文件。

WiredTiger 存储引擎在删除文档时会在数据文件中维护空记录列表。此空间可被 WiredTiger 重用,但不会返回给操作系统(特殊情况除外)。

可供 WiredTiger 重用的空闲空间量反映在 wiredTiger.block-manager.file bytes available for reuse 下的 db.collection.stats() 输出中。

要允许 WiredTiger 存储引擎将此空闲空间释放给操作系统,可以对数据文件进行碎片整理。这可以通过重新同步副本集节点或使用 compact 命令来实现。

要查看集合的统计信息(包括数据大小),请使用 mongosh 中的 db.collection.stats() 方法。以下示例为 orders 集合发出 db.collection.stats()

db.orders.stats();

MongoDB 还提供以下方法返回集合的特定大小信息:

以下脚本会输出每个数据库的统计信息:

db.adminCommand("listDatabases").databases.forEach(function (d) {
mdb = db.getSiblingDB(d.name);
printjson(mdb.stats());
})

以下脚本会打印出每个数据库中每个集合的统计信息:

db.adminCommand("listDatabases").databases.forEach(function (d) {
mdb = db.getSiblingDB(d.name);
mdb.getCollectionNames().forEach(function(c) {
s = mdb[c].stats();
printjson(s);
})
})

要查看为每个索引分配的数据大小,使用 db.collection.stats() 方法并检查返回文档中的 indexSizes 字段。

如果索引使用前缀压缩(即 default for WiredTiger),针对该索引返回的大小将反映压缩后的大小。

mongosh 中的 db.stats() 方法会返回“活动”数据库的当前状态。有关返回字段的说明,请参阅 dbStats 输出

后退

GridFS