php 大文件上传 redis+php resque 较低io消耗

在做视频站的时候存在这么一个情景,用户需要上传较大的视频文件,一般在两个G以上,且可能存在多人同时上传的情况。

经过查阅资料解决方案有如下几种:

1、调整php和nginx文件上传的最大限制

2、在前端将文件切片上传后再进行合并

经过我们的评估发现,方案1的做法并不合适,单纯的调大文件大小限制,会导致上传一个文件需要一个连续很长的时间, 占用一个php进程,且可能出现超时等各种情况。

所以我们选择方案二进行探索:

使用百度webuploader前端插件对大文件进行切片处理,等待所有文件全部上传完毕后再进行合并。

但是用着用着凸显出一些问题:

1、大文件在完全上传完毕后,把一个一个小的切片文件合并成一个大文件,这个时间可能是很长的,很有可能超过php或者nginx的超时限制,这样给用户的就是超时提醒,是极为不友好的。

2、文件在合并的时候需要连续长时间的写入到磁盘中,对服务器io压力很大,如果mysql在同一台服务器上也将对整个网站产生压力。

3、多人同时上传,且差不多同一时间上传完毕,再合并对服务器的压力将更大。。。超时问题也将更加的严重。

4、php接收上传的文件临时区默认是在磁盘上,整个流程就是接收->写入磁盘->上传完毕->读取切片文件->写入磁盘,整个流程对服务器压力较大。

经过查找资料(但是没找到太多,难道是关键词不对)我们想出了如下大致的解决方案

1、修改php文件上传存放的临时目录,放到ubuntu分配的内存文件目录,减少io。

2、将上传完毕再合成修改为边上传边合并,这样用户发完最后一个文件就能很快的得到上传成功或失败的提醒,同时减少了上面提到的连续长时间磁盘io。

第1点没什么说的,修改php配置即可,但是需要注意的是内存的大小限制。

难点主要在第2点中:

具体如下:

1、切片上传的文件是无序的,可能上传切片的顺序是1、5、3、4、2这样的,如何保证合并的顺序?

2、同一用户同时上传多个文件?

3、不同用户上传同名文件,如何命名?

这里主要针对难点1的解决方案进行阐述:

需要的两个工具:redis和任务调度框架php resque

利用redis维护

一个有序集合(存储已经上传的切片文件编号,有序是因为合并切片需要切片的顺序)

and

一个普通列表(存储已经合并的切片编号,用于判读切片是否连续)

php resque去发起合并任务(每个上传的文件对应唯一的任务标志id)

根据php resque的任务状态确保同一个文件同时只有一个合并任务在进行

每次切片上传成功后,向该上传文件的有序集合中,添加一个数据,键为切片序号,值也为切片序号

php resque中的job内容:参数主要为(临时文件名、切片文件总长度,最终保存的文件名)

job:

循环执行:

从有序集合从取第一小的切片号,判断该切片号-1是否已经在已经合并的切片的普通列表中(切片为1直接开始合并),不在的话循环结束

读取切片号对应的文件,写入到最终的文件中,最刚开始不存在则创建。

写入完毕后,向切片列表中加入该切片编号

删除该切片文件

继续循环

如果切片号==文件切片长度,任务over

原文地址:https://www.cnblogs.com/Lynwood/p/9650603.html

时间: 2024-09-30 19:43:07

php 大文件上传 redis+php resque 较低io消耗的相关文章

基于Nodejs的大文件上传之断点续传

接着<扒一扒Nodejs formidable的onPart>和<也说文件上传之兼容IE789的进度条---丢掉flash>:前面已完成兼容IE789的大文件上传:无flash的低版本进度条,高版本的分段上传,并已为断点续传做好铺垫: 说什么做好铺垫,原本以为Nodejs端已没问题,只剩前端依靠HTML5接着监听abort事件,保存中断时上传到第几块了(断点续传只支持文件比较大,然后意外上传中断了,暂时定50M开启断点续传吧),通过文件内容hash和该文件唯一上传token来记录断

web大文件上传解决方案支持分片断点上传

