2010-10-29 1 views
1

Я работаю над довольно большим проектом переноса данных, который включает в себя перемещение данных между серверами и различные схемы активной записи. Вся миграция буквально занимает несколько дней.Rails/MySQL ленивая запись на .save (обновления/записи)

Как реализовать кэширующее решение, где мой код миграции Ruby при вызове метода сохранения активной записи записывается в кеш (который затем обновляет базу данных MySQL асинхронно). Память не является ограничением.

Все решения кэширования в Rails, похоже, хорошо работают с загрузкой/запросом, но записи - это то, что я не смог найти.

Это что-то, что легко выполнимо в MySQL путем настройки параметров конфигурации? Или существует ли кэширующее решение для Ruby/Rails, которое существует?

Я смотрел Delayed Job, хотя это не кеширующий слой (и не очевидно, что кто-то использовал его для ленивой записи в базу данных). Я просмотрел таблицы хранения MEMORY в MySQL, но, конечно, они не записываются на диск. Memcached для этого не создан.

Обратите внимание!

ответ

0

Если вы просто хотите перенести данные, почему бы вам не использовать хранимые процедуры непосредственно из базы данных? я уверен, более эффективен, чем использование слоя ActiveRecord

+0

Изменения схемы довольно неприятны и связаны. Я не могу сделать это на уровне SQL чисто. – 2010-10-30 00:17:40

2

Что вы имеете в виду, как я могу быстро вставить данные, не дожидаясь, пока MySQL обновит все его индексы, чтобы моя миграция базы данных не занимала много времени?

Есть два решения, чтобы ускорить вверх вставит базы данных, но они имеют серьезные недостатки, а также:

Я нашел INSERT DELAYED, чтобы помочь. Он запускает ваш запрос и немедленно возвращается. MySQL ставит несколько запросов на несколько секунд и применяет их, когда больше нечего делать. Это отлично подходит для ведения журнала и т. Д.

Недостаток: если ваш db опускается, очередь операторов INSERT теряется.

Другой вариант заключается в следующем:

  • Создать новую схему базы данных - без индексов!
  • Перенос данных, ВСТАВЬТЕ. Это происходит быстрее, потому что MySQL не будет обновлять свои индексы во время INSERTing.
  • Когда все данные переносятся, добавьте свои индексы.

Недостаток здесь в том, что ваши данные могут быть несовместимыми. например ваш источник db имеет повторяющиеся значения, которые вы не хотите в своем целевом db.

Третий вариант, который я бы рекомендовал использовать с использованием чистого SQL вместо ActiveRecord. Если вам нужно перенести 1 миллион записей, ActiveRecord должен выделить 1 миллион раз экземпляр вашей модели ActiveRecord, выполнить запрос и снова удалить объект.

Создание и удаление этих объектов не требует много времени, но если вы делаете это 1 миллион раз, оно складывается.

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

Отрежьте посредника и, если возможно, используйте необработанный SQL. Использование ruby ​​для выполнения SQL не является проблемой, но держите его как можно проще.

Смежные вопросы