Pymongo 3.0.2比2.8.1慢

时间:2015-05-19 19:24:55

标签: python performance mongodb pymongo

我在MongoDB上运行一个简单的Django应用程序,最近升级到PyMongo 3.0.2 - 但运行速度非常慢。如果我降级到PyMongo 2.8.1或2.7.2,它会再次加速。 MongoDB 3和2.6都会发生这种情况,所以我认为基本的东西已经发生了变化。根据更改日志,PyMongo 3实际上应该加速很多,我找不到任何会导致性能下降的明显变化。我在SO或Google上找不到任何相关问题。这是在Django 1.6.4和Python 2.7.5上。

很难建立一个这样的代码示例,但是我们使用的是单个MongoDB实例(没有分片,没有远程主机),并且在我们使用mongo_client的每个方法中,我们调用{ {1}}在方法的最后。如果我们不断关闭连接,是否有一些新的连接重新打开行为可能会减慢客户端的速度?示例方法如下:

close()

更新1:

根据建议,我使用 from pymongo import MongoClient mongo_client = MongoClient() collection = mongo_client[self._db_prefix + 'assessment']['Assessment'] if collection.find({'itemIds': str(item_id)}).count() != 0: raise errors.IllegalState('this Item is being used in one or more Assessments') collection = mongo_client[self._db_prefix + 'assessment']['Item'] item_map = collection.find_one({'_id': ObjectId(item_id.get_identifier())}) if item_map is None: raise errors.NotFound() objects.Item(item_map, db_prefix=self._db_prefix, runtime=self._runtime)._delete() delete_result = collection.delete_one({'_id': ObjectId(item_id.get_identifier())}) if delete_result.deleted_count == 0: raise errors.NotFound() mongo_client.close() 库创建了专用负载测试。使用PyMongo 3.0.2:

timeit

实际上会抛出错误:

timeit.timeit('MongoClient()["test_blah"]["blah"].insert_one({"foo":"bar"})', number=10000, setup="from pymongo import MongoClient")

然后我降级到PyMongo 2.8.1:

  File "~/Documents/virtual_environments/assessments/lib/python2.7/site-packages/pymongo/pool.py", line 58, in _raise_connection_failure
raise AutoReconnect(msg)
AutoReconnect: localhost:27017: [Errno 49] Can't assign requested address

在python shell中运行相同的命令:

pip install pymongo==2.8.1

这次它实际上已经结束......所以看起来新的timeit.timeit('MongoClient()["test_blah"]["blah"].insert({"foo":"bar"})', number=10000, setup="from pymongo import MongoClient") 8.372910976409912 方法做了不同的事情,它没有关闭连接?

更新2(使用解决方案):

伯尼的回答帮助我们指明了正确的方向,以及SO question。除了使用单个insert_one之外,我们的问题是我们在每个方法结束时关闭了连接。下面的示例MongoClient()(PyMongo 3.0.2):

timeit

手动关闭客户端是性能杀手......慢1000倍。也许是由于监控线程缓慢关闭引起的,伯尼提到了什么?

1 个答案:

答案 0 :(得分:2)

我认为你看到的问题是由于MongoClient产生了一个后台监控线程。这是PyMongo 3.0中的新功能,与PyMongo 2.x中MongoReplicaSetClient的行为相匹配。你应该能够通过只产生一个MongoClient实例来加快速度(这是使用MongoClient的首选方法)。

>>> import timeit
>>> timeit.timeit('client["test_blah"]["blah"].insert_one({"foo":"bar"})', number=10000, setup="from pymongo import MongoClient; client = MongoClient()")
2.2610740661621094
>>> import pymongo
>>> pymongo.version
'3.0.2'

>>> timeit.timeit('client["test_blah"]["blah"].insert({"foo":"bar"})', number=10000, setup="from pymongo import MongoClient; client = MongoClient()")
2.3010458946228027
>>> import pymongo
>>> pymongo.version
'2.8.1'

我还认为监视器线程关闭时间太长,并且正在寻找修复程序。