Как принудительно использовать индексаторы по расписанию
Этот вопрос некоторое время оставался для меня без ответа, и я хотел бы получить от кого-нибудь окончательный ответ о том, как это работает.
Сценарий:
Запустив Magento 1.14.2.1, я настроил все свои индексаторы на запуск по расписанию, и я запускаю cron Magento, который запускается enterprise_refresh_index
всякий раз, когда что-либо должно быть частично (или полностью?) проиндексировано.
До обновления до этой версии я работал под управлением 1.13.1 и не использовал cron. У меня были установлены указатели чтобы быть на , сохраните , и всякий раз, когда мне нужно было заставить любой из индексаторов работать, я делал это либо через shell/indexer.php
, либо с помощью следующего примера кода:
// Example of indexers passed in:
$indexers = ['catalog_product_flat', 'catalog_category_flat'];
foreach ($indexers as $code) {
$process = Mage::getSingleton('index/indexer')
->getProcessByCode($code)
->reindexEverything();
}
Ранее...
Ранее это прекрасно работало с точки зрения того, что индексаторы запускались немедленно, когда я этого хотел, и различные необходимые изменения относительно быстро распространялись на внешний интерфейс и т. Д.
Очевидно, что мы столкнулись с проблемами взаимоблокировки/блокировки таблиц и индексаторами, конфликтующими друг с другом, когда у нас несколько пользователей-администраторов Одновременно сохраняют продукты и т. Д., Поэтому мы переходим к новой "лучшей практике" использования cron Magento для обработки всего этого по расписанию.
Мои вопросы:
- Как вы заменяете старый стиль принудительной переиндексации продукта (
php shell/indexer.php --reindex catalog_product_flat
) на эквивалентный теперь через запланированное задание cron? Все, что я, кажется, вижу, это то, что вы можете запустить заданиеenterprise_refresh_index
cron, но оно обрабатывает все индексаторы правильно - нет возможности выделить определенные части? - Имеет ли вообще значение необходимость делать это еще раз? Под этим я подразумеваю, что, выполнив эту предыдущую команду, будет ли Magento по-прежнему индексировать только то, что ему нужно, в плоской области продукта каталога, и, выполнив запланированную задачу, он сделает то же самое, но объединит все индексаторы в один? Если это так, то все в порядке - просто это довольно сложно понять.
Предыстория:
Я задал этот вопрос при поддержке Magento EE. Они вернулись к скажите, что это выходит за рамки соглашений о поддержке, но все же получил ответ от одного из разработчиков Magento и ответил мне, сказав, что "изменения в базе данных обнаруживаются с помощью триггеров и создаются записи в журнале изменений". Я понимаю, что отсюда запланированный индексатор решает, что нужно сделать, основываясь на этих записях журнала изменений.
Ранее я предполагал, что если мне понадобится переиндексировать плоские таблицы продуктов (все продукты, все), я бы сделал это из командная строка, как в предыдущем примере. Как мне добиться того же самого сейчас, если он собирается переиндексировать только те, которые, как он знает, должны быть сделаны с помощью журналов изменений? Есть ли способ переиндексировать все плоские данные продукта, не используя все остальные индексаторы с помощью enterprise_refresh_index
?
Я не думаю, что это уместно, но мы используем модуль Aoe_Scheduler, чтобы лучше понять, что делает cron.
Я знаю, что это долго. Пожалуйста, дайте мне знать, если я смогу подвести итог немного лучше. Мне не повезло получить окончательный ответ, и некоторые пользователи-администраторы не уверены, что cron Magento каждый раз эффективно переиндексирует все. Когда делается такое заявление, я обычно переиндексирую все плоские данные продукта из CLI, но я больше не могу этого делать, потому что это вызывает конфликты с запланированным индексатором, и весь ад вырывается на свободу.
2 answers
public function refreshIndex(Mage_Cron_Model_Schedule $schedule)
{
/** @var $helper Enterprise_Index_Helper_Data */
$helper = Mage::helper('enterprise_index');
/** @var $lock Enterprise_Index_Model_Lock */
$lock = Enterprise_Index_Model_Lock::getInstance();
if ($lock->setLock(self::REINDEX_FULL_LOCK)) {
/**
* Workaround for fatals and memory crashes: Invalidating indexers that are in progress
* Successful lock setting is considered that no other full reindex processes are running
*/
$this->_invalidateInProgressIndexers();
$client = Mage::getModel('enterprise_mview/client');
try {
//full re-index
$inactiveIndexes = $this->_getInactiveIndexersByPriority();
$rebuiltIndexes = array();
foreach ($inactiveIndexes as $inactiveIndexer) {
$tableName = (string)$inactiveIndexer->index_table;
$actionName = (string)$inactiveIndexer->action_model->all;
$client->init($tableName);
if ($actionName) {
$client->execute($actionName);
$rebuiltIndexes[] = $tableName;
}
}
//re-index by changelog
$indexers = $helper->getIndexers(true);
foreach ($indexers as $indexerName => $indexerData) {
$indexTable = (string)$indexerData->index_table;
$actionName = (string)$indexerData->action_model->changelog;
$client->init($indexTable);
if (isset($actionName) && !in_array($indexTable, $rebuiltIndexes)) {
$client->execute($actionName);
}
}
} catch (Exception $e) {
$lock->releaseLock(self::REINDEX_FULL_LOCK);
throw $e;
}
$lock->releaseLock(self::REINDEX_FULL_LOCK);
}
return $this;
}
Это выполняется "всегда" при каждом выполнении cron. Он выполняет полную переиндексацию для необходимых индексов и обрабатывает список изменений для тех, которые этого не делают.
Кроме того, вы все еще можете запускать сценарии командной строки, но они не будут учитывать частичный список изменений и будут слепо выполнять полное переиндексацию.
Если вы получаете мертвые блокировки, вам может потребоваться установить для всех ваших индексаторов значение Manual
и настроить альтернативные процессы для перестроения индекса в нерабочее время (когда администраторы прочь). Только Цены на продукты и Состояние запасов должны быть настроены на обновление при сохранении.
Также имейте в виду, что при частичной переиндексации статус в таблице index_process
больше не используется, а рассчитывается из enterprise_mview_metadata
.
Отключение некоторых внутренних модулей, таких как Mage_Rss
, также может помочь повлиять на частоту аннулирования индексов.
Далее чтение:
Кстати, недавно я наткнулся на модуль aoe_eeindexerstats от aoepeople на GitHub - с первого взгляда кажется, что он позволит вам управлять определенными частями индексаторов или целыми индексаторами, которые все охвачены enterprise_refresh_index
. Потенциально это было бы эквивалентно предыдущему процессу, в котором вы могли бы самостоятельно настроить таргетинг на индекс catalog_product_flat
.
Он также должен быть доступен в коде как таковом:
$client = Mage::getModel('enterprise_mview/client'); /* @var $client Enterprise_Mview_Model_Client */
$client->initByTableName($tablename);
$metadata = $client->getMetadata();
$metadata->setInvalidStatus();
$metadata->save();