processus d'index mass_action

8

Nous avons le problème que le processus d'index mass_action ne semble jamais s'exécuter. Cela a pour effet secondaire que les données d'emploi de cet emploi augmentent considérablement au fil du temps.

Dans notre cas, sur plusieurs jours, les données du travail atteignent plusieurs Mo.

mysql> select type, entity, count(*), avg(length(new_data)), max(length(new_data)) from index_event group by type, entity;
+-----------------------+--------------------------------+----------+-----------------------+-----------------------+
| type                  | entity                         | count(*) | avg(length(new_data)) | max(length(new_data)) |
+-----------------------+--------------------------------+----------+-----------------------+-----------------------+
| catalog_reindex_price | catalog_product                |     1368 |              442.7982 |                   443 |
| mass_action           | catalog_product                |        1 |          6176981.0000 |               6176981 |
| save                  | awaffiliate_withdrawal_request |        6 |              444.3333 |                   445 |
| save                  | cataloginventory_stock_item    |     4439 |              607.9685 |                   608 |
| save                  | catalog_category               |       71 |             1040.3662 |                  3395 |
| save                  | catalog_eav_attribute          |        3 |              424.6667 |                   476 |
| save                  | catalog_product                |     1368 |             1269.0899 |                  1922 |
+-----------------------+--------------------------------+----------+-----------------------+-----------------------+

Comme ces données ne sont pas sérialisées puis sérialisées pour une mise à jour ainsi que transférées depuis et vers le serveur DB, une mise à jour de l'entrée mass_action prend actuellement environ 3 secondes. Cela affecte le code qui déclenche une mise à jour de cet index.

Si je comprends bien, le déclenchement d'une mise à jour des index suivants mettra à jour l'action de masse

mysql> select ip.indexer_code, ipe.process_id, ipe.event_id, ipe.status, ie.type, ie.created_at from index_process_event as ipe left join index_event as ie on ipe.event_id = ie.event_id  left join index_process as ip on ip.process_id = ipe.process_id where ie.type  = 'mass_action';
+---------------------------+------------+----------+--------+-------------+---------------------+
| indexer_code              | process_id | event_id | status | type        | created_at          |
+---------------------------+------------+----------+--------+-------------+---------------------+
| catalog_product_attribute |          1 |     9074 | new    | mass_action | 2016-11-03 23:18:06 |
| catalog_product_price     |          2 |     9074 | new    | mass_action | 2016-11-03 23:18:06 |
| catalogsearch_fulltext    |          7 |     9074 | new    | mass_action | 2016-11-03 23:18:06 |
| cataloginventory_stock    |          8 |     9074 | new    | mass_action | 2016-11-03 23:18:06 |
| tag_summary               |          9 |     9074 | new    | mass_action | 2016-11-03 23:18:06 |
| catalog_product_flat      |         19 |     9074 | new    | mass_action | 2016-11-03 23:18:06 |
| catalog_category_product  |         21 |     9074 | new    | mass_action | 2016-11-03 23:18:06 |
+---------------------------+------------+----------+--------+-------------+---------------------+

Nous avons tous les index définis sur manuel et exécutons des tâches cron à divers moments de la journée pour mettre à jour les index.

mysql> select * from index_process;
+------------+-------------------------------+-----------------+---------------------+---------------------+--------+
| process_id | indexer_code                  | status          | started_at          | ended_at            | mode   |
+------------+-------------------------------+-----------------+---------------------+---------------------+--------+
|          1 | catalog_product_attribute     | require_reindex | 2016-11-15 00:40:10 | 2016-11-15 00:10:24 | manual |
|          2 | catalog_product_price         | require_reindex | 2016-11-15 00:45:09 | 2016-11-15 00:15:44 | manual |
|          7 | catalogsearch_fulltext        | require_reindex | 2016-11-14 23:51:23 | 2016-11-14 12:12:30 | manual |
|          8 | cataloginventory_stock        | require_reindex | 2016-11-15 00:47:01 | 2016-11-15 00:45:09 | manual |
|          9 | tag_summary                   | require_reindex | 2016-11-14 23:54:01 | 2016-11-14 23:54:01 | manual |
|         12 | awaffiliate_affiliate_balance | pending         | 2016-11-14 23:54:01 | 2016-11-14 23:54:03 | manual |
|         18 | catalog_url                   | require_reindex | 2016-11-14 23:54:03 | 2016-11-14 21:02:53 | manual |
|         19 | catalog_product_flat          | require_reindex | 2016-11-15 00:49:02 | 2016-11-15 00:10:10 | manual |
|         20 | catalog_category_flat         | pending         | 2016-11-15 00:51:01 | 2016-11-15 00:51:04 | manual |
|         21 | catalog_category_product      | require_reindex | 2016-11-15 00:53:01 | 2016-11-15 00:06:04 | manual |
|         22 | ampgrid_qty_sold              | require_reindex | 2016-11-15 00:06:04 | 2016-11-14 12:21:18 | manual |
+------------+-------------------------------+-----------------+---------------------+---------------------+--------+

