Мне поручили переносить данные из базы данных MongoDB в базу данных MySQL. (Есть серьезные причины для переноса - так что это нужно сделать).
Коллекция MongoDB:
- Имеет около 110 миллионов документов
- Весит 60 ГБ.
- Имеет индексы для важных свойств
- Выполняется автономный отдельный сервер Windows 2008, который не обслуживает какой-либо производственный трафик.
Программа, которую мы пробовали:
- Экзамен большого экземпляра Amazon EC2 Win2008 с 7,5 гигабайтами оперативной памяти /8 записей файла страницы.
- Консольное приложение С#, которое преобразует данные MongoDB в локальную базу данных MySQL.
Мы собираем 1K документов за раз в памяти от MongoDB, выполняем необходимую обработку и затем сохраняем их в MySQL db, делая периодические записи по 500 за раз.
Проблема, с которой мы сталкиваемся, заключается в том, что каждый 2.5 M docs, сервер задыхается, и Mongo реагирует очень медленно - сглаживает операцию извлечения данных приложения (Free RAM переходит на время обработки документов 1M)
Мы медленно продвигаемся вперед, убивая процесс mongod и начинаем его снова каждые 2.5M записи, когда он падает, но я уверен, что мы делаем что-то неправильно.
Вопрос:
Должен ли я переместить Mongo Server на большой экземпляр на базе Linux и MySQL на Amazon RDS для этого и переписать приложение преобразования в PHP? Помогло ли это?
Поэтому мы решили сохранить все это на одной коробке была задержка проблема наличия различных серверов на разных коробках - но я думаю, что это спорный вопрос, если коробка засорение.
Какие еще вещи я могу попробовать/советы, которые я могу использовать?
Спасибо, что прочел это!
- Обновление 01 -
Он был приблизительно 6 часов с момента перезапуска моего приложения и сделал следующее изменение:
- Увеличенное количество просмотров Mongo Read от 1000 до 10 000 записей за раз. Пропустите (10K).limit(10K)
- Удалены все индексы из целевой базы данных MySQL.
- Увеличен размер страницы Windows с 4 до 8 гигов.
Моя память потребляет 100%, но приложение работает. (Последний раз он прохрипел через 52 минуты). Mongo - 6,8 гигабайта оперативной памяти, MySQL - 450 мегабайт и приложение конвертера - 400 мегабайт (приблизительные значения).
Обработано 11M записей до сих пор - но скорость снизилась до 370 записей/сек с примерно 500 записей/сек.
Следующие шаги состоят в том, чтобы изолировать как серверы Mongo, так и MySQL для разделения ящиков и - сохранить все их в той же зоне доступности Amazon, чтобы минимизировать время ожидания.
- Обновить 02 -
Мы внесли некоторые изменения в код, чтобы использовать Mongo Cursor и автоматически увеличивать его автоматически против использования .skip(). limt(). Это значительно ускорило процесс, и мы делали 1250 записей в секунду от 300 нечетных ранее. Тем не менее, приложение начало потреблять слишком много памяти и закончилось бы из ОЗУ и аварийным завершением, и его необходимо было перезапустить после каждых двух записей.
Мы использовали этот фрагмент кода:
var docs = db[collectionName].Find(query);
docs.SetBatchSize(numOfResultsToFetchAtATime);
foreach (var d in docs) {
// do processing
}
Итак, что это значит, это выборка "numOfResultsToFetchAtATime" за раз, но затем автоматически выполняется в цикле и выбирает следующий набор записей. Монго позаботится об этой прогрессии с помощью курсора, и, следовательно, это намного быстрее.
Однако мы все еще не смогли успешно перенести это. Отправьте мой ответ с кодом, когда это произойдет правильно.
- Обновление 03: Успех -
Наконец, мы использовали предложение @scarpacci о выполнении mongoexport. Помните, что очень важно, чтобы mongodb находился в окне Linux, а не в окне окна.
Сначала мы попробовали сделать mongoexport из Windows на локальном MongoDB и независимо от того, что мы пробовали, он потерпит неудачу в разных местах для одной большой коллекции (13Gigs +)
Наконец, я восстановил БД на Linux-боксе, и mongoexport работал как шарм.
Нет конвертера Json → MySQL, так что многое нам нужно было сделать. С небольшой настройкой мы смогли использовать наше предыдущее приложение и прочитать файлы и напрямую написать MySQL. Это было быстро и относительно безошибочно.
У нас были некоторые проблемы с большими файлами, но с ним удалось разбить 13-гигабайтный файл на 500 мегабайтных файлов, и мы смогли успешно перенести все данные в MySQL.
Большое спасибо всем за то, что они проводят время, помогая нам. Надеюсь, что это объяснение поможет кому-то в будущем.