mass_action index prozess

8

Wir haben das Problem, dass der mass_action-Indexprozess niemals ausgeführt zu werden scheint. Dies hat den Nebeneffekt, dass die Jobdaten dieses Jobs im Laufe der Zeit erheblich wachsen.

In unserem Fall wachsen die Auftragsdaten über mehrere Tage auf mehrere 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 |
+-----------------------+--------------------------------+----------+-----------------------+-----------------------+

Da diese Daten unserialisiert und dann für ein Update serialisiert sowie vom und zum DB-Server übertragen werden, dauert ein Update des Eintrags mass_action derzeit ca. 3 Sekunden. Dies betrifft Code, der eine Aktualisierung dieses Index auslöst.

Soweit ich weiß, wird durch das Auslösen einer Aktualisierung der folgenden Indizes die Massenaktion aktualisiert

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

Wir haben alle Indizes auf manuell eingestellt und führen zu verschiedenen Tageszeiten Cronjobs aus, um die Indizes zu aktualisieren.

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-Zeitplan neu indizieren:

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

Index-Timings:

$ 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

Ich gehe davon aus, dass das Ausführen eines vollständigen Neuindexierens den Prozess mass_action verarbeiten und aus der Tabelle löschen würde. Dies ist leider nicht der Fall. Weiß jemand, unter welchen Bedingungen dieser Prozess geklärt wird?

Michael Thessel
quelle
Ich erlebe das auch. Die Zeile 'mass_action' in der Tabelle wächst und wächst, obwohl die Indizes erfolgreich ausgeführt werden. Ich habe die index_eventTabelle und die index_processTabelle abgeschnitten und dann ein Skript ausgeführt, um die Lagerartikelzahlen zu aktualisieren. Die Reihe tauchte wieder auf, natürlich kleiner als zuvor, und wuchs nach einer Neuindizierung weiter.
Aaron Pollock
1
Ich habe nie eine richtige Lösung dafür gefunden. Am Ende habe ich einen Cron-Job hinzugefügt, der mass_action häufig löscht. Es sollte keine Nebenwirkungen haben, solange Sie alle Indizes häufig manuell indizieren.
Michael Thessel

Antworten:

1

Haben Sie die Indexierungszeit für einige Ihrer Indizes bemerkt? Es variiert von Sekunden bis meistens Stunden. Abhängig davon, wie Sie Ihre Cronjobs konfiguriert haben, ist Ihr Geschäft möglicherweise den ganzen Tag damit beschäftigt, kontinuierlich zu indizieren. Dies könnte Ihr Problem sein, da es nicht in der Lage ist, die Indexierungen abzuschließen oder zumindest mitzuhalten. Ein jederzeit gesperrter Index kann zu Problemen führen und ist für diese Art von Problemen bekannt.

Ich muss hier einige Annahmen treffen, mich korrigieren, wenn nötig. Geben Sie weitere Informationen zu Ihrem Setup an, wenn Sie der Meinung sind, dass dies mit Ihrem Problem zusammenhängt. Ich habe an einem Projekt gearbeitet, das Entwicklern helfen soll, ihre core_url_rewriteTabelle zu bereinigen, da es in bestimmten Szenarien im Laufe der Zeit erheblich wächst. Ich denke, auch Sie haben dieses Problem, da es fast 3 Stunden lang lief und das von Ihnen beschriebene Problem damit zusammenhängen könnte. Ich sehe ähnliche Dinge bei Testfällen.

Ist Ihr Problem nur für das mass_actionEreignisobjekt spezifisch ? oder passiert es auch bei den anderen Ereignistypen? (Speichern, Löschen, Neuindizieren usw. (Mage_Index_Model_Event)). Wenn nicht, würde ich sagen, dass es damit zusammenhängt, dass die Indizes nicht richtig indiziert werden. Angesichts der Tatsache, dass es Sperren für Tabellen geben kann, die für die Verarbeitung erforderlich sind, bin ich mir nicht sicher. Sie können leicht nach aktiven Sperren suchen, indem Sie Folgendes verwenden:

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

Oder verwenden Sie meinen Kern, vergessen Sie nicht, ihn zu entfernen, wenn Sie fertig sind. Es ist nicht für den Produktionsgebrauch.

Einseitige Übersicht über Index und Sperrstatus

