processo de índice mass_action

8

Estamos com o problema que o processo de índice mass_action parece nunca executar. Isso tem o efeito colateral de que os dados desse trabalho aumentam substancialmente com o tempo.

No nosso caso, ao longo de vários dias, os dados do trabalho aumentam para vários 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 esses dados são desserializados e serializados para uma atualização, além de transferidos de e para o servidor DB, uma atualização na entrada mass_action leva atualmente cerca de 3s para ser concluída. Isso afeta o código que aciona uma atualização desse índice.

Pelo que entendi, o acionamento de uma atualização dos seguintes índices atualizará a ação em massa

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

Todos os índices estão definidos como manuais e executamos cronjobs em vários horários do dia para atualizar os í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 |
+------------+-------------------------------+-----------------+---------------------+---------------------+--------+

Re-indexar a programação do 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

Tempos do índice:

$ 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

Minha suposição é que a execução de um re-índice completo processaria o processo mass_action e o eliminaria da tabela. Infelizmente, esse não é o caso. Alguém sabe quais são as condições que esclarecem esse processo?

Michael Thessel
fonte
Eu também estou experimentando isso. A linha 'mass_action' na tabela continua crescendo, apesar dos índices serem executados com êxito. Trunquei a index_eventtabela e a index_processtabela e, em seguida, executei um script para atualizar os números dos itens de estoque. A linha reapareceu, menor do que antes, é claro, e continuou crescendo novamente após uma reindexação.
Aaron Pollock
11
Eu nunca encontrei uma solução adequada para isso. O que acabei fazendo foi adicionar um trabalho cron que exclui mass_action com frequência. Não deve ter efeito colateral, desde que você indexe manualmente manualmente todos os índices.
Michael Thessel

Respostas:

1

Você notou o tempo de indexação em alguns de seus índices? Varia de segundos a principalmente horas. Dependendo de como você configurou seus cronjobs, sua loja pode estar ocupada indexando o dia todo, continuamente. Esse pode ser o seu problema, pois não é possível concluir as indexações ou, pelo menos, acompanhá-lo. Ter um índice bloqueado o tempo todo pode causar alguns problemas e é conhecido por esse tipo de problema.

Eu tenho que fazer algumas suposições aqui, me corrija se necessário. Especifique mais informações sobre sua configuração, se achar que isso pode estar relacionado ao seu problema. Eu tenho trabalhado em um projeto que deve ajudar os desenvolvedores a limpar sua core_url_rewritetabela, porque cresce substancialmente ao longo do tempo em determinados cenários. Acho que o seu também está com esse problema, pois ele durou quase 3 horas, e o problema que você descreve pode estar relacionado a ele. Vejo coisas semelhantes nos casos de teste.

Seu problema é específico apenas ao mass_actionobjeto de evento? ou isso acontece com os outros tipos de eventos também? (salvar, excluir, reindexar etc. (Mage_Index_Model_Event)). Caso contrário, eu diria que está relacionado aos índices que não estão sendo indexados corretamente. Dado o fato de haver bloqueios nas tabelas, necessários para o processamento, não tenho certeza disso. Você pode facilmente verificar se há bloqueios ativos 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() . "!";
        }
    }

Ou use minha essência, não esqueça de removê-la quando terminar. Não é para uso em produção.

Índice de uma página e visão geral do status de bloqueio

Então, acho que quando você corrige o tempo de indexação, seu problema pode desaparecer e a loja pode funcionar de maneira mais tranquila. No caso da core_url_rewritetabela, a sobrecarga é gerada pelo próprio Magento, em um esforço para ter URLs únicas, mas acaba duplicando-as. Isso tem complicações no lado de SEO e desempenho. A solução para esse problema é tornar o URL único e limpar toda a sobrecarga, sem danificar sua pontuação de SEO. Quando estiverem limpos, você notará uma grande diferença nos tempos de indexação. Alguns dos meus casos começaram a gerar sitemaps novamente depois de meses.

Limpá-lo pode ser complicado, mas o pacote magerun que montei dos scripts que usei pode ajudá-lo com pelo menos a tabela de reescrita. Atualmente, é uma prova de conceito, portanto, faça backups. Quando provar algo útil, eu o reconstruirei.

Pacote Magerun com comandos para limpar core_url_rewrite

Quanto às outras tabelas, devo assumir que há algo semelhante causando sobrecarga, pois não tenho outras informações das quais possa relacionar um problema. Talvez você possa adicionar mais algumas informações sobre coisas como o tamanho do seu catálogo, especificações do servidor, configurações de escopo da loja, todas relacionadas ao desempenho do seu índice. Você também pode verificar sua tabela para garantir que não haja restrições, etc.

Magento DB Repair

Há um post de pilha contendo uma grande coleção de informações nos índices do Magento, caso você ainda não tenha visto.

Empilhar postagem em índices

Espero que isso tenha algum valor para você, boa sorte

FROSIT
fonte
11
Insights muito interessantes. Configurei os trabalhos do cron de forma que todos os índices sejam concluídos de maneira que não haja sobreposição (agendamento adicionado acima). O processo de indexação mais longo é o de reescrita do URL, mas que termina em cerca de 10 minutos. Verifiquei os bloqueios do índice e, quando nenhum trabalho de índice está sendo executado, nenhum dos índices está bloqueado. Não tenho certeza de como os tempos de indexação na tabela index_process funcionam, mas, às vezes, start_at e ended_at parecem refletir o mesmo trabalho cron. Parece que iniciado_at pode ser atualizado quando o sinalizador require_reindex estiver definido.
Michael Thessel
0

Não sei se você ainda tem esse problema, mas isso tem a ver com você sendo executado no modo MANUAL para todos os seus indexadores.

No Mage_Index_Model_Resource_Event, você tem um _beforeSave que faz o seguinte:

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

Aqui, o $ object-> cleanNewData () será chamado em 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 será redefinido se o status de Index_Process não for igual a Mage_Index_Model_Process :: EVENT_STATUS_DONE? Bem, no modo MANUAL para os indexadores, isso nunca acontecerá no Index Event Register.

Isso ocorre porque o Mage_Index_Model_Process nunca processará o evento no modo MANUAL (o que não deveria) e, portanto, nunca definirá o status como 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;
}

Se você quiser apenas diminuir o tamanho, poderá redefinir o evento ou simplesmente configurar os indexadores para usar o modo REAL_TIME e reindexar tudo através do shell / reindexer.php. Na próxima vez que você executar uma ação que cria um evento de indexação, os dados antigos serão desabilitados.

Morita
fonte