Импорт/обновление большого количества материалов по Cron без использования Batch API и Drupal Queue

Главные вкладки

Аватар пользователя Koreychenko Koreychenko 20 июня 2012 в 11:32

Часто бывает необходимо импортировать или обновить большое количество материалов на сайте. Чтобы все модули отработали правильно, необходимо сохранять ноды с помощью функций node_submit и node_save.
К сожалению, в этом случае, время выполнения скрипта будет довольно большим по сравнению с непосредственной записью в базу данных.

Для того, чтобы разбить процесс обработки данных на части, и чтобы скрипт не вылетал по тайм-ауту придумали Drupal Batch API. Великолепная идея, но у нее есть один минус - оно требует присутствия человека. Т.е. операцию необходимо запустить из браузера, и браузер должен быть открыт во время всего процесса выполнения. Что же делать, если нам нужна обработка по Cron?

Самый простой способ без использования каких-либо наворотов.

1. Создаете модуль, который импортирует данные (например из файла на хостинге) во временную таблицу базы данных. Запись в базу даже большого количества данных занимает небольшое время.

2. В модуле по hook_cron вызываете функцию импорта/обновления, после чего удаляете обработанные строки временной базы данных.

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

Кто знает более простое решение - милости прошу в комменты.

Оригинал живет здесь

Комментарии

Аватар пользователя Koreychenko Koreychenko 20 июня 2012 в 12:18

"xxandeadxx" wrote:
drush

Не совсем понял чем он нам здесь поможет?

"<a href="mailto:sas@drupal.org">sas@drupal.org</a>" wrote:
Ну есть же  elysia_cron

Что-то я про него забыл. Действительно решение, спасибо.

Аватар пользователя Sun-fire Sun-fire 20 июня 2012 в 12:38

Писал решение для импорта/обновления номенклатур в интернет-магазине. На данный момент в базе около 38К номенклатур, в ближайшее время количество должно вырасти до 70-80К. (Поскольку используется Drupal Commerce, то сущностей в два раза больше)

Задачу решал применением темповых таблиц, и Queue API. Поскольку нужно было обеспечить актуальность данных с интервалом 10 минут, было принято решение использовать две очереди выгрузки: первая очередь - обновление того, что изменилось с момента последней выгрузки, и общая очередь, которая проводит обновление всей базы, и корректирует возможные сбои в актуальности и целосности данных, которые могли возникнуть на этапе "быстрого" обновления.

В итоге на сайте поддерживается актуальность товаров с интервалом в 10 минут, полная очередь коррекции занимает 6-8 часов (что само по себе не критично). Нагрузка на процессор и память получается минимальная, поскольку выгрузка "розмазана" по времени.

Насчет Elysia cron - в моем случае этот модуль не пригодился, поскольку он не умеет работать с queue cron.

Аватар пользователя Koreychenko Koreychenko 20 июня 2012 в 12:44

"Sun-fire" wrote:
Писал решение для импорта/обновления номенклатур в интернет-магазине.

Подумалось. Для интернет-магазина я бы разделил операции обновления товаров (например цены и количества) и создания новых товаров.

Обновление цены можно делать непосредственно работая с базой, без Drupal API, это будет очень быстро.

Создание и удаление материалов делать уже через очереди.

"Sun-fire" wrote:
Насчет Elysia cron - в моем случае этот модуль не пригодился, поскольку он не умеет работать с queue cron.

По сути Elysia Cron + тот способ, который я написал - это и будет Drupal Queue. Решение-то аналогичное абсолютно.

Аватар пользователя Sun-fire Sun-fire 20 июня 2012 в 14:37

"Koreychenko" wrote:
Обновление цены можно делать непосредственно работая с базой, без Drupal API, это будет очень быстро.

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

"Koreychenko" wrote:
По сути Elysia Cron + тот способ, который я написал - это и будет Drupal Queue. Решение-то аналогичное абсолютно.

В моем случае решил не выдумывать велосипед, а делать штатными методами.

Аватар пользователя Ch Ch 20 июня 2012 в 16:04

"Sun-fire" wrote:
Писал решение для импорта/обновления номенклатур в интернет-магазине
Обновлялись сущности целиком или только некоторые поля отдельно?

Аватар пользователя Sun-fire Sun-fire 20 июня 2012 в 16:56

