Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/google-app-engine/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PyMongoDB的缓慢升级_Mongodb_Pymongo - Fatal编程技术网

PyMongoDB的缓慢升级

PyMongoDB的缓慢升级,mongodb,pymongo,Mongodb,Pymongo,我试图在macbook air 1.7GHz i7上使用PyMongo向MongoDB插入约8亿条记录,无需多线程,文档结构如下: 我正在读取的记录是以下元组: 用户id、导入日期、导入创意、导入pid、地理id 我正在根据我正在读取的文件中的用户id创建我自己的_id字段 {_id:user_id, 'imp_date':[array of dates], 'imp_creative':[array of numeric ids], 'imp_pid':[array of numeric id

我试图在macbook air 1.7GHz i7上使用PyMongo向MongoDB插入约8亿条记录,无需多线程,文档结构如下:

我正在读取的记录是以下元组:

用户id、导入日期、导入创意、导入pid、地理id

我正在根据我正在读取的文件中的用户id创建我自己的_id字段

{_id:user_id,
'imp_date':[array of dates],
'imp_creative':[array of numeric ids],
'imp_pid':[array of numeric ids],
'geo_id':numeric id}
我使用一个带有$push的upsert来为相应的数组追加日期、创造性id和pid

self.collection.update({'_id':uid},
                       {"$push":{'imp_date':<datevalue>,
                                 'imp_creative':<creative_id>,
                                 'imp_pid':<pid>}},safe=True,upsert=True)
我正在使用一个带有$set的upsert来覆盖地理位置,只关心最近的一次

self.collection.update({'_id':uid},
                       {"$set":{'geo_id':<geo id>}},safe=True,upsert=True)
如果我设置safe=False,我每秒只写1500条记录8000条。我的问题是:我能做些什么来进一步加速(理想情况下是20k/秒或更快)

我找不到关于以下方面的明确建议: -使用多线程插入数据 -碎片 -填充数组我的数组增长非常缓慢,每个文档数组在文件末尾的平均长度为~4 -关闭日志记录


抱歉,如果我遗漏了任何必需的信息,这是我的第一篇帖子。

1-您可以添加索引以加快查找速度,索引将帮助您更快地查找文档,尽管插入速度会较慢,但您也必须更新索引。如果检索阶段的改进补偿了更新索引的额外时间,则这取决于集合中有多少记录、有多少索引以及这些索引有多复杂

然而,在您的例子中,您只使用_id进行查询,因此您无法对索引做更多的操作

2-您是否使用两个连续更新?我是说,一个是$set,一个是$push? 如果这是真的,那么你应该只使用一个:

self.collection.update({'_id':uid},
                       {"$push":{'imp_date':<datevalue>,
                                 'imp_creative':<creative_id>,
                                 'imp_pid':<pid>},
                       "$set":{'geo_id':<geo id>}},
                       safe=True,upsert=True)
3-更新操作是一个可能锁定其他查询的原子操作。如果您要更新的文档不在RAM中,但在磁盘中,mongo必须首先从磁盘获取它,然后更新它。如果您先执行查找操作,但由于该操作是只读操作,因此不会阻塞,则文档肯定位于RAM中,因此更新操作和锁定操作将更快:

self.collection.findOne({'_id':uid})
self.collection.update({'_id':uid},
                       {"$push":{'imp_date':<datevalue>,
                                 'imp_creative':<creative_id>,
                                 'imp_pid':<pid>},
                       "$set":{'geo_id':<geo id>}},
                       safe=True,upsert=True)

4-如果您的文档没有像您所说的那样增长太多,那么就没有必要担心填充因子和重新分配问题。此外,在一些最新版本中,我们记不起是因为2.2还是2.4集合是在默认情况下启用了powerOfTwo选项的情况下创建的。

Enrique在他的回答中提出了一些好的建议。您是否也尝试过将批处理拆分并在两个单独的连接/机器上运行它?我只是做了一个基本的测试,看起来这两个连接并没有让对方慢下来。换句话说,线程可能会对您产生最显著的影响。非常感谢。我按照建议2更改了插入语法,并获得了性能提升。我尝试了建议3,但在尝试多线程时遇到了一些并发性问题,最终导致总体性能降低。目前,我认为我能做的最好的事情是在AWS上使用更好的机器,随着我的机器上DB的增长,碎片性能严重下降,并以大约80M的记录爬行。谢谢你的帮助。