Подтвердить что ты не робот

Rails, как перенести большой объем данных?

У меня есть приложение rails 3, работающее на более старой версии spree (корзина с открытым исходным кодом). Я сейчас обновляю его до последней версии. Это требует, чтобы я запускал многочисленные миграции в базе данных для совместимости с последней версией. Однако текущая база данных приложений примерно составляет около 300 МБ и для запуска миграции на моем локальном компьютере (mac os x 10.7, 4gb ram, 2.4GHz Core 2 Duo) требуется более 3 дней.

Я смог уменьшить это время до 16 часов, используя экземпляр ecazon ec2 (экземпляры On-Demand High-I/O, Quadruple Extra Large). Но еще 16 часов все еще долго, так как мне придется снять сайт, чтобы выполнить это обновление.

Есть ли у кого-нибудь другие предложения, чтобы снизить это время? Или какие-либо советы по увеличению производительности миграции?

FYI: использование ruby ​​1.9.2 и ubuntu на экземпляре amazon.

4b9b3361

Ответ 1

  • Отбрасывание индексов заранее и добавление их снова после этого - хорошая идея.

  • Также заменяем .where(...). Каждый с .find_each и, возможно, добавление транзакций может помочь, как уже упоминалось.

  • Замените .save! с .save(: validate = > false), потому что во время миграции вы не получаете случайных входов от пользователей, вы должны делать хорошо известные обновления, а валидации составляют большую часть времени выполнения. Или использование .update_attribute также пропустит проверки, в которых вы обновляете только одно поле.

  • По возможности используйте меньшее количество объектов AR в цикле. Создание и последующий сбор мусора требует процессорного времени и использует больше памяти.

Ответ 2

Возможно, вы уже это подумали:

  • Скажите db не беспокоиться о том, чтобы все было на диске (без WAL, no fsync и т.д.), теперь у вас есть память db, которая должна иметь очень большое значение. (Поскольку вы взяли db offline, вы можете просто восстановить из резервной копии в маловероятном случае потери мощности или аналогичного). Включите fsync/WAL, когда вы закончите.

  • Скорее всего, вы сможете выполнить некоторые миграции, прежде чем использовать db в автономном режиме. Протестируйте это, конечно. Эта большая миграция пользователей вполне может быть реализована вживую. Убедитесь, что вы не делаете этого в транзакции, вам может потребоваться немного изменить их.

Я не знаком с вашей конкретной ситуацией, но я уверен, что есть еще больше вещей, которые вы можете сделать, если этого недостаточно.

Ответ 3

Этот ответ больше касается подхода, чем конкретного технического решения. Если ваши основные критерии - минимальное время простоя (и целостность данных, конечно), то лучшей стратегией для этого является использование рельсов!

Вместо этого вы можете выполнить всю тяжелую работу и оставить только критическую миграцию данных в реальном времени (я использую "миграцию" в смысле не-рельсов здесь) в качестве шага во время переключения.

Итак, у вас есть текущее приложение с его схемой db и производственными данными. Вы также (предположительно) имеете версию разработки приложения, основанную на обновленных драгоценных камнях с новой схемой db, но без данных. Все, что вам нужно сделать, это выяснить способ преобразования данных между ними. Это можно сделать несколькими способами, например, используя чистые SQL и временные таблицы, где это необходимо, или с использованием SQL и ruby ​​для создания операторов вставки. Эти шаги можно разделить так, чтобы данные, которые являются довольно "статическими" (справочные таблицы, продукты и т.д.), Могут быть загружены в db раньше времени, а данные, которые изменяются чаще (пользователи, сообщения, заказы и т.д.), Могут быть выполненных на этапе миграции.

Вы должны script выполнить эту процедуру экспорта-преобразования-импорта, чтобы она была повторяемой и провела тесты/проверки после ее завершения, чтобы обеспечить целостность данных. Если вы можете организовать доступ к новой производственной базе данных во время переключения, тогда вам будет легко запустить script против нее. Если вы ограничены процессом выпуска (например, webistrano), вам может потребоваться перевести его в рельсовую миграцию, но вы можете запустить raw SQL с помощью execute.

Ответ 5

Несчастливо, только что разобщенное решение. То, что на самом деле медленнее в рельсах, - это модели activerecord. Они не подходят для таких задач.

Если вам нужна быстрая миграция, вам придется сделать это в sql.

Существует другой подход. Но вам придется переписывать большую часть миграций...