cronjob: как переиндексировать только то, что нужно

8

У нас есть сервер, на котором есть 5 магазинов. Некоторые практически неактивны. Некоторые из них ежедневно активны. Уменьшить нагрузку на сервер. Мы изменили индекс с автоматического на ручной. Затем мы устанавливаем cronjob каждые 6 часов. Я нашел достаточно примеров из переиндексации всех.

Теперь мы запускаем что-то вроде этого:
Shop1: 0 0,6,12,18 * * * php -f /shell/indexer.php reindexall
Shop2: 0 1,7,13,19 * * * php -f /shell/indexer.php reindexall
и так далее, чтобы избежать дублирования.

Прямо сейчас неактивные магазины также переиндексируют каждые 6 часов, где они не нужны. Есть ли способ только переиндексировать то, что нужно с помощью cronjob?

Или мы вообще не правы?

janw
источник

Ответы:

3

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

Взгляните на сценарии в папке оболочки (log.php подойдет) в качестве примера того, как создать такой сценарий.

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

Обычно я создаю свои собственные сценарии оболочки в папке / scripts, так как я не люблю загрязнять оболочку основной папки своим пользовательским кодом.

Для этого у меня есть абстрактный класс, на котором я основываю все свои скрипты, и он содержит код, который позволяет мне легко переиндексировать индексаторы, если они требуют индексации.

вот мой абстрактный класс:

/**
 * Abstracted functions for scripts
 *
 * @category    ProxiBlue
 * @package     Scripts
 * @author  Lucas van Staden (sales@proxiblue.com.au)
 * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
 *
 */
require_once dirname(__FILE__) . '/../shell/abstract.php';

class Mage_Shell_Scripts_Abstract extends Mage_Shell_Abstract {

    public $_doReindexFlag = false;

    public function run() {

        die('Please implement a run function inyour script');

    }
    /**
     * Get the category model
     * @return Object
     */
    public function getCatalogModel() {
        return Mage::getModel('catalog/category');
    }

    /**
     * Reindex given indexers.
     * Tests if indexer actually needs re-index, and is not in manual state before it does index.
     * 
     * @param array $reIndex 
     */
    public function reindex(array $reIndex) {

        foreach ($reIndex as $indexerId) {
            $process = $this->_getIndexer()->getProcessByCode($indexerId);
            if ($process->getStatus() == Mage_Index_Model_Process::STATUS_REQUIRE_REINDEX && $process->getMode() != Mage_Index_Model_Process::MODE_MANUAL) {
                try {
                    echo "Reindexing: " . $process->getIndexerCode();
                    $process->reindexEverything();
                } catch (Exception $e) {
                    mage::logException("{$indexer} Indexer had issues. {$e->getMessage()}");
                }
            }
        }
    }

    /**
     * Get Indexer instance
     *
     * @return Mage_Index_Model_Indexer
     */
    private function _getIndexer() {
        return Mage::getSingleton('index/indexer');
    }

    /**
     * Returns a list of cache types.
     * @return void
     */
    public function getInvalidateCache() {
        $invalidTypes = $this->_getInvalidatedTypes();
        $result = array();
        foreach($invalidTypes as $cache) {
            if ($cache->status == 1) {
                $result[] = $cache;
            }    
        }
        return $result;
    }

    /**
     * Gets a list of invalidated cache types that should be refreshed.
     * @return array Array of invalidated types.
     */
    private function _getInvalidatedTypes() {
        return Mage::getModel('core/cache')->getInvalidatedTypes();
        //return $this->_getCacheTypes();
    }

    /**
     * Gets Magento cache types.
     * @return
     */
    private function _getCacheTypes() {
        //return Mage::helper('core')->getCacheTypes();
        return Mage::getModel('core/cache')->getTypes();
    }

}

Затем класс, основанный на этом, который вызывает переиндексацию после некоторой работы.

require_once dirname(__FILE__) . '/abstract.php';

class Mage_Shell_setCategoryStatus extends Mage_Shell_Scripts_Abstract {

    public $_doReindexFlag = true;
    public function run() {

        /** code stripped out as not warrented for this answer **/

        if ($this->_doReindexFlag) {
            $this->reindex(array('catalog_product_flat',
                'catalog_category_flat',
                'catalog_category_product',
                'cataloginventory_stock',
                'catalogsearch_fulltext',
            ));
        }
    }

}

$shell = new Mage_Shell_setCategoryStatus();
$shell->run();
ProxiBlue
источник
Я должен сказать, что ответ, данный @Flyingmana, на самом деле намного умнее моего собственного;)
ProxiBlue
6

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

Но у Magento есть некоторые функции, которые вам понравятся. В то время как «обновление при сохранении» выполняет обновления для индексации мгновенно, «ручное обновление» помещает те же «обновления» в очередь, которую вы можете запустить позже.