Ich denke also, wenn Sie Ihre Indexzeiten korrigieren, könnte Ihr Problem verschwinden und der Laden könnte viel reibungsloser laufen. Im Fall der core_url_rewriteTabelle wird der Overhead von Magento selbst generiert, um eindeutige URLs zu erhalten, diese werden jedoch dupliziert. Dies hat Komplikationen auf der SEO- und Leistungsseite. Die Lösung für dieses Problem besteht darin, die URL eindeutig zu machen und den gesamten Overhead zu beseitigen, ohne Ihre SEO-Ergebnisse zu beschädigen. Wenn sie sauber sind, werden Sie einen großen Unterschied in den Indexzeiten feststellen. In einigen meiner Fälle wurden nach Monaten wieder Sitemaps erstellt.

Das Reinigen kann schwierig sein, aber das Magerun-Bundle, das ich aus den von mir verwendeten Skripten zusammengestellt habe, kann Ihnen zumindest beim Umschreiben der Tabelle helfen. Derzeit handelt es sich um einen Proof of Concept. Stellen Sie daher sicher, dass Sie Backups haben. Wenn es sich als nützlich erwiesen hat, werde ich es wieder aufbauen.

Magerun-Bundle mit Befehlen zum Reinigen von core_url_rewrite

Was die anderen Tabellen betrifft, muss ich davon ausgehen, dass es etwas Ähnliches gibt, das Overhead verursacht, da ich keine anderen Informationen habe, anhand derer ich ein Problem in Beziehung setzen kann. Vielleicht könnten Sie weitere Informationen zu Dingen wie der Größe Ihres Katalogs, Serverspezifikationen und Speicherbereichskonfigurationen hinzufügen, die alle mit Ihrer Indexleistung zusammenhängen. Möglicherweise möchten Sie auch Ihre Tabelle überprüfen, um sicherzustellen, dass keine Einschränkungen usw. fehlen.

Magento DB Reparatur

Es gibt einen Stapelbeitrag mit einer großartigen Sammlung von Informationen zu Magentos Indizes, für den Fall, dass Sie sie noch nicht gesehen haben.

Stapelpfosten auf Indizes

Ich hoffe, das ist für Sie von Wert, viel Glück

FROSIT
quelle
1
Sehr interessante Einblicke. Ich habe die Cron-Jobs so eingerichtet, dass alle Indizes so vervollständigt werden, dass es keine Überlappung gibt (Zeitplan oben hinzugefügt). Der längste Indizierungsprozess ist der URL-Umschreibungsprozess, der jedoch in etwa 10 Minuten abgeschlossen ist. Ich habe die Indexsperren überprüft und wenn kein Indexjob ausgeführt wird, ist keiner der Indizes gesperrt. Ich bin nicht sicher, wie die Indizierungszeiten in der Tabelle index_process funktionieren, aber start_at und ended_at scheinen manchmal nicht denselben Cron-Job zu widerspiegeln. Es sieht so aus, als ob start_at möglicherweise aktualisiert wird, wenn das Flag require_reindex gesetzt ist.
Michael Thessel
0

Ich weiß nicht, ob Sie dieses Problem immer noch haben, aber es hat damit zu tun, dass Sie für alle Ihre Indexer im MANUELLEN Modus ausgeführt werden.

In Mage_Index_Model_Resource_Event haben Sie ein _beforeSave, das Folgendes ausführt:

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

Hier wird $ object-> cleanNewData () in Mage_Index_Model_Event aufgerufen:

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

Beachten Sie, dass $ newData niemals zurückgesetzt wird, wenn der Index_Process-Status nicht gleich Mage_Index_Model_Process :: EVENT_STATUS_DONE ist. Nun, im MANUELLEN Modus für die Indexer wird dies im Index-Ereignisregister niemals passieren.

Dies liegt daran, dass Mage_Index_Model_Process das Ereignis niemals im MANUELLEN Modus verarbeitet (was nicht der Fall sein sollte) und daher den Status niemals auf Mage_Index_Model_Process :: EVENT_STATUS_DONE setzt.

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

Wenn Sie nur die Größe verringern möchten, können Sie entweder das Ereignis zurücksetzen oder die Indexer so einstellen, dass sie den REAL_TIME-Modus verwenden und die gesamte Shell / reindexer.php neu indizieren. Wenn Sie das nächste Mal eine Aktion ausführen, die ein Indizierungsereignis erstellt, werden die alten Daten deaktiviert.

Morita
quelle