cronjob: Como reindexar apenas o necessário


8

Temos um servidor que possui 5 lojas separadas. Alguns são praticamente inativos. Alguns são ativos diariamente. Para diminuir a carga do servidor. Alteramos o índice de automático para manual. Em seguida, definimos um cronjob a cada 6 horas. I encontrados suficientes exemplos de reindexação todos.

Agora, executamos algo assim:
Shop1 : Shop2 0 0,6,12,18 * * * php -f /shell/indexer.php reindexall
: 0 1,7,13,19 * * * php -f /shell/indexer.php reindexall
e assim por diante, para evitar sobreposição.

No momento, as lojas inativas também reindexam a cada 6 horas, onde nenhuma é necessária. Existe uma maneira de reindexar apenas o necessário com um cronjob?

Ou o que estamos fazendo é errado completamente?

Respostas:


3

O que você deseja é criar um script da CLI do shell e usá-lo para determinar se um índice requer um re-índice.

Dê uma olhada nos scripts na pasta shell (log.php funcionará bem) como um exemplo de como criar esse script.

O script que você criar verificaria o status do índice e somente o indexaria novamente novamente se estiver em um status que exija indexação.

Geralmente, crio meus scripts de shell customizados em uma pasta chamada / scripts, pois não gosto de poluir o shell da pasta principal com meu código personalizado.

Para esse efeito, tenho uma classe abstrata na qual baseamos todos os meus scripts e contém um código que me permite re-indexar facilmente indexadores, se eles precisarem de indexação.

aqui está minha classe abstrata:

/**
 * 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();
    }

}

Em seguida, uma classe que é baseada nisso, que chama um re-índice, depois que algum trabalho foi feito.

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();

Eu tenho que dizer a resposta dada por @Flyingmana é na verdade muito mais esperto do que a minha própria;)
ProxiBlue

6

O que eu sei, o Índice é algo global, portanto, uma reindexa sempre cobre todas as lojas / sites de um Magento.

Mas, Magento tem algumas funcionalidades que você vai gostar. Enquanto "update on Save" faz as atualizações para indexar instantaneamente, a "atualização manual" coloca as mesmas "atualizações" em uma fila, que você pode acionar mais tarde.

Para isso, você precisará escrever seu próprio shell script ou tarefa cron

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

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

Não vou explicar o básico dos modelos de processo, basta dar uma olhada na função indexEvents, pegar as entradas da fila e atualizá-las. Mas tenha cuidado, o Índice de URL pode ser um pouco lento. Mas isso é outro problema.


11
Solução interessante, eu não sabia que os eventos são salvos quando a "atualização manual" é ativada. Isso permitiria indexar apenas os dados alterados.
Andreas von Studnitz

0

Para reindexar os processos, exigimos seus IDs.
Para o magento padrão, existem 9 processos para reindexar, numerados de 1 a 9.

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

Às vezes, existem processos de nossos módulos personalizados que também exigem reindexação. Precisamos adicionar esses IDs à ​​nossa matriz existente de IDs. Para conhecer o ID do processo, passe o mouse sobre cada processo em seu
admin panel-> System-> Index Management

Você receberá uma URL: admin / process / some_id / ...... esse id corresponde ao processo

$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();
   }
}

Isso não responde à minha pergunta sobre como alterar o cronjob. Além disso, isso reindexa tudo. Eu só quero reindexar as partes que foram alteradas.
janw

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();
        }
    }
    ?>

0

Gostei mais da resposta de Amit Bera - mas modifiquei a colocação dos IDs em uma matriz e, o mais importante, arranjei para uma operação mais suave. Se você passar direto pelos números, a nova indexação de uma tabela de índice poderá fazer com que outra se torne inválida. Tabela I_Product do índice do IE, o preço pode fazer com que a tabela simples do produto se torne inválida e precise ser reindexada.

<?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
Para sua informação, seu @jim que não respondeu.
dh47 4/06/2015

0

Verificar status do indexador M1

Execute o comando abaixo no diretório raiz para verificar o status.

php shell/indexer.php --status

Execute o comando abaixo no diretório raiz do indexador de verificação.

php shell/indexer.php info

cronjob: Como reindexar apenas o necessário.

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

Por exemplo: defino a reindexação a cada 6 horas

*_6_*_*_* php -f /home/magento/public_html/shell/indexer.php --reindex catalogsearch_fulltex
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.