质量作用指数过程


8

我们遇到的问题是mass_action索引过程似乎永远不会执行。这具有该作业的作业数据随着时间的推移而显着增长的副作用。

在我们的案例中,几天的工作数据增长到了几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 |
+-----------------------+--------------------------------+----------+-----------------------+-----------------------+

由于未序列化此数据,然后将其序列化以进行更新,以及从数据库服务器传输数据至数据库服务器,以及将数据传输至数据库服务器,对mass_action条目的更新当前大约需要3秒钟才能完成。这会影响触发此索引更新的代码。

据我了解,触发以下索引的更新将更新群众行动

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

我们将所有索引设置为手动,并在一天的不同时间运行cronjobs以更新索引。

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

重新索引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

索引时间:

$ 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

我的假设是,运行完整的重新索引将处理mass_action流程并将其从表中清除。不幸的是,这种情况并非如此。有谁知道清除该过程的条件是什么?


我也在经历这个。尽管索引成功运行,表中的“ mass_action”行仍在不断增长。我截断了index_event表格和index_process表格,然后运行了一个脚本来更新库存项目数字。该行重新出现,比以前少了,并且在重新索引后又保持增长。
亚伦·波洛克

1
我从未为此找到合适的解决方案。我最终要做的是添加一个cron作业,该作业经常删除mass_action。只要您经常手动索引所有索引,它就没有副作用。
Michael Thessel '17

Answers:


1

您是否注意到某些索引的索引时间?它从几秒钟到大部分小时不等。根据您配置cronjobs的方式,您的商店可能整天连续忙于编制索引。这可能是您的问题,因为它无法完成索引编制或至少无法跟上索引编制的进度。始终具有锁定索引可能会造成一些麻烦,并且以此类问题而闻名。

我必须在这里做一些假设,如有需要请纠正我。如果您认为这可能与您的问题有关,请在设置中指定更多信息。我一直在研究一个项目,该项目应该帮助开发人员清理core_url_rewrite表,因为在某些情况下,表会随着时间的推移而显着增长。我认为您的问题也已经存在了,因为它已经运行了将近3个小时,您所描述的问题可能与此有关。我在测试案例中看到了类似的东西。

您的问题仅针对mass_action事件对象吗?还是其他事件类型也会发生?(保存,删除,重新编制索引等。(Mage_Index_Model_Event))。如果不是,我会说这与索引未正确索引有关。鉴于事实可能存在表上的锁,这是处理所必需的,对此我不确定。您可以使用以下类似方法轻松检查活动锁:

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

或使用我的要点,完成后别忘了将其删除。它不是用于生产用途。

一页索引和锁定状态概述

因此,我认为,当您固定索引时间时,您的问题可能会消失,并且商店会运行得更加顺利。在core_url_rewrite表的情况下,开销是由Magento自身产生的,目的是拥有唯一的URL,但最终会重复它们。这在SEO和性能方面会带来麻烦。解决此问题的方法是使URL唯一,并清除所有开销,而又不损害SEO分数。当它们干净时,您会注意到索引时间有很大的不同。我的一些案例在几个月后又开始生成站点地图。

清理它可能很棘手,但是我从我使用的脚本中放在一起的magerun捆绑包至少可以帮助您重写表。当前,这是一个概念证明,因此请确保进行备份。当证明有用的东西时,我将对其进行重建。

Magerun软件包,其中包含用于清理core_url_rewrite的命令

至于其他表,我必须假设存在类似的原因导致开销,因为我没有其他可与之相关的信息。也许您可以添加有关目录大小,服务器规格,存储范围配置之类的更多信息,它们都与索引性能有关。您可能还需要检查表以确保它没有缺少约束等。

Magento DB维修

有一个堆栈文章,其中包含有关Magento索引的大量信息,以防万一您还没有看到它。

在索引上堆积帖子

我希望这对您有任何价值,祝您好运


1
非常有趣的见解。我以不重叠的方式完成所有索引的方式设置了cron作业(上面添加了时间表)。最长的索引编制过程是url重写,但大约需要10分钟才能完成。我检查了索引锁,并且当没有索引作业在运行时,没有索引被锁定。我不确定index_process表中的索引编制时间如何工作,但是started_at和end_at有时似乎不能反映相同的cron作业。设置require_reindex标志后,started_at可能会更新。
Michael Thessel '16

0

我不知道您是否仍然遇到此问题,但是这与您为所有索引器在MANUAL模式下运行有关。

在Mage_Index_Model_Resource_Event中,您有一个_beforeSave执行以下操作:

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

这里$ object-> cleanNewData()将在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;
}

注意,如果Index_Process状态不等于Mage_Index_Model_Process :: EVENT_STATUS_DONE,$ newData将永远不会被重置?好吧,在索引器的手动模式下,这不会在索引事件寄存器中发生。

这是因为Mage_Index_Model_Process将永远不会在手动模式下处理事件(不应这样做),因此永远不会将状态设置为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;
}

如果只想减小大小,则可以重置事件或将索引器设置为使用REAL_TIME模式,然后通过shell / reindexer.php重新索引所有索引。下次您执行创建索引事件的操作时,将不会设置旧数据。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.