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

常见问题解答:自托管部署的MongoDB存储

本页内容

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

本文档解答了关于MongoDB存储系统的一些常见问题。

存储引擎是数据库的一部分,负责管理数据的存储方式,包括内存和磁盘上的数据。许多数据库支持多种存储引擎,不同的引擎对特定工作负载的性能表现更优。例如,一种存储引擎可能对读密集型工作负载提供更好的性能,而另一种可能支持更高的写入吞吐量。

提示

另请参阅

自托管部署的存储引擎

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

当集合和索引的总数超过100,000时,集群的性能可能会下降。此外,许多大型集合对性能的影响大于小型集合。

是的。请参阅

压缩数据与未压缩数据的比率取决于您的数据和所使用的压缩库。默认情况下,WiredTiger中的集合数据使用Snappy块压缩;也提供zlibzstd压缩。索引数据默认使用前缀压缩

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

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

  • RAM的50%减去1 GB,或者

  • 256 MB。

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

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

每个连接最多使用1兆字节的RAM。

为了优化连接的内存使用,请确保您

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

  • 当不再需要时关闭连接池。连接池是驱动程序维护的已打开、准备就绪的数据库连接的缓存。关闭未使用的池可以释放额外的内存资源。

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

    提示

    要配置您的连接池,请参阅Connection Pool Configuration Settings

检查点
MongoDB 将 WiredTiger 配置为创建检查点,具体来说,每隔 60 秒将快照数据写入磁盘。
日志数据
WiredTiger 在以下任何一种情况下都会同步缓冲的日志记录到磁盘
  • 对于副本集成员(主成员和次成员)

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

    • 此外,对于次成员,在每次应用 oplog 条目批处理后。

    注意

    写关注 "majority" 如果 writeConcernMajorityJournalDefault 为 true,则意味着 j: true

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

  • 当 WiredTiger 创建一个新的日志文件时。因为 MongoDB 使用 100 MB 的日志文件大小限制,所以 WiredTiger 大约每 100 MB 数据创建一个新的日志文件。

WiredTiger 存储引擎在删除文档时,会在数据文件中维护空记录的列表。此空间可以被 WiredTiger 重复使用,但除非在非常特定的情况下,否则不会返回给操作系统。

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

要允许 WiredTiger 存储引擎将此空空间释放给操作系统,您可以取消数据文件的碎片。这可以通过 重新同步副本集成员 或使用 compact 命令来实现。

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

db.orders.stats();

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

  • db.collection.dataSize() 返回集合的未压缩数据大小(以字节为单位)。

  • db.collection.storageSize() 返回集合在磁盘存储上的大小(以字节为单位)。如果集合数据被压缩(这是 WiredTiger 的默认设置),则存储大小反映了压缩大小,可能小于 db.collection.dataSize() 返回的值。

  • db.collection.totalIndexSize() 返回集合的索引大小(以字节为单位)。如果索引使用前缀压缩(这是 WiredTiger 的默认设置),则返回的大小反映了压缩大小。

以下脚本打印每个数据库的统计信息

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字段。

如果索引使用前缀压缩(这是WiredTiger的默认设置),则返回的索引大小反映的是压缩大小。

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

返回

GridFS