-
13-12-2019 - |
题
这个问题对我来说已经有一段时间没有答案了,我想从某人那里得到关于它是如何工作的明确答案。
设想:
运行 Magento 1.14.2.1,我已将所有索引器设置为按计划运行,并且运行 Magento cron 来运行 enterprise_refresh_index
每当任何东西需要部分(或完全?)索引时。
在升级到此版本之前,我运行的是 1.13.1 并且没有使用 cron。我已将索引器设置为打开 节省, ,每当我需要强制任何索引器运行时,我都会通过 shell/indexer.php
或使用以下代码示例:
// Example of indexers passed in:
$indexers = ['catalog_product_flat', 'catalog_category_flat'];
foreach ($indexers as $code) {
$process = Mage::getSingleton('index/indexer')
->getProcessByCode($code)
->reindexEverything();
}
之前...
以前这种方法工作得很好,可以让索引器在我想要的时候立即运行,并且将所需的各种更改相对快速地传播到前端等。
显然,当我们有多个管理员用户同时保存产品等时,我们遇到了死锁/表锁定问题和索引器相互冲突,因此我们转向使用 Magento cron 来处理这一切的新“最佳实践”日程。
我的问题:
- 如何取代强制产品扁平重新索引的旧方式(
php shell/indexer.php --reindex catalog_product_flat
)现在通过预定的 cron 作业进行等效操作?我似乎只看到你可以跑enterprise_refresh_index
cron 作业,但这可以处理 所有索引器 对吧——没有能力挑出某些部分? - 是否还需要再这样做?我的意思是,通过执行前面的命令,Magento 是否仍然只对目录产品平面领域内所需的内容建立索引,并且通过运行计划任务,它会执行相同的操作,但将所有索引器合并为一个?如果是这样的话,那也没关系——只是理解起来很混乱。
背景:
我在 Magento EE 支持下问过这个问题。他们回来说,它属于支持协议的范围,但仍然从一个Magento Devs获得了答案,并回答我说:“对数据库的更改是用触发器检测到的,并创建了ChangElog记录。”我了解到,从这里开始,计划的索引器决定基于那些ChangElog记录需要做什么。
我之前假设,如果我需要重新索引产品平面表(所有产品,所有内容),我会像前面的示例一样从命令行执行此操作。如果它只会重新索引它知道应该通过变更日志完成的内容,我现在如何实现同样的目标?有没有办法重新索引 全部 产品平面数据,而不通过它捕获所有其他索引器 enterprise_refresh_index
?
我不认为它相关,但我们使用 AOE_Scheduler 模块来更好地了解 cron 正在做什么。
我知道这很长。如果我能总结得更好一点,请告诉我。我没有运气得到明确的答案,并且一些管理员用户不相信 Magento cron 每次都会有效地重新索引所有内容。当做出这种声明时,我通常会从 CLI 重新索引所有产品平面数据,但我不能再这样做了,因为它会导致与计划的索引器发生冲突,一切都会崩溃。
解决方案
public function refreshIndex(Mage_Cron_Model_Schedule $schedule)
{
/** @var $helper Enterprise_Index_Helper_Data */
$helper = Mage::helper('enterprise_index');
/** @var $lock Enterprise_Index_Model_Lock */
$lock = Enterprise_Index_Model_Lock::getInstance();
if ($lock->setLock(self::REINDEX_FULL_LOCK)) {
/**
* Workaround for fatals and memory crashes: Invalidating indexers that are in progress
* Successful lock setting is considered that no other full reindex processes are running
*/
$this->_invalidateInProgressIndexers();
$client = Mage::getModel('enterprise_mview/client');
try {
//full re-index
$inactiveIndexes = $this->_getInactiveIndexersByPriority();
$rebuiltIndexes = array();
foreach ($inactiveIndexes as $inactiveIndexer) {
$tableName = (string)$inactiveIndexer->index_table;
$actionName = (string)$inactiveIndexer->action_model->all;
$client->init($tableName);
if ($actionName) {
$client->execute($actionName);
$rebuiltIndexes[] = $tableName;
}
}
//re-index by changelog
$indexers = $helper->getIndexers(true);
foreach ($indexers as $indexerName => $indexerData) {
$indexTable = (string)$indexerData->index_table;
$actionName = (string)$indexerData->action_model->changelog;
$client->init($indexTable);
if (isset($actionName) && !in_array($indexTable, $rebuiltIndexes)) {
$client->execute($actionName);
}
}
} catch (Exception $e) {
$lock->releaseLock(self::REINDEX_FULL_LOCK);
throw $e;
}
$lock->releaseLock(self::REINDEX_FULL_LOCK);
}
return $this;
}
这在每次 cron 执行时“始终”运行。它对所需的索引运行完整的重新索引,并为不需要的索引处理更改日志。
此外,您仍然可以运行 CLI shell 脚本,但它们不会考虑部分更改日志,并且会盲目地执行完整的重新索引。
如果遇到死锁,您可能需要将所有索引器设置为 Manual
并设置替代流程以在非高峰时间(当管理员不在时)重建索引。仅有的 产品价格 和 库存状况 应设置为“保存时更新”。
另请记住,部分重新索引状态 index_process
表不再使用,但计算自 enterprise_mview_metadata
.
禁用一些内部模块,例如 Mage_Rss
还可以帮助影响索引失效的频率。
进一步阅读:
其他提示
顺便说一句,我最近遇到了 AOE_EeIndexerStats 来自 GitHub 上 AOEpeople 的模块 - 快速浏览一下,它似乎允许您控制索引器的某些部分或整个索引器,这些都包含在 enterprise_refresh_index
. 。这可能与之前的流程等效,您可以在其中定位 catalog_product_flat
索引本身。
它也应该可以在代码中访问,如下所示:
$client = Mage::getModel('enterprise_mview/client'); /* @var $client Enterprise_Mview_Model_Client */
$client->initByTableName($tablename);
$metadata = $client->getMetadata();
$metadata->setInvalidStatus();
$metadata->save();