"Ch" wrote:
Обновлялись сущности целиком или только некоторые поля отдельно?

Первая версия модуля предусматривала изменения на уровне полей. Во второй (текущей) версии обновляются сущности целиком. Это позволяет отслеживать что, когда, и как изменялось (цены, наличие, и т. п.)

Аватар пользователя Koreychenko Koreychenko 20 июня 2012 в 17:45

"Sun-fire" wrote:
В моем случае решил не выдумывать велосипед, а делать штатными методами.

Если речь про Drupal 6, то в нем Queue такая же "нештатная" вещь, как и Elysia Cron Wink Это в семерке он в ядре.

"Sun-fire" wrote:
Первая версия модуля предусматривала изменения на уровне полей. Во второй (текущей) версии обновляются сущности целиком. Это позволяет отслеживать что, когда, и как изменялось (цены, наличие, и т. п.)

Ну, у вас здесь задача чуть более интересная, нежели у меня.

Аватар пользователя Ch Ch 20 июня 2012 в 19:23

"Sun-fire" wrote:
Это позволяет отслеживать что, когда, и как изменялось (цены, наличие, и т. п.)

Каким образом? Ревизии у сущностей?

Аватар пользователя Sun-fire Sun-fire 20 июня 2012 в 19:29

"Koreychenko" wrote:
Если речь про Drupal 6, то в нем Queue такая же "нештатная" вещь, как и Elysia Cron

Упс Smile Сорри, не заметил, что речь идет о Drupal 6, там и в правду Queue в ядре нет.

В тему планировщиков - кроме Elysia Cron на глаза попадался также модуль Ultimate Cron. Он вроде как даже умеет работать с Queue cron, но содержит в депенденсах Background Process и Progress. Есть версии как для 6, так и для 7 ветки. Толком его не тестировал, поэтому что за зверь - не скажу.

Аватар пользователя Sun-fire Sun-fire 20 июня 2012 в 19:39

"Ch" wrote:
Каким образом? Ревизии у сущностей?

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

Аватар пользователя Koreychenko Koreychenko 21 июня 2012 в 19:04

Попробуйте выгрузку из 1C фидсами обработать Wink Это какой-то хитрый XML, с 6 таблицами, которые все связаны друг с другом через...... артикул Wink

Короче, Feeds замечательный инструмент, но лишь для конкретных случаев (RSS парсить).

Аватар пользователя Sun-fire Sun-fire 21 июня 2012 в 22:00

Feeds штука хорошая. Он не только RSS, но и XML нормально разбирает. Об CSV вообще молчу. Но как и все универсальные средства не лишен недостатков.

Самый основной его недостаток, с которым мне пришлось столкнуться - это его относительная медлительность. Если нужно выгрузить данные на сайт, и изредка их приводить в соответствие - Feeds именно то, что нужно. Если нужно поддерживать актуальность при большом объеме данных - то этот модуль уже мало чем поможет. А так - штука очень и очень полезная.

Аватар пользователя multpix multpix 21 июня 2012 в 22:23

"Koreychenko" wrote:
Короче, Feeds замечательный инструмент, но лишь для конкретных случаев (RSS парсить).

feed + feeds_xpathparser буквально сегодня радостно разобрал XMLочку))

попробуйте если незнакомо - в D7 2к позиций залетело в фоне без вопросов, не много но всеже))

Аватар пользователя rimen rimen 24 июня 2012 в 14:07

Drupal Queue - порт 7-ки под 6-ку.
Задачи добавляете по hook_cron , а выполняете запуском отдельного файла аля drupal_queue_run.php c содержимым

<?php
include_once './includes/bootstrap.inc';
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
if (
function_exists('drupal_queue_cron_run')) {
  
drupal_queue_cron_run();
}
?>

Запуск вынести в cron_tab на нужные промежутки времени.

Аватар пользователя evolved evolved 17 января 2013 в 16:26

"Sun-fire" wrote:

Писал решение для импорта/обновления номенклатур в интернет-магазине. На данный момент в базе около 38К номенклатур, в ближайшее время количество должно вырасти до 70-80К. (Поскольку используется Drupal Commerce, то сущностей в два раза больше)

А я чето психанул и написал скрипт на Perl, который пинается кроном каждые 15 минут