System Information:
OS: Ubuntu 20.04 LTS
System: 80 GB RAM, 1 TB SSD, i7-12700k

这个集合中的文档平均为16KB,这个集合中有50万个文档.我注意到,随着集合变得越来越大,插入文档所需的时间也越来越长.

Linear relationship?

In what ways could I improve the speed of writes?

插入15万个文档需要10个小时.这大约是当我们积分这条线时图表所预测的:

def f(num):
    return 0.0004*num+0.9594

sum=0
for i in range(500,650):
    sum+=f(i*1000)

>> sum/3600
>> 9.61497

Potential upgrades in my mind:

  • 使用C++Mongo引擎进行写入
  • 给魔神分配更多的内存

Logs

iotop显示了mongod使用<1%的IO容量,写入速度约为10-20 KB/s

htop表示魔神只使用了~16 GB的内存\

显示约300 GB固态硬盘可用的磁盘

EDIT:

Psudo代码:

docs=[...]
for doc in docs:
   doc["last_updated"]=str(datetime.now())
   
   doc_from_db = collection.find_one({"key":doc["key"]})
   
   new_dict = minify(doc)
   if doc_from_db is None:
      collection.insert_one(new_dict)
   else:
      collection.replace_one({"key":doc["key"]},new_dict,upsert=true)

推荐答案

当涉及到写入时,有几件事需要考虑,我认为最有影响的一件事是这里的问题是索引大小/索引复杂性/唯一索引.

在没有更多信息的情况下,很难给出准确的建议,所以我将根据我的经验详细说明写作中最常见的瓶颈.

  1. 如前所述,如果您有太多的索引.唯一索引.或者在非常大的数组上创建索引(并且您插入的文档具有大型数组),这些都会严重影响插入性能.此行为还与您提供的图表相关,因为索引越大,插入就越糟糕.这个问题没有"真正"的解决方案,您应该重新考虑哪些索引和哪些索引会导致瓶颈(关注于唯一/数组索引).例如,如果您有一个强制唯一性的索引,则删除它并在应用程序级别强制唯一性.

  2. 写入问题和复制延迟,如果您使用的是副本集,并且您需要大多数写入问题,这肯定会由于发生和增长的同步延迟而导致问题,通常这是不同问题的副作用,例如,由于#1(大索引)插入花费的时间太长,从而导致同步延迟,从而进一步延迟写入问题.

  3. 未经优化的硬件(假设您托管在云上),您会惊讶地发现,仅通过更改磁盘类型和增加IOPS就可以优化写入性能.这将带来立竿见影的效果.显然是以$为代价的.

  4. 没有提供代码,所以我也会判断,如果它是for循环,那么显然您可以并行化逻辑.

我建议您在无索引集合上测试相同的插入逻辑以确定问题所在,一旦您能够提供更多信息,我很乐意帮助您思考其他问题/解决方案.


编辑:

下面是一个如何避免for循环问题的示例,方法是在使用pymongo的python中使用bulkWrite.

from pymongo import InsertOne, DeleteOne, ReplaceOne
from pymongo.errors import BulkWriteError

docs = [... input documents ]
requests = []
for doc in docs:
    requests.append({
       ReplaceOne({"docId": doc["docID"]}, doc, { upsert: True})
   })

try:
    db.docs.bulk_write(requests, ordered=False)
except BulkWriteError as bwe:
    pprint(bwe.details)

Mongodb相关问答推荐

MongoDB聚合如何对对象数组中的值求和

除非满足某个条件,否则Mongo是否按日期排序?

为什么 mongoose 在 mongodb 中找不到我的数据

我无法在react 中使用 fetch 和express 从数据库中删除数据

如何在 kubernetes 中获取分片 mongodb 的备份

DB 中的引用对象在 GraphQL 查询中返回 null

如何在 Spring-Data-MongoDB 中使用 $facet、$addFields 和 $function

Mongo 删除最后的文件

创建索引需要很长时间

mongodump 是否锁定数据库?

在 Mongo 中存储嵌套类别的最有效方法?

无法连接到远程 mongodb 服务器

将 MongoDB 数据库复制到本地计算机

具有简单密码认证的 MongoDB 副本集

如果我在 MongoDB 上使用 LINQ,为什么会失go 性能?

在 Mongo 中,$near 和 $nearSphere 有什么区别?

有人在 Google App Engine 上try 过 MongoDB 吗?

Mongoose - 获取 _id 列表而不是具有 _id 的对象数组

MongoError:failed to connect to server [localhost:27017] on first connect

在mongoose中创建和查找地理位置