cronjob: comment réindexer uniquement ce qui est nécessaire

8

Nous avons eu un serveur qui a 5 magasins séparés dessus. Certains sont pratiquement inactifs. Certains sont actifs quotidiennement. Pour diminuer la charge du serveur. Nous avons changé l'index de automatique à manuel. Ensuite, nous fixons un cronjob toutes les 6 heures. J'ai trouvé suffisamment d' exemples de réindexation de tous.

Nous
exécutons quelque chose comme ceci maintenant: Shop1: 0 0,6,12,18 * * * php -f /shell/indexer.php reindexall
Shop2: 0 1,7,13,19 * * * php -f /shell/indexer.php reindexall
et ainsi de suite, pour éviter les chevauchements.

À l'heure actuelle, les magasins inactifs réindexent également toutes les 6 heures, là où aucun n'est nécessaire. Existe-t-il un moyen de réindexer uniquement ce qui est nécessaire avec un cronjob?

Ou faisons-nous tout à fait tort?

janw
la source

Réponses:

3

Ce que vous voulez, c'est créer un script CLI shell, et l'utiliser pour déterminer si un index nécessite un ré-indexage.

Jetez un œil aux scripts dans le dossier shell (log.php fera l'affaire) comme exemple sur la façon de créer un tel script.

Le script que vous créez vérifierait alors l'état de l'index et ne ré-indexerait que s'il se trouve dans un état qui nécessite une indexation.

Je crée généralement mes scripts shell personnalisés dans un dossier appelé / scripts, car je n'aime pas polluer le shell du dossier principal avec mon code personnalisé.

À cet effet, j'ai une classe abstraite sur laquelle je base tous mes scripts, et elle contient du code qui me permet de réindexer facilement les indexeurs s'ils nécessitent une indexation.

voici ma classe abstraite:

/**
 * Abstracted functions for scripts
 *
 * @category    ProxiBlue
 * @package     Scripts
 * @author  Lucas van Staden ([email protected])
 * @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();
    }

}

Ensuite, une classe basée sur cela, qui appelle un ré-index, après un certain travail.

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
la source
Je dois dire que la réponse donnée par @Flyingmana est en fait bien plus intelligente que la mienne;)
ProxiBlue
6

Ce que je sais, l'Index est quelque chose de global, donc une réindexation couvre toujours tous les magasins / sites Web d'un Magento.

Mais, Magento a certaines fonctionnalités que vous aimerez. Tandis que la «mise à jour lors de l'enregistrement» effectue les mises à jour pour indexer instantanément, la «mise à jour manuelle» place les mêmes «mises à jour» dans une file d'attente, que vous pouvez déclencher ultérieurement.

Pour cela, vous devrez écrire votre propre script shell ou tâche cron

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

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

Je n'expliquerai pas les bases des modèles de processus, jetez simplement un œil à la fonction indexEvents, elle prend les entrées de la file d'attente et les met à jour. Mais attention, l'index URL peut être un peu lent. Mais c'est un autre problème.

Flyingmana
la source
1
Solution intéressante, je ne savais pas que les événements sont enregistrés lorsque la "mise à jour manuelle" est activée. Cela permettrait d'indexer uniquement les données modifiées.
Andreas von Studnitz
0

Pour réindexer les processus, nous avons besoin de leurs identifiants.
Pour magento par défaut, il y a 9 processus à réindexer, numérotés de 1 à 9.

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

Parfois, il existe des processus de nos modules personnalisés qui nécessitent également une réindexation. Nous devons ajouter ces identifiants à notre tableau existant d’identifiants.
admin panel-> System-> Index Management

Vous obtiendrez une URL: admin / process / some_id / ...... cet identifiant correspond au processus

$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();
   }
}
Deepak Mallah
la source
Cela ne répond pas à ma question comment changer le cronjob. De plus, cela réindexe tout. Je veux seulement réindexer les pièces modifiées.
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();
        }
    }
    ?>
jrossi
la source
0

J'ai préféré la réponse d'Amit Bera - mais modifié en plaçant les identifiants dans un tableau et surtout arrangé pour un fonctionnement plus fluide. Si vous exécutez directement à travers les nombres, la réindexation d'une table d'index peut entraîner la invalidité d'une autre. IE Index product_flat table alors le prix peut rendre la table plate du produit invalide et nécessiter une réindexation.

<?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();
  }
}
Dan Tupper
la source
2
Pour info, c'est @jim qui n'a pas répondu.
dh47
0

M1 vérifier l'état de l'indexeur

Exécutez la commande ci-dessous dans le répertoire racine pour vérifier l'état.

php shell/indexer.php --status

Exécutez la commande ci-dessous dans le répertoire racine pour vérifier l'indexeur.

php shell/indexer.php info

cronjob: comment réindexer uniquement ce qui est nécessaire.

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

Par exemple: je règle la réindexation toutes les 6 heures

*_6_*_*_* php -f /home/magento/public_html/shell/indexer.php --reindex catalogsearch_fulltex
Baharuni Asif
la source