OperationFailure: ошибка базы данных при многопоточности в MongoEngine / PyMongo - PullRequest
5 голосов
/ 25 марта 2012

У меня есть функция, которая будет считывать данные с веб-сайта, обрабатывать их, а затем загружать в MongoDB. Когда я запускаю это без многопоточности, оно работает нормально, но как только я настраиваю задачи сельдерея, которые просто вызывают эту функцию, я часто получаю следующую ошибку: «OperationFailure: ошибка базы данных: неавторизованный db: тип блокировки dbname: -1»

Это несколько странно, потому что, если я запускаю версию без сельдерея на нескольких терминалах, я вообще не получаю эту ошибку.

Я подозреваю, что это как-то связано с отсутствием открытого соединения с Mongo, хотя в моем коде я открываю его прямо перед каждым вызовом Mongo.

Ниже приведено точное исключение:

Task twitter[a974bfcc-d6ca-4baf-b36f-cae9143ce2d9] raised exception: OperationFailure(u'database error: unauthorized db:data lock type:-1 client:68.193.49.9',)
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/celery/execute/trace.py", line 36, in trace
  return cls(states.SUCCESS, retval=fun(*args, **kwargs))
File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/celery/app/task/__init__.py", line 232, in __call__
  return self.run(*args, **kwargs)
File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/celery/app/__init__.py", line 172, in run
  return fun(*args, **kwargs)
File "/djangoblog/network/tasks.py", line 40, in twitter
  n_twitter.GetTweetsTwitter(user)
File "/djangoblog/network/twitter.py", line 255, in GetTweetsTwitter
  id = SaveTweet(user, network, tweet)
File "/djangoblog/network/twitter.py", line 150, in SaveTweet
  if mmo.Moment.objects(user=user.id,source_id=id,network=network.id).count() == 0:
File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/mongoengine/queryset.py", line 933, in count
  return self._cursor.count(with_limit_and_skip=True)
File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/mongoengine/queryset.py", line 563, in _cursor
  self._cursor_obj = self._collection.find(self._query,
File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/mongoengine/queryset.py", line 493, in _collection
  if self._collection_obj.name not in db.collection_names():
File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/pymongo/database.py", line 361, in collection_names
  names = [r["name"] for r in results]
File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/pymongo/cursor.py", line 703, in next
  if len(self.__data) or self._refresh():
File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/pymongo/cursor.py", line 666, in _refresh
  self.__uuid_subtype))
File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/pymongo/cursor.py", line 628, in __send_message self.__tz_aware)
File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/pymongo/helpers.py", line 101, in _unpack_response error_object["$err"])
OperationFailure: database error: unauthorized db:data lock type:-1 client:68.193.49.9

Извините за форматирование, но если вы посмотрите на строку, начинающуюся с mmo.Moment, соединение открывается прямо перед его вызовом.

Проведя небольшое исследование, похоже, что это как-то связано с тем, как обрабатывается многопоточность в PyMongo - http://api.mongodb.org/python/1.5.1/faq.html#how-does-connection-pooling-work-in-pymongo - Возможно, мне придется начать закрывать соединения, но я ожидаю, что MongoEngine будет делать это ..

1 Ответ

2 голосов
/ 26 марта 2012

Вероятно, это связано с тем, что вы не вызываете db.authenticate () при запуске нового соединения и использовании аутентификации на MongoDB.

Что касается закрытия потоков, я бы порекомендовал убедиться, что вы используете пул соединений и позволяете драйверу управлять пулами (вызов close () или подобного вручную может привести к большим трудностям).

Для получения дополнительной информации см. примечание в документации pymongo об использовании authenticate () в многопоточной среде.

...