Тормозят inserts в MongoDB (Doctrine 2 ODM)
// Февраль 12th, 2013 // Doctrine 2, NoSQL
Недавно на работе столкнулись с такой проблемой. Необходимо было провести импорт множества сущностей из MySQL в MongoDB. Но вот незадача, первые 200 объектов импортировались нормально, а потом скорость начала асимптотически падать стремясь к нулю.
Задача в принципе была простая, даже впилил в консольную команду Symfony 2 прогресс-бар. Кстати хорошая штука. Позволяет прикидывать как скорость процесса, так и общий прогресс. Вот он то мне и помог понять, что что-то не то. Я уже начал грешить на php, запиливать многопоточную обработку, когда коллега сказал, что надо копать не в сторону php как такового, а в сторону MongoDB и Doctrine.
Решилось всё простою. Надо было в конце итреации цикла делать
$dm->clear();
который собственно очищает UnitOfWork, все мета-данные и т.д. Вот кстати его код:
/**
* Clears the UnitOfWork.
*
* @param string $documentName if given, only documents of this type will get detached
*/
public function clear($documentName = null)
{
if ($documentName === null) {
$this->identityMap =
$this->documentIdentifiers =
$this->originalDocumentData =
$this->documentChangeSets =
$this->documentStates =
$this->scheduledForDirtyCheck =
$this->documentInsertions =
$this->documentUpdates =
$this->documentDeletions =
$this->collectionUpdates =
$this->collectionDeletions =
$this->extraUpdates =
$this->parentAssociations =
$this->orphanRemovals = array();
if ($this->commitOrderCalculator !== null) {
$this->commitOrderCalculator->clear();
}
} else {
$visited = array();
foreach ($this->identityMap as $className => $documents) {
if ($className === $documentName) {
foreach ($documents as $document) {
$this->doDetach($document, $visited, true);
}
}
}
}
if ($this->evm->hasListeners(Events::onClear)) {
$this->evm->dispatchEvent(Events::onClear, new Event\OnClearEventArgs($this->dm, $documentName));
}
}
После этого скорость вставок падать перестала, и то что занялбо у меня целые выходные выполнилось за 3 минуты
Related posts
- Уральский вебдев. Конференция Dump в Екатеринбурге. Фотоотчёт.
- Symfony 2.1 Session Handler MongoDB MongoTimestamp Bug
- Баг в igbinary 1.1.1 при сериализации сессий в MongoDB Session Handler
- Глобальные блокировки на MongoDB
- Eventr.com как смесь веб-технологий
- Производительность GridFS
- Пробуем кластерную файловую систему GridFS
- Оживляем Doctrine 2 Document/Entity при получении из кэша
- Потокобезопасные миграции Doctrine 2 / Symfony 2
- Пару слов про Doctrine 2 Identity Map
Смотрите также:
Спасибо!
Если вам помогла статья, или вы хотите поддержать мои исследования и блог - вот лучший способ сделать это:









А зачем сюда доктрина? Простейший скрипт с batchInsert будет еще производительней
Да, Олег. Иногда так и делаем. Но к хорошему быстро привыкаешь
Также не следует забывать, что доктрайн пишет еще и все запросы в лог (Symfony 2).
Да, это если есть серви ‘logger’. Но, можно выключить это для продакшена.