功能需求:批量插入更新产品数据。
工作流程:将需要更新的产品数据(csv)+产品图片压缩成一个 zip 文件,上传至服务器指定目录,然后通过 web 方式,解压 zip 文件,读取解析 csv 文件,分离出产品的主要数据和属性数据,并根据 csv 中每一个产品的 ID 获取该产品的图片路径,然后复制图片到以产品序号命名的文件夹中,然后通过字符串连接的方式,组成多条 SQL 语句,最后统一插入数据库。 另外,产品的搜索使用 elasticsearch ,所以在更新产品数据时,同时需要更新 elasticsearch 中的数据。
ZIP 文件结构: 1,product.csv 2,以 csv 中每一条产品的 ID 为命名的文件夹,文件夹里包含三个文件夹(缩略图,产品图,附件),缩略图为一个图片,产品图和附件为多个文件; 3 , csv 文件和产品 ID 为命名的文件夹同级;
涉及到的数据表: 1,product:存储产品的主要数据:标题,缩略图,单价,详细描述,店铺 ID ,创建人 ID ,分类 ID 等等 2,product_attribute:存储产品的属性数据:规格,尺寸,重量,以及其他属性内容; 3,product_images:存储产品图片以及附件,根据其中 type 字段进行区分
服务器配置(均为阿里云服务器): 1,测试服务器:CPU:2 核,内存:4G 内存,mysql 在服务器上; 2,线上服务器:CPU:4 核,内存:8G 内存,mysql 为单独的 RDS:CPU:1 核,内存:1G 内存,最大连接数为 300;
PHP 框架: Symfony 3 数据插入语句是: $productAttachmentSQLExec = $dataConnection->prepare($productAttachmentSQL); $productAttachmentSQLExec->execute();
现在遇到的问题是: 就算处理一个 100M 以内的压缩包,都会导致内存溢出,数据导入不成功, csv 中的数据仅仅为 100 多条数据; 经过测试,如果只解析 csv 文件,就算有 1 万条数据,都可以处理,但是要涉及到图片的处理,就内存溢出。
我想过通过写 shell 脚本来处理 zip 的解压以及移动,但是不熟悉这个 shell 脚本的编写,所以进行不下去。
请教下 V2 上的朋友,有没有好的解决方案。
1
yangqi 2017-03-11 06:16:41 +08:00
你不要告诉我你们图片直接存数据库里面?
好的解决方案就是把图片寸硬盘上,数据库最多存个图片的路径名 |
2
willakira 2017-03-11 07:23:15 +08:00
图片处理?是压缩么
不用存在数据库,否则很难用 nginx 之类的加速 顺便说下 4G 内存解压一个 100M 的普通压缩包绰绰有余(只要你不在内存里面做其他操作) |
3
fuxkcsdn 2017-03-11 08:25:11 +08:00 via iPhone
主要是压缩包里的图片解压后导致 php 内存溢出,很明显楼主犯了和这个链接的 po 主一样的错误
http://stackoverflow.com/questions/3263129/unzipping-larger-files-with-php |
4
Time2 2017-03-11 08:39:38 +08:00
可以使用 生成器 的 yield 关键字,来读取 csv 文件 ,会减少发部分内存消耗。
|
5
Time2 2017-03-11 08:43:09 +08:00
忽略 4 楼。我没看清 lz 需求...
|
6
likezun 2017-03-11 09:04:05 +08:00
看见 Symfony 3 好评!
|
7
Felldeadbird 2017-03-11 09:04:08 +08:00 via iPhone 1
1.每次循环处理完图片,记得释放内存。删除没用的变量数组,降低内存的消耗。
2.如果还不行,就将图片处理部分异步。先将图片地址丢到数据库和临时目录,然后 cli 命令下定时处理。 3.楼主上传 csv 是通过 web 形式吧?这个肯定是有内存限制的,或者做异步处理,文件先上传到服务器,然后 cli 定时脚本处理,处理成功发送通知… |
8
likezun 2017-03-11 09:05:11 +08:00
我也觉得 4G 内存解压一个 100M 绰绰有余;
内存溢出? 内存限制多少? |
9
MrMike OP @Felldeadbird
@yangqi 图片肯定不是存储在数据库的,是存在硬盘上的。 csv 在压缩包里,是先通过 ftp 上传到服务器后,再通过 web 的方式进入网站后台去进行在线解压缩并解析 csv 插入更新数据库的。 内存,测试服务器上是 2G,线上服务器是 4G 。 我想过异步处理,但是对 shell 脚本不熟,所以没有完全实现。 谢谢。 |
10
yangqi 2017-03-11 11:12:22 +08:00
|
11
qhxin 2017-03-11 11:21:41 +08:00
php 进程的内存限制配置的多少?
|
12
MrMike OP @yangqi 代码单独解析 csv 文件的话, 1 万条数据没问题,但是如果再解析每一个产品所对应的产品图片,获取对应的图片路径,再插入数据库的话,就内存溢出了。我是把一万条数据组成一条 MYSQL INSERT INTO 语句一次性插入的,我直接将生成的 MYSQL 语句单独使用 PHPMYADMIN 进行插入,是完全可以执行的。但是一旦放在代码里,就不行。
|