一. 功能性需求与非功能性需求 要求操作便利,一次选择多个文件和文件夹进行上传:支持PC端全平台操作系统,Windows,Linux,Mac 支持文件和文件夹的批量下载,断点续传.刷新页面后继续传输.关闭浏览器后保留进度信息. 支持文件夹批量上传下载,服务器端保留文件夹层级结构,服务器端文件夹层级结构与本地相同. 支持大文件批量上传(20G)和下载,同时需要保证上传期间用户电脑不出现卡死等体验:支持文件夹上传,文件夹中的文件数量达到1万个以上,且包含层级结构. 支持断点续传,关闭浏览器或刷新浏览

JavaScript大文件上传解决方案实例代码

一. 功能性需求与非功能性需求 要求操作便利,一次选择多个文件和文件夹进行上传:支持PC端全平台操作系统,Windows,Linux,Mac 支持文件和文件夹的批量下载,断点续传.刷新页面后继续传输.关闭浏览器后保留进度信息. 支持文件夹批量上传下载,服务器端保留文件夹层级结构,服务器端文件夹层级结构与本地相同. 支持大文件批量上传(20G)和下载,同时需要保证上传期间用户电脑不出现卡死等体验:支持文件夹上传,文件夹中的文件数量达到1万个以上,且包含层级结构. 支持断点续传,关闭浏览器或刷新浏览

【原创】用JAVA实现大文件上传及显示进度信息

用JAVA实现大文件上传及显示进度信息 ---解析HTTP MultiPart协议 一. 大文件上传基础描述: 各种WEB框架中,对于浏览器上传文件的请求,都有自己的处理对象负责对Http MultiPart协议内容进行解析,并供开发人员调用请求的表单内容. 比如: Spring 框架中使用类似CommonsMultipartFile对象处理表二进制文件信息. 而.NET 中使用HtmlInputFile/ HttpPostedFile对象处理二进制文件信息. 优点:使用框架内置对象可以很方便的

Socket大文件上传

1 public sealed class SocketData 2 { 3 private SocketData() 4 { 5 } 6 7 public static SendFileMode SendFile(Socket socket, string fileName, int maxBufferLength) 8 { 9 SendFileMode flag = SendFileMode.Success; 10 try 11 { 12 using (Stream fs = new Fil

IIS中的大文件上传问题解决方法

IIS出于安全考虑限制了大文件的上传,而网上百度到的大部分解决方法都是用一个管理员权限的记事本打开一个文件修改参数,但是我发现里面根本没有网上所说的那些参数,最后自己找到了修改发布文件的webconfig的方法解决的IIS对大文件上传的限制. 首先在system.web中加入以下代码 [csharp] view plain copy <httpRuntime maxRequestLength="2097151"//最大上传长度 useFullyQualifiedRedirectU

Nodejs+HTML5兼容IE789的大文件上传完整版

业余将大文件上传重新梳理了一遍,后端基于Nodejs:有几个要点感觉很好玩: 兼容性:IE789为代表: 跨域上传:document.domain||middlePage: 多文件上传:input['type=file'] multiple: 拖拽上传:drag drop: 大文件分段:files.slice(s,e): 断点续传:localStorage: 接收分段的文件:formidable.onPart: 陆续写入分段文件:fs.write(fd,bf,offset,length,posi

C# 大文件上传

IHttpModule 分块上传大文件 IHttpModule 分块上传大文件 来源:http://www.cnblogs.com/HeroBeast/archive/2008/03/18/1084874.html 1.一般的在Asp.net里上传文件都是10m左右,要做到大文件上传,必须要改web.config,不过改了web.config有时候也上传不成功,那是每次上传的文件太大,浏览器在这个过程中会超时,采用分块上传的方法就可以避免这种情况. 2.分块上传就是利用post的方法,把数据分块

gitlab使用过程中遇到大文件上传或下载失败的问题,总结一下

环境如下:gitlab服务器redhat,客户端环境mac os,如果是其他环境遇到问题仅供参考 如果gitlab上传代码提示: error: RPC failed; result=22, HTTP code = 411 该问题是由于客户端设置的http_post_buffer大小不足导致的,解决方法如下: 进入到工程所在的终端目录下执行: git config http.postBuffer 524288000 如果gitlab上传代码提示: error: RPC failed; result