Réindexer le calendrier cron:

0-59/15 *  *   *   *  cd html && /usr/bin/php  /www/sites/files/html/shell/indexer.php --reindex catalog_product_price > /dev/null 2>&1
2-59/15 *  *   *   *  cd html && /usr/bin/php  /www/sites/files/html/shell/indexer.php --reindex cataloginventory_stock > /dev/null 2>&1
4-59/15 *  *   *   *  cd html && /usr/bin/php  /www/sites/files/html/shell/indexer.php --reindex catalog_product_flat > /dev/null 2>&1
6-59/15 *  *   *   *  cd html && /usr/bin/php  /www/sites/files/html/shell/indexer.php --reindex catalog_category_flat > /dev/null 2>&1
8-59/15 *  *   *   *  cd html && /usr/bin/php  /www/sites/files/html/shell/indexer.php --reindex catalog_category_product > /dev/null 2>&1
10-59/15 *  *   *   *  cd html && /usr/bin/php  /www/sites/files/html/shell/indexer.php --reindex catalog_product_attribute > /dev/null 2>&1

10 4  *   *   *    cd html && /usr/bin/php  /www/sites/files/html/shell/indexer.php --reindex catalogsearch_fulltext > /dev/null 2>&1
20 4  *   *   *    cd html && /usr/bin/php  /www/sites/files/html/shell/indexer.php --reindex ampgrid_qty_sold > /dev/null 2>&1
30 4  *   *   *    cd html && /usr/bin/php  /www/sites/files/html/shell/indexer.php --reindex awaffiliate_affiliate_balance > /dev/null 2>&1
40 4  *   *   *    cd html && /usr/bin/php  /www/sites/files/html/shell/indexer.php --reindex tag_summary > /dev/null 2>&1

50  */6   *   *  *  cd html && /usr/bin/php  /www/sites/files/html/shell/indexer.php --reindex catalog_url > /dev/null 2>&1

Timings d'index:

$ time php shell/indexer.php --reindexall
Product Attributes index was rebuilt successfully in 00:00:21
Product Prices index was rebuilt successfully in 00:00:32
Search Index index was rebuilt successfully in 00:02:31
Stock Status index was rebuilt successfully in 00:00:00
Tag Aggregation Data index was rebuilt successfully in 00:00:00
Affiliates Balance index was rebuilt successfully in 00:00:02
Catalog URL Rewrites index was rebuilt successfully in 00:10:08
Product Flat Data index was rebuilt successfully in 00:01:54
Category Flat Data index was rebuilt successfully in 00:00:04
Category Products index was rebuilt successfully in 00:00:18
Qty Sold index was rebuilt successfully in 00:00:15

real    16m9.562s
user    8m23.551s
sys     0m19.705s

Mon hypothèse est que l'exécution d'un ré-index complet traiterait le processus mass_action et l'effacerait de la table. Malheureusement, ce n'est pas le cas. Quelqu'un sait-il quelles sont les conditions qui clarifient ce processus?

Michael Thessel
la source
J'en fais l'expérience aussi. La ligne «mass_action» dans le tableau continue de croître et de croître, malgré le succès des index. J'ai tronqué le index_eventtableau et le index_processtableau, puis j'ai exécuté un script pour mettre à jour les chiffres des articles en stock. La ligne est réapparue, plus petite qu'avant, bien sûr, et a continué de croître après une réindexation.
Aaron Pollock
1
Je n'ai jamais trouvé de solution appropriée à cela. J'ai fini par ajouter un travail cron qui supprime fréquemment mass_action. Cela ne devrait avoir aucun effet secondaire tant que vous indexez manuellement tous les index fréquemment.
Michael Thessel

