Magento 2: Как работает индексация
Для решения одной из проблем, пришлось разобраться с индексацией в Magento 2. В этой статье расскажу о том, что мне удалось узнать.
Индекс и индексатор
В Magento 2 довольно сложная система хранения продуктов, категорий и связанных с ними данных, таких как цены товаров, цены групп товаров, скидки и т.д. Для того, чтобы ускорить выборку этих данных, используются индексные таблицы. Без индексации, пришлось бы все это рассчитывать "на лету", что значительно отразилось бы на производительности. Индексные таблицы представляют собой набор данных, оптимизированный для быстрой выборки. Такой подход позволяет заранее произвести все нужные расчеты, например учесть скидки и в дальнейшем использовать уже обработанные данные вместо того, чтобы делать это для каждого запроса.
За создание индексов отвечают индексаторы. По сути, это классы отвечающие за то, чтобы обработать данные и сохранить их в нужном формате.
- Индекс = это таблица с оптимизированным для выборки набором данных.
- Индексатор = класс который оптимизирует данные и записывает их в таблицу индекса
Способы обновления данных
Предусмотрено 2а способа обновления данных индекса
- Полный реиндекс - используется когда необходимо пересчитать все данные индекса.
- Частичный реиндекс - используется при обновлении конкретного значения индекса.
Теперь поговорим про каждый из способов подробнее.
Полный реиндекс
Для запуска полного реиндекса используется крон задача indexer_reindex_all_invalid, описанная в файле
/vendor/magento/module-indexer/etc/crontab.xml
1 2 3 4 5 6 7 8 9 10 11 12 |
<!-- vendor/magento/module-indexer/etc/crontab.xml --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Cron:etc/crontab.xsd"> <group id="index"> <job name="indexer_reindex_all_invalid" instance="Magento\Indexer\Cron\ReindexAllInvalid" method="execute"> <schedule>* * * * *</schedule> </job> ... </group> </config> |
Работает это так. Некоторые запускаемые процессы могут пометить весь индекс как "invalid". Делается это установкой статуса invalid в таблице indexer_state. Например, некоторый процесс поставит статус invalid для индексера catalog_product_flat
В админке это будет выглядеть так
В случае, если magento крон установлен, то такой индекс будет обнаружен задачей indexer_reindex_all_invalid и отправлен на полную переиндексацию.
Возможности выполнить задачу indexer_reindex_all_invalid вручную средствами magento нет. Однако на помощь придет утилита N98-Magerun: https://github.com/netz98/n98-magerun2 . С ее помощью можно запустить эту задачу вот так:
123 php n98-magerun2.phar sys:cron:run indexer_reindex_all_invalidа вот так посмотреть список всех доступных задач
123 php n98-magerun2.phar sys:cron:list
Другой способ запустить переиндексацию, это выполнить консольную команду указав конкретный индексатор
1 2 3 |
php bin/magento indexer:reindex catalog_product_flat |
Так же из консоли можно перестроить все индексы сразу, для этого нужно просто опустить название индексатора
1 2 3 |
php bin/magento indexer:reindex |
В результате вы получите сообщение, что все индексы были перестроены
1 2 3 4 5 6 7 8 9 10 11 12 13 |
Design Config Grid index has been rebuilt successfully in <time> Customer Grid index has been rebuilt successfully in <time> Category Products index has been rebuilt successfully in <time> Product Categories index has been rebuilt successfully in <time> Catalog Rule Product index has been rebuilt successfully in <time> Product EAV index has been rebuilt successfully in <time> Inventory index has been rebuilt successfully in <time> Catalog Product Rule index has been rebuilt successfully in <time> Stock index has been rebuilt successfully in <time> Product Price index has been rebuilt successfully in <time> Catalog Search index has been rebuilt successfully in <time> |
Просмотреть статус индексов из консоли можно так
1 2 3 |
bin/magento indexer:status |
результат
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
+----------------------+------------------+-----------+---------------------+---------------------+ | Title | Status | Update On | Schedule Status | Schedule Updated | +----------------------+------------------+-----------+---------------------+---------------------+ | Catalog Product Rule | Reindex required | Save | | | | Catalog Rule Product | Reindex required | Save | | | | Catalog Search | Ready | Save | | | | Category Products | Reindex required | Schedule | idle (0 in backlog) | 2018-06-28 09:45:53 | | Customer Grid | Ready | Schedule | idle (0 in backlog) | 2018-06-28 09:45:52 | | Design Config Grid | Ready | Schedule | idle (0 in backlog) | 2018-06-28 09:45:52 | | Inventory | Ready | Save | | | Product Categories | Reindex required | Schedule | idle (0 in backlog) | 2018-06-28 09:45:53 | | Product EAV | Reindex required | Save | | | | Product Price | Reindex required | Save | | | | Stock | Reindex required | Save | | | +----------------------+------------------+-----------+---------------------+---------------------+ |
Тут
- Title = название индекса
- Status = статус индекса указывающий на то, требуется обновление или нет
- Update On = тип частичного реиндекса (см. следующий раздел)
- Schedule Status = Статус индексатора, указывающий на то, был ли он запущен или нет.
- Schedule Updated = Время обновления Schedule Status
Просмотреть id индексаторов из консоли можно так
1 2 3 |
bin/magento indexer:info |
выведет
1 2 3 4 5 6 7 8 9 10 11 12 13 |
design_config_grid Design Config Grid customer_grid Customer Grid catalog_category_product Category Products catalog_product_category Product Categories catalogrule_rule Catalog Rule Product catalog_product_attribute Product EAV inventory Inventory catalogrule_product Catalog Product Rule cataloginventory_stock Stock catalog_product_price Product Price catalogsearch_fulltext Catalog Search |
Подведем итоги по командам: php bin/magento <команда>
- indexer:status = покажет какие индексы требуют обновления
- indexer:info = покажет id всех индексаторов
- indexer:reindex = переиндексировать все индексы (все индексаторы будут запущены по очереди)
- indexer:reindex <id-индексатора> = запустить конкретный индексатор
Частичный реиндекс
Частичный реиндекс выполняется только для обновляемого элемента. Например, вы поменяли цену у товара в админке, и нужно обновить все связанные записи в индексных таблицах где участвует этот товар.
В Magento 2 существует два типа частичного реиндекса:
- Update on Save = данные обновляются в момент сохранения изменений
- Update by Schedule = измененные данные обновляются по расписанию
Для каждого из индексов, можно задать свой тип обновления. Например, индекс цен обновлять "по расписанию", а индекc категорий обновлять "в момент сохранения". Изменить эти настройки, можно в админке: Magento Admin > System > Tools > Index Management, затем отметить чекбоксами нужные индексы и выбрать нужный пункт в выпадающем списке "Actions"
Основное отличие двух способов, это производительность при перестроении индексов. Разберем каждый из способов подробнее.
Update on Save - используется в случае, если при сохранении не будет необходимости обновлять большое кол-во элементов. Например, у вас 3 категории и 50 товаров, тогда смело можно использовать этот способ. Кроме того, данный способ позволяет практически моментально синхронизировать изменения с витриной.
Update on Schedule - используется в случае, когда у вас огромное кол-во товаров или требуется перестроить индекс для большого кол-ва записей. Работает это так: id измененных записей накапливаются в отдельной таблице с постфиксом _cl, по расписанию запускается процесс индексации, который поочередно обновляет эти записи.
Конфигурация расписания Update on Schedule
Как вы уже знаете, индексы для которых указан тип индексации "Update on Schedule" будут запущены по расписанию.
Индексаторы запускаются в отдельной крон-группе: index. Настройки для данной группы задаются в админке, в разделе:
1 2 3 |
Magento Admin > Store > Configuration > Advanced > System > Cron (Scheduled Tasks) > Cron configuration options for group: index |
Расписание для индексаторов задается в файлe /vendor/magento/module-indexer/etc/crontab.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<!-- vendor/magento/module-indexer/etc/crontab.xml --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Cron:etc/crontab.xsd"> <group id="index"> ... <job name="indexer_update_all_views" instance="Magento\Indexer\Cron\UpdateMview" method="execute"> <schedule>* * * * *</schedule> </job> <job name="indexer_clean_all_changelogs" instance="Magento\Indexer\Cron\ClearChangelog" method="execute"> <schedule>0 * * * *</schedule> </job> </group> </config> |
Подробнее про настройки и то как работает планировщик можно прочитать тут: Magento 2: Планировщик задач
Тут мы видим 2 крона, связанных с частичным индексированием:
- ndexer_update_all_views - индексирует записи из таблиц имя-таблицы_cl
- indexer_clean_all_changelogs - очищает старые записи из таблиц имя-таблицы_cl
Прежде чем продолжать нам нужно разобраться с тем что такое MView и как это используется в Magento
MView
Mview это сокращение от Materialized Views или на русском Материализованное представление.
Материализо́ванное представле́ние — физический объект базы данных, содержащий результат выполнения запроса.
Материализованные представления позволяют многократно ускорить выполнение запросов, обращающихся к большому количеству (сотням тысяч или миллионам) записей, позволяя за секунды (и даже доли секунд) выполнять запросы к терабайтам данных. Это достигается за счет прозрачного использования заранее вычисленных итоговых данных и результатов соединений таблиц. Предварительно вычисленные итоговые данные обычно имеют очень небольшой объем по сравнению с исходными данными. Целостность данных в материализованных представлениях поддерживается за счёт периодических синхронизаций или с использованием триггеров.
Впервые появились в СУБД Oracle.
Если упростить, то суть в том, чтобы сделать выборку по сложному запросу и сохранить результаты этой выборки в виртуальной таблице. Далее, вы можете делать запросы по этой таблице, точно так же как по обычной. Данные в виртуальной таблице обновляются посредством полного обновления или триггеров.
Основное отличие View от Materialized View в том, что в первом случае виртуальная таблица всегда содержит актуальные данные, а в случае с Materialized View кешированные. Как результата Materialized View работает быстрее, хоть и требует дополнительных действий по обновлению данных.
MySQL не имеет поддержки Materialized View, поэтому вместо виртуальных таблиц используются реальные. В Magento это индексные и flat таблицы.
Как работает обновление данных
Прежде всего, нужно пойти в админки и выбрать для определенного индекса режим работы "Update by Schedule"
В момент изменения режима работы, в базе данных будет создана таблица с постфиксом _cl (у нас это catalog_product_flat_cl), а так же будут добавлены тригеры, отвечающие за то, чтобы сохранять change log-и, или проще говоря идентификатор того, что определенное значение в таблице было обновлено. Тригеры навешиваются на CRUD операции в базе, поэтому добавляется сразу несколько тригеров. В случае, если сущность является EAV, то тригеры будет сгенерированы для каждой из участвующих таблиц. Т.е. в нашем примере, будет добавлено 27 тригеров, для 3х операций (INSERT, UPDATE, DELETE) в 9 таблицах:
1 2 3 4 5 6 7 8 9 10 11 |
catalog_product_entity catalog_product_entity_datetime catalog_product_entity_decimal catalog_product_entity_gallery catalog_product_entity_int catalog_product_entity_media_gallery_value catalog_product_entity_text catalog_product_entity_tier_price catalog_product_entity_varchar |
Просмотреть тригеры можно такой командой
1 2 3 |
SHOW TRIGGERS FROM <db-name>; |
пример вывода
Если просмотреть запросы, мы заметим что все что делают эти тригеры, это добавление id сущности в таблицу с постфиксом _cl. Т.е. каждый раз при обновлении записи, в таблицу с постфиксом _cl будет добавлено новое значение. Если посмотреть структуру таких таблиц, то увидим что там сохраняется всего два значения version_id и entity_id. Поле version_id - является primary key с автоинкрементом, entity_id - id сущности которая поменялась.
Подведем промежуточный итог: при включении режима обновления индексов "Update by schedule" создается таблица с постфиксом _cl, а так же добавляются тригеры на изменения данных сущности, которые наполняют эту таблицу. Как только мы обновляем какой-то товар в админке, в таблицу catalog_product_flat_cl добавляется новое значение.
Далее, нам нужно обратить внимание на таблицу mview_state, которая содержит информацию о том какие индексы работают в режиме "Update by schedule", их статус и главное, последнее обработанное значение из _cl таблицы в поле version_id.
Теперь мы знаем что у нас есть catalog_product_flat_cl таблица где собраны id товаров которые обновились, а так же что в mview_state сохраняется последняя версия из этой таблицы, по которой изменения были внесены в индексную таблицу. Звучит запутанно, поэтому, лучше приведу пример, как это обновление работает.
- Каждую минуту запускается magento планировщик (про планировщик написано тут)
- Планировщик запускает индексатор, который называется indexer_update_all_views
- Этот индексатор, перебирает поочередно все записи имеющие mode=enabled из таблицы mview_state
- Далее он берет из этой таблицы mview_state.version_id и ищет в таблице catalog_product_flat_cl все version_id которые больше этого значения.
- Таким образом индексатор узнает какие записи обновились с момента последней обработки, а соответственно их нужно обновить в индексе
- Производит обновление индексов для этих записей
- Обновляет значение mview_state.version_id , на последнее обработанное
- Завершает работу
Как видите, все построено достаточно просто, по сути у нас есть список записей который были обновлены, и маркер последней обработанной индексатором записи. Берем все записи которые больше этого маркера, обновлем их и перезаписываем маркер.
Если присмотреться к списку шагов, вы не найдете шага с удалением обработанных записей из cl таблицы. Действительно, индексатор indexer_update_all_views не удаляет записи, которые он обработал, только меняет version_id на последний в таблице mview_state. За очистку старых данных в cl таблице отвечает другая задача, а именно indexer_clean_all_changelogs.
Объявления обоих индексаторов и связанных с ними классов находятся в файле: /vendor/magento/module-indexer/etc/crontab.xml
Под капотом indexer_update_all_views
Рассмотрим стек вызова индексаторов при запуске задачи indexer_update_all_views.
Я пока не определился с нормальным переводом view, view processor, indexer в используемом контексте, поэтому все три сущности буду называть индексатор, чтобы не путать терминами типа "вид", "процессор вида" и т.д.
Сперва запускается стандартный cron:run который согласно расписания определенного тут
/vendor/magento/module-indexer/etc/crontab.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<!-- vendor/magento/module-indexer/etc/crontab.xml --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Cron:etc/crontab.xsd"> <group id="index"> ... <job name="indexer_update_all_views" instance="Magento\Indexer\Cron\UpdateMview" method="execute"> <schedule>* * * * *</schedule> </job> ... </group> </config> |
добавляет соответствующие задачи, в таблицу cron_schedule. Далее, запуск этого же крона процессит записи из этой таблицы и в случае если запланированная дата запуска настала, запускает их, таким образом происходит вызов метода
1 2 3 4 5 |
Magento\Indexer\Cron\UpdateMview::execute vendor/magento/module-indexer/Cron/UpdateMview.php |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
<?php namespace Magento\Indexer\Cron; class UpdateMview { /** * @var \Magento\Indexer\Model\Processor */ protected $processor; /** * @param \Magento\Indexer\Model\Processor $processor */ public function __construct( \Magento\Indexer\Model\Processor $processor ) { $this->processor = $processor; } /** * Regenerate indexes for all invalid indexers * * @return void */ public function execute() { $this->processor->updateMview(); } } |
как видим тут ничего практически не происходит, поэтому обратимся к вызову находящемуся внутри метода execute
1 2 3 4 |
\Magento\Indexer\Model\Processor::updateMview vendor/magento/module-indexer/Model/Processor.php |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<?php namespace Magento\Indexer\Model; class Processor { ... /** * Update indexer views * * @return void */ public function updateMview() { $this->mviewProcessor->update('indexer'); } .. } |
как видим и тут не очень много полезного, опускаемся еще ниже
1 2 3 4 |
\Magento\Framework\Mview\Processor::update vendor/magento/framework/Mview/Processor.php |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
<?php namespace Magento\Framework\Mview; class Processor implements ProcessorInterface { /** * @var View\CollectionFactory */ protected $viewsFactory; /** * @param View\CollectionFactory $viewsFactory */ public function __construct(View\CollectionFactory $viewsFactory) { $this->viewsFactory = $viewsFactory; } /** * Return list of views by group * * @param string $group * @return ViewInterface[] */ protected function getViewsByGroup($group = '') { $collection = $this->viewsFactory->create(); return $group ? $collection->getItemsByColumnValue('group', $group) : $collection->getItems(); } /** * Materialize all views by group (all views if empty) * * @param string $group * @return void */ public function update($group = '') { foreach ($this->getViewsByGroup($group) as $view) { $view->update(); } } ... } |
тут все становится немного интереснее, а именно мы видим что выбираются индексаторы соответствующей группы (если она указана) и далее уже у индексаторов поочередно запускается метод update. Это означает, что если в одном из индексаторов произойдет ошибка которая прервет выполнение работы, то остальные индексаторы запущены не будут. Очередность можно получить с помощью вот такого простого скрипта, который надо положить в корневую диекторию проекта и запустить из консоли
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
<?php ini_set('display_errors', 1); ini_set('display_startup_errors', 1); ini_set('memory_limit', '5G'); error_reporting(E_ALL); require 'app/bootstrap.php'; $bootstrap = \Magento\Framework\App\Bootstrap::create(BP, $_SERVER); $objectManager = $bootstrap->getObjectManager(); /** @var $state \Magento\Framework\App\State */ $state = $objectManager->get(\Magento\Framework\App\State::class); $state->setAreaCode(\Magento\Framework\App\Area::AREA_GLOBAL); /** @var $state \Magento\Framework\Mview\Processor */ $mview = $objectManager->create(\Magento\Framework\Mview\Processor::class); $r = new ReflectionMethod($mview, 'getViewsByGroup'); $r->setAccessible(true); $collection = $r->invoke($mview, 'indexer'); foreach($collection as $item) { echo $item->getViewId().PHP_EOL; } |
Выполнятся следующие индексаторы сверху вниз
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
design_config_dummy customer_dummy catalog_category_product catalog_product_category catalogrule_rule catalog_product_attribute cataloginventory_stock inventory catalogrule_product catalog_product_price targetrule_product_rule targetrule_rule_product salesrule_rule catalogsearch_fulltext catalogpermissions_category catalogpermissions_product |
по-умолчанию, индексаторы имеют тип
1 2 3 4 |
Magento\Framework\Mview\View vendor/magento/framework/Mview/View.php |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
class View extends \Magento\Framework\DataObject implements ViewInterface { ... public function update() { if ($this->getState()->getStatus() == View\StateInterface::STATUS_IDLE) { try { $currentVersionId = $this->getChangelog()->getVersion(); } catch (ChangelogTableNotExistsException $e) { return; } $lastVersionId = (int) $this->getState()->getVersionId(); $action = $this->actionFactory->get($this->getActionClass()); try { $this->getState()->setStatus(View\StateInterface::STATUS_WORKING)->save(); $versionBatchSize = self::$maxVersionQueryBatch; $batchSize = isset($this->changelogBatchSize[$this->getChangelog()->getViewId()]) ? $this->changelogBatchSize[$this->getChangelog()->getViewId()] : self::DEFAULT_BATCH_SIZE; for ($versionFrom = $lastVersionId; $versionFrom < $currentVersionId; $versionFrom += $versionBatchSize) { // Don't go past the current version for atomicy. $versionTo = min($currentVersionId, $versionFrom + $versionBatchSize); $ids = $this->getChangelog()->getList($versionFrom, $versionTo); // We run the actual indexer in batches. Chunked AFTER loading to avoid duplicates in separate chunks. $chunks = array_chunk($ids, $batchSize); foreach ($chunks as $ids) { $action->execute($ids); } } $this->getState()->loadByView($this->getId()); $statusToRestore = $this->getState()->getStatus() == View\StateInterface::STATUS_SUSPENDED ? View\StateInterface::STATUS_SUSPENDED : View\StateInterface::STATUS_IDLE; $this->getState()->setVersionId($currentVersionId)->setStatus($statusToRestore)->save(); } catch (\Exception $exception) { $this->getState()->loadByView($this->getId()); $statusToRestore = $this->getState()->getStatus() == View\StateInterface::STATUS_SUSPENDED ? View\StateInterface::STATUS_SUSPENDED : View\StateInterface::STATUS_IDLE; $this->getState()->setStatus($statusToRestore)->save(); throw $exception; } } } ... } |
если убрать разбиение на группы и переключение статусов, то мы увидим что тут из view берется action_class и у него вызывается метод execute с передачей внутрь id-шек которые нужно проиндексировать:
1 2 3 4 5 6 7 |
$action = $this->actionFactory->get($this->getActionClass()); ... foreach ($chunks as $ids) { $action->execute($ids); } |
эти $action'ы - это классы определенные в файлах etc/indexer.xml , пример
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
vendor/magento/module-catalog-rule/etc/indexer.xml <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Indexer/etc/indexer.xsd"> <indexer id="catalogrule_rule" view_id="catalogrule_rule" class="Magento\CatalogRule\Model\Indexer\Rule\RuleProductIndexer" shared_index="catalogrule"> <title translate="true">Catalog Rule Product</title> <description translate="true">Indexed rule/product association</description> </indexer> <indexer id="catalogrule_product" view_id="catalogrule_product" class="Magento\CatalogRule\Model\Indexer\Product\ProductRuleIndexer" shared_index="catalogrule"> <title translate="true">Catalog Product Rule</title> <description translate="true">Indexed product/rule association</description> </indexer> <indexer id="catalog_product_price"> <dependencies> <indexer id="catalogrule_rule" /> </dependencies> </indexer> </config> |
вот полный список классов по-умолчанию для упомянутых индексаторов
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
design_config_dummy => Magento\Framework\Indexer\Action\Dummy customer_dummy => Magento\Framework\Indexer\Action\Dummy catalog_category_product => Magento\Catalog\Model\Indexer\Category\Product catalog_product_category => Magento\Catalog\Model\Indexer\Product\Category catalogrule_rule => Magento\CatalogRule\Model\Indexer\Rule\RuleProductIndexer catalog_product_attribute => Magento\Catalog\Model\Indexer\Product\Eav cataloginventory_stock => Magento\CatalogInventory\Model\Indexer\Stock inventory => Magento\InventoryIndexer\Indexer\Mview\Action catalogrule_product => Magento\CatalogRule\Model\Indexer\Product\ProductRuleIndexer catalog_product_price => Magento\Catalog\Model\Indexer\Product\Price targetrule_product_rule => Magento\TargetRule\Model\Indexer\TargetRule\Product\Rule targetrule_rule_product => Magento\TargetRule\Model\Indexer\TargetRule\Rule\Product salesrule_rule => Magento\AdvancedSalesRule\Model\Indexer\SalesRule catalogsearch_fulltext => Magento\CatalogSearch\Model\Indexer\Mview\Action catalogpermissions_category => Magento\CatalogPermissions\Model\Indexer\Category catalogpermissions_product => Magento\CatalogPermissions\Model\Indexer\Product |
далее логика реализации отличается у каждого индексатора, поэтому каждый нужно рассматривать отдельно.
Заключение
Magento - на первый взгляд имеет очень сложную архитектуру, однако разобравшись в том, как и что устроенно становится понятно, что вся эта сложность является необходимостью для построения изящных решений в сложных задачах.
Статья получилась большая, и может содержать некоторые логические ошибки в названиях происходящих процессов, поэтому если заметите, дайте знать в комментариях.
Полезнае ссылки
- Essential Magento 2 Partial Reindexing: https://www.bigbridge.nl/blog/essential-magento-2-partial-reindexing/
- What is mview in magento2: https://magento.stackexchange.com/questions/117030/what-is-mview-in-magento2/121000#121000
- Indexing overview: https://devdocs.magento.com/guides/v2.3/extension-dev-guide/indexing.html
- Manage the indexers: https://devdocs.magento.com/guides/v2.3/config-guide/cli/config-cli-subcommands-index.html
Author: | Tags: /
| Rating:
Leave a Reply