proceso de índice de acción masiva

8

Estamos teniendo el problema de que el proceso de índice de mass_action nunca parece ejecutarse. Esto tiene el efecto secundario de que los datos del trabajo de este trabajo crecen sustancialmente con el tiempo.

En nuestro caso, en el transcurso de varios días, los datos del trabajo crecen a varios MB.

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 |
+-----------------------+--------------------------------+----------+-----------------------+-----------------------+

Como estos datos no se serializan y luego se serializan para una actualización, así como se transfieren desde y hacia el servidor DB, una actualización de la entrada mass_action tarda actualmente alrededor de 3 segundos en completarse. Esto afecta el código que desencadena una actualización de este índice.

Según tengo entendido, la activación de una actualización de los siguientes índices actualizará la acción masiva

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 |
+---------------------------+------------+----------+--------+-------------+---------------------+

Tenemos todos los índices configurados en manual y ejecutamos cronjobs en varios momentos del día para actualizar los índices.

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 |
+------------+-------------------------------+-----------------+---------------------+---------------------+--------+

Volver a indexar cron cronograma:

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

Índice de tiempos:

$ 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

Mi suposición es que ejecutar un reindexado completo procesará el proceso de acción masiva y lo eliminará de la tabla. Por desgracia, este no es el caso. ¿Alguien sabe cuáles son las condiciones que aclaran ese proceso?

Michael Thessel
fuente
Estoy experimentando esto también. La fila 'mass_action' en la tabla sigue creciendo y creciendo, a pesar de que los índices se ejecutan con éxito. Trunqué la index_eventtabla y la index_processtabla y luego ejecuté un script para actualizar las cifras de los artículos de stock. La fila volvió a aparecer, más pequeña que antes, por supuesto, y siguió creciendo nuevamente después de una reindexación.
Aaron Pollock
1
Nunca he encontrado una solución adecuada para eso. Lo que terminé haciendo fue agregar un trabajo cron que elimina frecuentemente mass_action. No debería tener ningún efecto secundario siempre que indexe manualmente todos los índices con frecuencia.
Michael Thessel

Respuestas:

1

¿Notó el tiempo de indexación en algunos de sus índices? Varía de segundos a la mayoría de las horas. Dependiendo de cómo configuró sus cronjobs, su tienda podría estar ocupada indexando todo el día, continuamente. Este podría ser su problema, ya que no puede finalizar las indexaciones o al menos mantenerse al día. Tener un índice bloqueado en todo momento podría causar algunos problemas y es conocido por este tipo de problemas.

Tengo que hacer algunas suposiciones aquí, corrígeme si es necesario. Especifique más información sobre su configuración si cree que esto podría estar relacionado con su problema. He estado trabajando en un proyecto que debería ayudar a los desarrolladores a limpiar su core_url_rewritemesa porque crece sustancialmente con el tiempo en ciertos escenarios. Creo que el suyo también está teniendo este problema, ya que se ejecutó durante casi 3 horas, y el problema que describe podría estar relacionado con él. Veo cosas similares en los casos de prueba.

¿Su problema es específico solo del mass_actionobjeto de evento? ¿O sucede también con los otros tipos de eventos? (guardar, eliminar, reindexar, etc. (Mage_Index_Model_Event)). Si no, diría que está relacionado con los índices que no se indexan correctamente. Dado el hecho de que podría haber bloqueos en las tablas, que son necesarios para el procesamiento, no estoy seguro de esto. Puede verificar fácilmente si hay bloqueos activos usando algo como:

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

O usa mi esencia, no olvides eliminarla cuando hayas terminado. No es para uso de producción.

Índice de una página y resumen del estado del bloqueo

Así que creo que cuando arreglas tus tiempos de índice, tu problema podría desaparecer y la tienda podría funcionar mucho mejor. En el caso de la core_url_rewritetabla, la sobrecarga es generada por el propio Magento en un esfuerzo por tener URL únicas pero termina duplicándolas. Esto tiene complicaciones en el lado de SEO y rendimiento. La solución a este problema es hacer que la URL sea única y eliminar todos los gastos generales, sin dañar sus puntajes de SEO. Cuando estén limpios, notará una gran diferencia en los tiempos de índice. Algunos de mis casos comenzaron a generar mapas de sitio nuevamente después de meses.

Limpiarlo puede ser complicado, pero el paquete magerun que reuní a partir de los scripts que utilicé puede ayudarlo con al menos la tabla de reescritura. Actualmente es una prueba de concepto, así que asegúrese de tener copias de seguridad. Cuando se pruebe algo útil, lo reconstruiré.

Paquete Magerun con comandos para limpiar core_url_rewrite

En cuanto a las otras tablas, debo suponer que hay algo similar que causa sobrecarga ya que no tengo otra información con la que pueda relacionar un problema. Tal vez podría agregar más información sobre cosas como el tamaño de su catálogo, las especificaciones del servidor, las configuraciones del alcance de la tienda, todas están relacionadas con el rendimiento de su índice. También es posible que desee verificar su tabla para asegurarse de que no faltan restricciones, etc.

Reparación de DB Magento

Hay una publicación de pila que contiene una gran colección de información sobre los índices de Magento, en caso de que aún no la haya visto.

Pila de publicación en índices

Espero que esto sea de algún valor para ti, buena suerte

FROSITO
fuente
1
Muy interesantes ideas. Configuré los trabajos cron de manera que todos los índices se completen de manera que no haya superposición (programa agregado arriba). El proceso de indexación más largo es el de reescritura de URL, pero finaliza en unos 10 minutos. Verifiqué los bloqueos de índice y cuando no se está ejecutando ningún trabajo de índice, ninguno de los índices está bloqueado. No estoy seguro de cómo funcionan los tiempos de indexación en la tabla index_process, pero begin_at y final_at a veces no parecen reflejar el mismo trabajo cron. Parece que initial_at podría actualizarse cuando se establece el indicador require_reindex.
Michael Thessel
0

No sé si todavía tiene este problema, pero tiene que ver con que se ejecute en modo MANUAL para todos sus indexadores.

En Mage_Index_Model_Resource_Event tienes un _beforeSave que hace lo siguiente:

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

Aquí $ object-> cleanNewData () invocará en 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;
}

Observe que $ newData nunca se restablecerá si el estado de Index_Process no es igual a Mage_Index_Model_Process :: EVENT_STATUS_DONE? Bueno, en modo MANUAL para los indexadores, esto nunca sucederá en el Registro de eventos de índice.

Esto se debe a que Mage_Index_Model_Process nunca procesará el Evento en modo MANUAL (que no debería) y, por lo tanto, nunca establecerá el estado en 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 solo desea reducir el tamaño, puede restablecer el evento o simplemente configurar los indexadores para usar el modo REAL_TIME y reindexar todo a través de shell / reindexer.php. La próxima vez que realice una acción que cree un evento de indexación, los datos antiguos se desarmarán.

Morita
fuente