Réponses:

1

Avez-vous remarqué le temps d'indexation sur certains de vos index? Cela varie de quelques secondes à plusieurs heures. Selon la façon dont vous avez configuré vos cronjobs, votre magasin peut être occupé à indexer toute la journée, en continu. Cela pourrait être votre problème car il n'est pas en mesure de terminer les indexations ou au moins de le suivre. Avoir un index verrouillé à tout moment pourrait causer des problèmes et est connu pour ce type de problèmes.

Je dois faire quelques hypothèses ici, corrigez-moi si besoin. Spécifiez quelques informations supplémentaires sur votre configuration si vous pensez que cela pourrait être lié à votre problème. J'ai travaillé sur un projet qui devrait aider les développeurs à nettoyer leur core_url_rewritetable car elle se développe considérablement au fil du temps dans certains scénarios. Je pense que le vôtre a aussi ce problème car il a fonctionné pendant près de 3 heures, et le problème que vous décrivez pourrait y être lié. Je vois des choses similaires dans les cas de test.

Votre problème est-il spécifique à l' mass_actionobjet événement uniquement ? ou cela se produit-il également avec les autres types d'événements? (enregistrer, supprimer, réindexer etc. (Mage_Index_Model_Event)). Sinon, je dirais que c'est lié au fait que les index ne sont pas indexés correctement. Étant donné qu'il pourrait y avoir des verrous sur les tables, qui sont nécessaires pour le traitement, je ne suis pas sûr de cela. Vous pouvez facilement vérifier les verrous actifs en utilisant quelque chose comme:

 $indexes = Mage::getSingleton('index/indexer')->getProcessesCollection()->load();
    foreach($indexes as $index){
        if($index->isLocked(){
            echo "Index" . $index->getIndexerCode() . " with state " . $index->getStatus() . " is locked since " . $index->getStartedAt() . "!";
        }
    }

Ou utilisez mon essentiel, n'oubliez pas de le retirer lorsque vous avez terminé. Ce n'est pas pour une utilisation en production.

Aperçu de l'index et du verrouillage d'une page

Je pense donc que lorsque vous corrigez vos heures d'index, votre problème peut disparaître et le magasin peut fonctionner de manière plus fluide. Dans le cas du core_url_rewritetableau, la surcharge est générée par Magento lui-même dans le but d'avoir des URL uniques mais finit par les dupliquer. Cela a des complications du côté du référencement et des performances. La solution à ce problème consiste à rendre l'URL unique et à éliminer tous les frais généraux, sans endommager vos scores SEO. Quand ils sont propres, vous remarquerez une grande différence dans les temps d'indexation. Certains de mes cas ont recommencé à générer des sitemaps après des mois.

Le nettoyer peut être difficile mais le bundle magerun que j'ai rassemblé à partir des scripts que j'ai utilisés peut vous aider au moins avec la table de réécriture. Actuellement, c'est une preuve de concept, alors assurez-vous d'avoir des sauvegardes. Quand il s'avérera quelque chose d'utile, je le reconstruirai.

Ensemble Magerun avec commandes de nettoyage de core_url_rewrite

En ce qui concerne les autres tableaux, je dois supposer qu'il y a quelque chose de similaire provoquant des frais généraux car je n'ai aucune autre information à partir de laquelle je peux relier un problème. Peut-être pourriez-vous ajouter plus d'informations sur des choses comme la taille de votre catalogue, les spécifications du serveur, les configurations de l'étendue du magasin, elles sont toutes liées aux performances de votre index. Vous pouvez également vérifier votre table pour vous assurer qu'elle ne manque pas de contraintes, etc.

Réparation de base de données Magento

Il y a un message de pile contenant une grande collection d'informations sur les index de Magento, juste au cas où vous ne l'auriez pas déjà vu.

Stack post sur les index

J'espère que cela a une valeur pour vous, bonne chance

FROSIT
la source
1
Des idées très intéressantes. J'ai configuré les tâches cron de manière à ce que tous les index se terminent de manière à ce qu'il n'y ait pas de chevauchement (calendrier ajouté ci-dessus). Le processus d'indexation le plus long est celui de la réécriture d'URL mais qui se termine en 10 minutes environ. J'ai vérifié les verrous d'index et lorsqu'aucun travail d'index n'est en cours d'exécution, aucun des index n'est verrouillé. Je ne sais pas comment fonctionnent les temps d'indexation dans la table index_process, mais begin_at et termin_at ne semblent parfois pas refléter le même travail cron. Il semble que started_at puisse être mis à jour lorsque l'indicateur require_reindex est défini.
Michael Thessel
0

Je ne sais pas si vous avez toujours ce problème mais cela a à voir avec votre fonctionnement en mode MANUEL pour tous vos indexeurs.

Dans Mage_Index_Model_Resource_Event, vous disposez d'un _beforeSave qui effectue les opérations suivantes:

/**
 * Check if semilar event exist before start saving data
 *
 * @param Mage_Core_Model_Abstract $object
 * @return Mage_Index_Model_Resource_Event
 */
protected function _beforeSave(Mage_Core_Model_Abstract $object)
{
    /**
     * Check if event already exist and merge previous data
     */
    if (!$object->getId()) {
        $select = $this->_getReadAdapter()->select()
            ->from($this->getMainTable())
            ->where('type=?', $object->getType())
            ->where('entity=?', $object->getEntity());
        if ($object->hasEntityPk()) {
            $select->where('entity_pk=?', $object->getEntityPk());
        }
        $data = $this->_getWriteAdapter()->fetchRow($select);
        if ($data) {
            $object->mergePreviousData($data);
        }
    }
    $object->cleanNewData();
    return parent::_beforeSave($object);
}

Ici, $ object-> cleanNewData () invoquera dans Mage_Index_Model_Event:

/**
 * Clean new data, unset data for done processes
 *
 * @return Mage_Index_Model_Event
 */
public function cleanNewData()
{
    $processIds = $this->getProcessIds();
    if (!is_array($processIds) || empty($processIds)) {
        return $this;
    }

    $newData = $this->getNewData(false);
    foreach ($processIds as $processId => $processStatus) {
        if ($processStatus == Mage_Index_Model_Process::EVENT_STATUS_DONE) {
            $process = Mage::getSingleton('index/indexer')->getProcessById($processId);
            if ($process) {
                $namespace = get_class($process->getIndexer());
                if (array_key_exists($namespace, $newData)) {
                    unset($newData[$namespace]);
                }
            }
        }
    }
    $this->setNewData(serialize($newData));

    return $this;
}

Notez que $ newData ne sera jamais réinitialisé si le statut Index_Process n'est pas égal à Mage_Index_Model_Process :: EVENT_STATUS_DONE? Eh bien, en mode MANUEL pour les indexeurs, cela ne se produira jamais avec le registre des événements d'index.

Cela est dû au fait que Mage_Index_Model_Process ne traitera jamais l'événement en mode MANUEL (ce qu'il ne devrait pas) et ne définira donc jamais l'état à Mage_Index_Model_Process :: EVENT_STATUS_DONE.

