【发布时间】:2018-10-16 15:21:02
【问题描述】:
我正在尝试通过解析 ASCII 文件 (3.5MB) 并仅使用 Prestashop 的 API 在 Prestashop 电子商务中定期有效地导入 15K+ 产品。
全部在 docker 下运行,官方镜像来自 docker hub。
如果不存在具有相同参考字段的产品,我将不得不插入一个新产品,如果它存在的话以更新它。 我开发了一个模块,通过单击自定义管理选项卡,它可以工作,但整个系统冻结,直到过程完成或终止:(几乎 77 分钟)。 我还尝试将(不是那么大的)大文件分成 500、100、50 的块,但处理时间线性减少,它没有多大帮助:
- 500 个元素平均 153 秒
- 100 个元素平均 31 秒
- 50 个元素平均 15 秒
我当然可以每 90 秒配置一个 cron 来处理 50 个元素,并在每晚 7-8 小时内完成整个导入,但这似乎是一个非常糟糕的折衷方案:每 90 秒脱机 15 秒。
我不能使用pthreads,因为这将是一个生产网络服务器。
我尝试调整 Apache,增加 memory_limit、max_input_vars、max_execution_time 但没有任何差异:使用 450MB 到 550MB RAM 的 DB 和服务器几乎相同。
Linux #1 SMP Debian 4.9.110-3+deb9u6 (2018-10-08) x86_64
版本软件删除服务器:Apache/2.4.10 (Debian)
PHP 版本:5.6.35
memory_limit=2048M
max_input_vars=1000000
max_execution_time=600000
MySQL:5.6.40
我是不是以错误的方式解决了这个问题,或者 Prestashop 的 API 不是高性能的并且是为批量(和高性能)产品导入而设计的?
public function batchImportAllProductsFromFile($productsToBeInserted){
foreach ($productsToBeInserted as $key => $customProduct ) {
$productIDs = $this->getProductIDsByReference($customProduct->MS_CODMAG);
if (sizeof($productIDs) == 0) {
$product = new Product();
} else if (sizeof($productIDs) == 1) {
$product = new Product($productIDs[0]);
} else {
continue;
}
$product->reference = $customProduct->MS_CODMAG;
$product->name = trim($customProduct->MS_DESCRIZIONE);
$product->price = $customProduct->MS_PREZZO_1;
$product->out_of_stock = ($customProduct ->MS_ESAURITO === "S" ? true : false);
$category = null;
$msGruppoConverted = $this->buildSubGroupCode($customProduct->MS_GRUPPO, $customProduct->MS_SGRUPPO);
if ($customProduct->MS_GRUPPO !== 0 && $msGruppoConverted !== 0) {
$product->id_category = [$customProduct->MS_GRUPPO, $msGruppoConverted];
} else if ($customProduct->MS_GRUPPO === 0 && $msGruppoConverted !== 0) {
$product->id_category = [$msGruppoConverted];
} else if ($customProduct ->MS_GRUPPO !== 0 && $msGruppoConverted === 0) {
$product->id_category = [$customProduct->MS_GRUPPO];
}
try {
if (sizeof($productIDs) == 0) {
if ($product->add()) {
$product->updateCategories($product->category);
$product->addFeatureProductImport($product->id, 1, $customProduct->MS_FAM);
//StockAvailable::setQuantity((int)$product->id, 0, $product->quantity, Context::getContext()->shop->id);
}
} else if (sizeof($productIDs) == 1) {
if ($product->update()) {
$product->updateCategories($product->category);
$alreadySavedFeatures = $product->getFeaturesStatic($productIDs[0]);
if (sizeof($alreadySavedFeatures) != 1 || $alreadySavedFeatures[0] != $customProduct->MS_FAM) {
$product->deleteProductFeatures();
$product->addFeatureProductImport($product->id, 1, $customProduct->MS_FAM);
}
}
}
} catch (Exception $e) {
var_dump("Errore: ", $e, $product);
}
}
}
2018 年 10 月 22 日编辑:
升级到 PHP7.2 并使用 MariaDB 10.3.10 并没有给我带来任何变化:时间仍然相同。 带来的好处是在 /etc/fstab 中使用选项 barrers=0 安装数据库存储信息的 FS (EXT4):性能从 153 秒提高到 35 秒500 个元素,总共大约 18 分钟(原为 77 个)。
仍然存在的问题是为什么系统在导入时变得无响应。
【问题讨论】:
-
您是否尝试过将 SQL 引擎从 MyISAM(我想)切换到 InnoDB 以避免任何表锁定问题?此外,切换到 PHP 7+ 和 MariaDB 可能会大大提高您的性能。
-
DB 和所有表(CRON 的 2 个表除外)已经是 InnoDB,但感谢有关 PHP 7+ 和 MariaDB 的提示:我将使用 PHP7.2 和MariaDB 10.3.10 并试一试
标签: php mysql apache prestashop-1.7