如何提升大容量文件上传性能

摘要:
我学到了一些优化思想,并在这里与您分享。请参见以下细分~~~在业务流程优化方面,为了提高上传大型文件的效率和容错性,可以在流程中实现三个功能步骤。上传大块文件。详细分析要优化文件上载性能,您必须首先了解服务器文件上载的过程。
背景

618压测过程中,涉及大规格的参数化文件上传平台,由于文件过大超过2G,在平台上传过程中经常失败,超时,重试也要等老半天,这就会造成人力资源等待影响工作效率。那么应该怎么做才能快速上传,如何提高文件上传性能以及做到就算失败了再次重试也能从上次中断的地方继续上传提升系统的容错能力呢 ?我学习整理了一些优化思路,在此分享给大家,请君看下文分解~~~

 

从业务流程上优化

为提升大文件上传效率和容错性,从流程上可实现3个功能步骤。

  • 大文件分片上传。
  • 支持断点续传。
  • 上传进度展示。

如何提升大容量文件上传性能第1张

从系统底层上优化

总思路原则

降时延,提并发

  1. 减少磁盘的工作量,如pagecache技术(磁盘高速缓存)。
  2. 减少CPU的工作量,如直接IO技术。
  1. 提高内存的利用率,如零拷贝技术。

 

详细解析

要优化文件上传性能,必须先了解服务器文件上传的过程。

过程

发送文件上传请求后,首先磁盘读取文件,然后通过网络协议发送给客户端。

客户端请求从磁盘找到文件位置,然后从磁盘把部分文件(切分后)读入缓冲区,然后通过网络把数据发送给客户端,如下图:

如何提升大容量文件上传性能第2张

问题

1.上下文切换

一次收发过程涉及到4次用户态和内核态的上下文切换,没处理缓冲区大小的数据需要一次read调用和一次write调用,每次调用都需要从用户态切换到内核态。然后等内核态完成任务后,再切换回用户态,如果文件大,分片较多,读取次数比较多,上下文切换的成本不容小觑。

 

2.多次内存拷贝

磁盘-》pagecache

pagecache->用户缓冲区

用户缓冲区->socket缓冲区

socket缓冲区->网卡

多次内存拷贝,消耗过多的CPU资源,降低系统并发能力,表现为CPU系统态占用过高

 

解决思路方案

零拷贝技术

降低上下文切换

首先读取磁盘文件的上下文切换是一定会有的,因为读取磁盘和操作网卡都是由操作系统内核完成,所以我们再执行read或write这种系统调用时,一定会经过2次上下文切换:先从用户态切换到内核态,当内核态任务完成后,再切换回用户态交由进程代码执行。所以想要降低上下文切换就需减少系统调用次数。解决办法是把read和write两次系统调用合并成一次,在内核态中完成磁盘与网卡的数据交换操作。

减少内存拷贝次数

一次收发过程有两次与物理设备相关的内存拷贝是必不可少的:1.把磁盘的数据拷贝到内存,2.把内存的数据拷贝到网卡,而用户缓冲区相关的拷贝则不是必须的,故可以在内核读取文件后,直接把pagecache中的数据拷贝socket缓冲区,这样就只有2次上下文切换和3次内存拷贝,如果网卡支持SG-DMA技术,还可以把拷贝到socket缓冲区的步骤省略,如下图:

如何提升大容量文件上传性能第3张

 如何提升大容量文件上传性能第4张

PageCache磁盘高速缓存技术

根据时间局部性原理,刚被访问到的数据在短时间被再次访问的概率高,通常将最近访问的数据放到pagecache中,当空间不足时根据LRU算法淘汰最久未被访问的数据。

pagecache提供预读功能,但不适合传输大文件,因为大文件容易把pagecache占满,而且由于文件过大,文件中某一部分的数据被再次访问的概率低,这会导致大文件在pagecache中没有享受到缓存的优势。

异步IO&直接IO技术

异步IO可以把读操作分为两个部分,前部向内核发起读请求,但不用等待数据就位就返回,然后可以继续处理其他任务,当内核把磁盘中的数据拷贝到进程缓冲区后,会通知进程去处理数据,异步IO是不会阻塞用户进程的,能提升并发操作。

对于磁盘,异步IO只支持直接IO,即应用程序绕过pagecache,不经过内核缓存区,直接访问磁盘中的数据,从而减少了内核缓存与用户程序之间的数据拷贝。

因为直接IO不适用pagecache缓存,所以享受不到内核针对pagecache做的一些优化,这是不足之处。故直接IO适应的应用场景:1.应用程序已经自己实现了磁盘文件的缓存,不需要pagecache再次进行缓存,引发额外的性能消耗;2.高并发下传输大文件,因为大文件难以命中pagecache缓存,又会影响其他热点小文件缓存。

 如何提升大容量文件上传性能第5张

方法论

从系统层面的优化思路上看,大文件交给异步IO和直接IO技术处理,小文件交给零拷贝技术处理。

 

免责声明:文章转载自《如何提升大容量文件上传性能》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇js forEach参数详解,forEach与for循环区别,forEach中如何删除数组元素NGUI系列教程二下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

做日文编码网页解决乱码的经验。(仇日派别砍我~~)

不得已做日文网页,虽然只有几个页面,但是费了好多时间,极郁闷。 一:页面编码要如下设置: <meta http-equiv="Content-Type" content="text/html; charset=shift_jis"> 二:把客户发过来的日文拷贝进去,居然变乱码!先拷贝到文本文件中再拷贝到网页中也变乱码!折腾了很久………   ...

[转载]Linux C编程-实现文件夹的递归拷贝

copy(读取的路径或名字,目标文件的路径或名字) {        if(读取的是一个文件夹)        {     创造一个文件夹              打开文件夹,读取文件夹的内容              判断是否是一个文件夹  是:递归copy(xx,xx);               否,说明是个文件,拷贝文件            ...

SpringBoot实现文件上传下载

前言 本篇文章主要介绍的是SpringBoot实现文件上传下载。 GitHub源码链接位于文章底部。 创建maven项目,在pom文件中添加依赖 <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <ja...

MappedByteBuffer

计算机内存管理 原文链接https://www.cnblogs.com/guozp/p/10470431.html MMC:CPU的内存管理单元。 物理内存:即内存条的内存空间。 虚拟内存:计算机系统内存管理的一种技术。它使得应用程序认为它拥有连续的可用的内存(一个连续完整的地址空间),而实际上,它通常是被分隔成多个物理内存碎片,还有部分暂时存储在外部磁盘...

Linux objcopy命令

一、简介 [功能]  将目标文件的一部分或者全部内容拷贝到另外一个目标文件中,或者实现目标文件的格式转换。  [描述]  objcopy工具使用BFD库读写目标文件,它可以将一个目标文件的内容拷贝到另外一个目标文件当中。objcopy通过它的选项来控制其不同的动作,它可以将目标文件拷贝成和原来的文件不一样的格式。需要注意的是objcopy能够在两种格...

关于 svn: E155004 is already locked 出现原因和解决办法

1.出错提示: svn: E155004 is already locked,please clean up ......... 2.出错原因: SVN本地更新时,由于一些操作中断更新,如磁盘空间不够,用户取消。可能会造成本地文件被锁定的情况。 3.解决办法: 1)可以使用SVNcleanup来清除锁定。2)如果不是本目录锁定,系统提示上一层目录锁定,需要...