Для этого вам нужно написать собственный скрипт или задание cron.

    $pCollection = Mage::getSingleton('index/indexer')->getProcessesCollection();

    foreach ($pCollection as $process) {
        $process->indexEvents();
    }

Я не буду объяснять основы моделей процессов, просто взгляну на функцию indexEvents, она берет записи в очереди и обновляет их. Но будьте осторожны, индекс URL может быть немного медленным. Но это еще одна проблема.

Flyingmana
источник
1
Интересное решение, я не знал, что события сохраняются при активации «ручного обновления». Это позволило бы индексировать только измененные данные.
Андреас фон Студниц
0

Для переиндексации процессов нам нужны их идентификаторы.
Для magento по умолчанию существует 9 процессов для переиндексации, пронумерованных от 1 до 9.

$ids = array(1,2,3,4,5,6,7,8,9);

Иногда существуют процессы из наших пользовательских модулей, которые также требуют переиндексации. Нам нужно добавить эти идентификаторы в существующий массив идентификаторов. Чтобы узнать идентификатор процесса, просто наведите указатель мыши на каждый процесс в вашем
admin panel-> System-> Index Management

Вы получите URL: admin / process / some_id / ...... этот идентификатор соответствует процессу

$ids = array(1,2,3,4,5,6,7,8,9,390,391,478);
foreach($ids as $id)
{
   //load each process through its id
   try
   {
      $process = Mage::getModel('index/process')->load($id);
      $process->reindexAll();
      echo "Indexing for Process ID # ".$id." Done<br />";
   }
   catch(Exception $e)
   {
      echo $e->getMessage();
   }
}
Дипак Малла
источник
Это не отвечает на мой вопрос, как изменить cronjob. Также это переиндексирует все. Я только хочу переиндексировать части, которые были изменены.
Янв
0
<?php
// this loops through all indexes and processes those that say they require reindexing

include_once '../app/Mage.php';

$mageRunCode = isset ( $_SERVER ['MAGE_RUN_CODE'] ) ? $_SERVER ['MAGE_RUN_CODE'] : '';
$mageRunType = isset ( $_SERVER ['MAGE_RUN_TYPE'] ) ? $_SERVER ['MAGE_RUN_TYPE'] : 'store';

    $app = Mage::app ( $mageRunCode, $mageRunType );
    for($i=3; $i<=9; $i++){
        $process = Mage::getSingleton('index/indexer')->getProcessById($i);
        $state = $process->getStatus();
    //    echo '<pre>'.$process->getData('indexer_code').': '.htmlentities(print_r($process->getStatus(),true)).'</pre>';
        if($process->getStatus() == 'require_reindex'){
            $process->reindexEverything();
        }
    }
    ?>
jrossi
источник
0

Мне больше всего понравился ответ Амит Бера - но он изменил размещение идентификаторов в массиве и, что наиболее важно, организовал более плавную работу. Если вы пробежитесь по номерам, переиндексируя одну индексную таблицу, это может привести к тому, что другая станет недействительной. IE Index product_flat table, тогда цена может привести к тому, что плоский продукт станет недействительным и потребует повторной индексации.

<?php
// this loops through all indexes and processes those that say they require reindexing

include_once 'app/Mage.php';

$mageRunCode = isset ( $_SERVER ['MAGE_RUN_CODE'] ) ? $_SERVER ['MAGE_RUN_CODE'] : '';
$mageRunType = isset ( $_SERVER ['MAGE_RUN_TYPE'] ) ? $_SERVER ['MAGE_RUN_TYPE'] : 'store';

$app = Mage::app ( $mageRunCode, $mageRunType );

$ids = array(13,9,8,7,6,1,2,3,5,4);

foreach($ids as $id){
  $process = Mage::getSingleton('index/indexer')->getProcessById($id);
  $state = $process->getStatus();
//      echo '<pre>'.$process->getData('indexer_code').': '.htmlentities(print_r($process->getStatus(),true)).'</pre>';
  if($process->getStatus() == 'require_reindex'){
    $process->reindexEverything();
  }
}
Дэн Таппер
источник
2
К вашему сведению, @jim, который ответил не так.
dh47
0

M1 проверить статус индексатора

Запустите следующую команду в корневом каталоге для проверки статуса.

php shell/indexer.php --status

Запустите следующую команду в корневом каталоге для проверки индексатора.

php shell/indexer.php info

cronjob: Как переиндексировать только то, что нужно.

Time php -f {magento file path}/shell/indexer.php --reindex {set indexer}

Например: я устанавливаю реиндекс каждые 6 часов

*_6_*_*_* php -f /home/magento/public_html/shell/indexer.php --reindex catalogsearch_fulltex
Бахаруни Асиф
источник