目标
在高延迟、高丢包的弱网环境下,合理调整上传任务中分片大小这一参数,以达到尽可能好的传输性能(传输时间、成功率)。
调研
- 腾讯云弱网分块续传功能
腾讯云的弱网分块续传功能,基于腾讯云对象存储(Cloud Object Storage,COS)服务,使移动端在弱网情况下,能根据实际情况动态调节上传分块大小,来提高上传成功率。
有以下几点:
- COS目前支持最小分块大小为100KB;
- 分块越小,意味着请求数越多,目前根据测试统计,100KB分块大小的请求耗时是1MB分块大小的2倍左右;
- 在正常网络下发起请求,建议设置分块大小为1MB及以上;
- 在网络信号弱等网络环境下上传对象容易导致上传失败,若是因为网络导致失败,则尝试将分块大小设置为100KB,再重新上传;
- 分块大小设置越小,将来下载该文件时可能比较缓慢(可能是因为更小的分片将来会产生更多的请求开销)。
- bilibili海外创作端上传链路专项治理
东南亚相对于国内较弱的网络环境和机型环境,导致了上传链路上存在很多不稳定因素。分析可能导致失败率高的原因有如下几点:
1. 分片大小太大:视频云配置了10MB作为一个分片的大小,每个分片需要较长时间才能完成上传,在弱网情况下容易出现超时或者失败,失败后该分片就需要从零开始重新上传。所以,在分片没有重新上传到原来的进度情况下,进度会一直卡住。
解决方案:针对海外的网络状态,调整分片大小为5MB。
2. iOS是单分片上传:旧iOS的分片上传方式是单线程串行上传,没有充分利用多线程的能力。理论上在带宽足够的情况下,多分片并发上传能很大程度上提升上传效率。
解决方案:针对iOS上传时, 单线程串行上传的策略,修改为多线程并发上传,通过preupload接口可配置下发并行线程数。
3. 没有断点续传的能力:由于没有实现断点续传功能,当上传任务失败后无法恢复上次的进度,而是需要从零开始重新上传,既耗费带宽,也影响上传效率。
解决方案:重新发起曾失败过的上传任务时,可从原失败位置再次发起。
4. 没有后台上传的能力:iOS没有后台继续上传的功能,进入后台很快就会停止上传。
- 极客时间博客
1. 应用场景
对于图片、视频、语音等这种较大的消息来说,采用分片上传可以让客户端在分片完成后,利用并行的方式来同时上传多个分片,从而提升上传效率。
在一些网络环境较差的场景下,采用分片的方式,可以在上传失败后进行重试时,不必重新上传整个文件,而只需要重传某一个失败的分片,这样也能提升重新发送的成功率和性能。
此外,类似语音这种流式消息,在上传时并不知道文件最终大小,采用分片上传可以让消息文件先部分上传到服务器,而没必要等到录制完才开始上传,这样也能节约上传的整体时长。
2. 分片大小
分片太大,片数少,上传的并发度不够,可能会降低上传效率,每个大的分片在失败后重传的成本会比较高。
分片太小,片数多,并发需要的 TCP 连接太多,多条TCP连接的“窗口慢启动”会降低整体吞吐,两端拆分与合并分片的开销也相应增加,而且传输时的额外流量(HTTP报头)也会更多。
一般来说,在网络状况较好的环境,比如在 WiFi、4G 下,相应的分片大小应该设置得更大一些;而在 2G、3G 弱网情况下,分片可以设置小一点。
对于分片大小的设置,简单一点的处理可以按照网络状态来粗略划分。比如,WiFi下2M,4G下1M,3G/2G下256K。
- 腾讯“鱼翅”项目
1. 背景介绍
当时的Android版手机QQ在带宽大而稳定的优质网络下的图片上传速度偏低,在带宽小而质量差的弱网络下传输成功率很低。团队尝试着对手机QQ的图片传输方案进行优化。通过半年多的研究、评测、实验和开发,推出了代号为“鱼翅”的适合移动网络的文件自适应传输方案。该方案将手机QQ的优质网络下的传输速度提升近 60%,弱网络下的传输成功率提升更是高达8倍。
2. 技术要点
<1>必须分小片传输一个文件:
若整个文件放在一个网络包里进行传输,一旦失败,就必须重传整个文件。因而采用把一个文件分片的方式传输,则只需要在某一个分片失败后重传这一个分片。同时,单个消息越大传输时越容易失败(快速数学证明:若文件大小接近0,则传输成功概率接近 100% ;而文件大小无穷大,则传输过程必然会失败),而移动互联网的整体质量比有线网络要差,相同大小的消息会更容易失败;因此就应该把一个较大的文件分成一个个的小片进行传输,每个小片更容易成功一些。
<2>不同类型的移动互联网下的分片初始大小应该有所不同:
不同移动互联网的带宽和稳定性的差异都很大,如WiFi和2G,使用不同大小的初始分片能更好地适应对应类型的网络,但是至于每种网络下的初始分片到底多大,这需要进行实验。
<3>在上传一个文件的过程中,应当尽可能动态增大分片大小(例如,后一片是前一片的 N 倍),以减少分片数量:
分片动作会带来不少额外开销,如C/S两端拆分与合并分片的时间、传输时的额外流量(HTTP头等)、每个分片的RTT等诸多开销,所以理论上传输同一个文件用的分片数量越少,额外开销越小。
<4>确定每个分片是否要继续增大之前,要检查网络类型是否发生了变化,一旦跟前一片传输的网络变得不同,则新的一片不能继续增大而是转而用新网络类型下的初始分片大小进行传输:
移动互联网下,由于用户的“移动”而时常发生网络类型的切换(如3G变2.5G),一旦网络类型变了,其带宽、时延、稳定性等因素都发生了很大的变化,所以需要分片大小“归零”,以迅速适应新网络,减少失败的概率。
<5>分片一旦传输失败,应当使用该网络下的初始分片大小进行重试:
若网络类型并没有产生切换,但某分片传输失败了,则说明该网络的质量可能已经下降到不再适合传输这个大小的分片,会有较高再次失败的可能性,因此转而重新用该网络下的初始大小的分片进行重试,以提升重传成功概率、同时减少再次失败所带来的流量浪费。
<6>每个分片都有一定次数的失败重传机会,当一个分片的所有重传都失败了,才定义为文件传输失败。
<7>配合后台服务器能力,待用户手动重试传输失败的文件时,能断点续传。
3. 基本实现
<1>分片大小的计算逻辑类似于TCP中的慢启动机制,把一个文件传输的全过程按照分片大小的增长快慢分成三种状态:QUICKSTART(快启动,分片以一定倍率快速增长)、SLOWSTART(慢启动,分片以一个远小于快启动增长倍率的小系数缓慢增长)、STABLE(稳定态,分片大小不再变化)。状态迁移的触发条件是“分片传输速度随分片大小的增大而变化的幅度”。
<2>在单片发送流程中,引入了MSNVT(最大累计真空时间)来代替RTO(超时重传时间)。即一个分片传输过程中,通过监控网卡状态,发现的传输层连续没有任何数据发送的时间长度为NVT(网络真空时间),所有发生过的NVT的累加值为SNVT(累计真空时间),若SNVT达到了规定的上限MSNVT,分片传输宣告失败。这是因为移动网络的质量/带宽经常会发生“跳变”、而不像有线网络那样的“渐变”,这就导致无论怎么设置网络请求的 RTO值都不合适,如下图。
- 小结
为了提高移动端在弱网环境下的上传任务成功率,各案例都建议降低分片的大小,具体方式有一开始根据网络类型来设定分片大小,也有根据实际情况来动态调整分片大小。