Как принудительно использовать индексаторы по расписанию


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

Сценарий:

Запустив 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 для обработки всего этого по расписанию.

Мои вопросы:

  1. Как вы заменяете старый стиль принудительной переиндексации продукта (php shell/indexer.php --reindex catalog_product_flat) на эквивалентный теперь через запланированное задание cron? Все, что я, кажется, вижу, это то, что вы можете запустить задание enterprise_refresh_index cron, но оно обрабатывает все индексаторы правильно - нет возможности выделить определенные части?
  2. Имеет ли вообще значение необходимость делать это еще раз? Под этим я подразумеваю, что, выполнив эту предыдущую команду, будет ли Magento по-прежнему индексировать только то, что ему нужно, в плоской области продукта каталога, и, выполнив запланированную задачу, он сделает то же самое, но объединит все индексаторы в один? Если это так, то все в порядке - просто это довольно сложно понять.

Предыстория:

Я задал этот вопрос при поддержке Magento EE. Они вернулись к скажите, что это выходит за рамки соглашений о поддержке, но все же получил ответ от одного из разработчиков Magento и ответил мне, сказав, что "изменения в базе данных обнаруживаются с помощью триггеров и создаются записи в журнале изменений". Я понимаю, что отсюда запланированный индексатор решает, что нужно сделать, основываясь на этих записях журнала изменений.

Ранее я предполагал, что если мне понадобится переиндексировать плоские таблицы продуктов (все продукты, все), я бы сделал это из командная строка, как в предыдущем примере. Как мне добиться того же самого сейчас, если он собирается переиндексировать только те, которые, как он знает, должны быть сделаны с помощью журналов изменений? Есть ли способ переиндексировать все плоские данные продукта, не используя все остальные индексаторы с помощью enterprise_refresh_index?

Я не думаю, что это уместно, но мы используем модуль Aoe_Scheduler, чтобы лучше понять, что делает cron.


Я знаю, что это долго. Пожалуйста, дайте мне знать, если я смогу подвести итог немного лучше. Мне не повезло получить окончательный ответ, и некоторые пользователи-администраторы не уверены, что cron Magento каждый раз эффективно переиндексирует все. Когда делается такое заявление, я обычно переиндексирую все плоские данные продукта из CLI, но я больше не могу этого делать, потому что это вызывает конфликты с запланированным индексатором, и весь ад вырывается на свободу.

Author: Robbie Averill, 2015-11-03

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, также может помочь повлиять на частоту аннулирования индексов.

Далее чтение:

 2
Author: B00MER, 2015-11-09 00:24:44

Кстати, недавно я наткнулся на модуль 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();
 4
Author: Robbie Averill, 2018-10-04 16:09:28