数据库有 3 个集合,包含 40 亿条记录。我尝试过一次性单独索引所有集合。每次扫描完成后,mongodb 都会崩溃/停止服务。
我正在 MongoDB shell 中运行这些命令来索引。
use Database db.collection.createIndex({value: 1})
在处理非常大的数据集(例如 40 亿条记录)时,MongoDB 在创建索引时可能会由于资源耗尽而崩溃。这种情况通常是由于以下原因之一引起的:
不要一次性为整个集合创建索引,而是分批创建。您可以使用 partialFilterExpression 或限制数据范围来减小每次操作的规模。例如:
partialFilterExpression
db.collection.createIndex({ value: 1 }, { partialFilterExpression: { value: { $gte: 0, $lt: 1000000 } } });
这样可以先为数据子集创建索引,然后扩展索引范围。
在索引创建过程中,使用 background: true(对于 MongoDB 4.2 之前)或默认选项(MongoDB 4.2 及之后的版本索引创建默认异步)以避免锁定集合:
background: true
db.collection.createIndex({ value: 1 }, { background: true });
storageEngine
如果使用的是 WiredTiger 存储引擎,可以尝试调整 wiredTiger 配置参数以优化索引创建。更新 mongod.conf 配置文件:
wiredTiger
mongod.conf
storage: wiredTiger: engineConfig: cacheSizeGB: 4 # 根据系统内存调整缓存大小
然后重启 MongoDB 服务。
如果集合已经非常大,建议将其分片(sharding)。MongoDB 分片允许将数据和索引分布在多个服务器上,从而分散负载。
sh.enableSharding("Database"); sh.shardCollection("Database.collection", { value: 1 });
查看 MongoDB 日志文件(默认路径为 /var/log/mongodb/mongod.log 或 C:\Program Files\MongoDB\Server\<version>\log)以了解崩溃的具体原因。日志通常会提供有关内存或磁盘问题的详细信息。
/var/log/mongodb/mongod.log
C:\Program Files\MongoDB\Server\<version>\log
如果不使用分片,您可以在应用程序中分批处理数据索引。示例(以 Python 为例):
from pymongo import MongoClient client = MongoClient("mongodb://localhost:27017/") db = client['Database'] collection = db['collection'] batch_size = 10_000_000 start = 0 while True: end = start + batch_size result = collection.create_index( [('value', 1)], partialFilterExpression={"value": {"$gte": start, "$lt": end}} ) print(f"Indexed range {start} to {end}") start = end if collection.count_documents({"value": {"$gte": start}}) == 0: break
确保使用最新的稳定版 MongoDB,特别是性能改进显著的版本。使用 MongoDB 5.x 或更高版本的用户可以尝试集群优化索引创建。
通过这些优化措施,您可以避免索引创建时 MongoDB 崩溃的问题。