/**
 * Process event with assigned indexer object
 *
 * @param Mage_Index_Model_Event $event
 * @return Mage_Index_Model_Process
 */
public function processEvent(Mage_Index_Model_Event $event)
{
    if (!$this->matchEvent($event)) {
        return $this;
    }
    if ($this->getMode() == self::MODE_MANUAL) {
        $this->changeStatus(self::STATUS_REQUIRE_REINDEX);
        return $this;
    }

    $this->_getResource()->updateProcessStartDate($this);
    $this->_setEventNamespace($event);
    $isError = false;

    try {
        $this->getIndexer()->processEvent($event);
    } catch (Exception $e) {
        $isError = true;
    }
    $event->resetData();
    $this->_resetEventNamespace($event);
    $this->_getResource()->updateProcessEndDate($this);
    $event->addProcessId($this->getId(), $isError ? self::EVENT_STATUS_ERROR : self::EVENT_STATUS_DONE);

    return $this;
}

Si vous souhaitez simplement réduire la taille, vous pouvez soit réinitialiser l'événement, soit définir les indexeurs pour utiliser le mode REAL_TIME et réindexer tout au long de shell / reindexer.php. La prochaine fois que vous effectuez une action qui crée un événement d'indexation, les anciennes données ne seront pas définies.

Morita
la source