Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

关于支持chunked的疑问 #187

Closed
10045125 opened this issue Jun 20, 2016 · 6 comments
Closed

关于支持chunked的疑问 #187

10045125 opened this issue Jun 20, 2016 · 6 comments
Labels

Comments

@10045125
Copy link

我有2个疑问希望作者回复下:

  1. 框架支持chunk协议的文件下载吗?
  2. 如果支持,那么分段下载文件存储方式和数据写入方式怎么体现,如何充分的利用cpu和带宽进行最大效率的下载?

如果不支持,很希望作者加入这种下载方式。有空我也Pull code,Thanks。

@Jacksgong
Copy link
Collaborator

Jacksgong commented Jun 21, 2016

支持chunk下载,具体提高效率,参考下这里: https://github.com/lingochamp/FileDownloader/wiki/filedownloader.properties


欢迎PR :)

@Jacksgong
Copy link
Collaborator

Jacksgong commented Jun 21, 2016

效率方面除了 filedownloader.properties 的配置,还可以通过调整 FileDownloadListener#progress 的回调频率,减少这块回调导致 CPU与IO 资源在回调上的消耗,具体可以参考: BaseDownloadTask#setCallbackProgressTimesBaseDownloadTask#setCallbackProgressMinInterval

@10045125
Copy link
Author

从代码上来看,目前文件输入流到写文件是在一个线程里面执行,也就是文件的读写操作会堵塞当前线程,这样就不能够很好的协调网络流和文件流之间的并发,从而降低了文件的下载速度,这个速度在支持chunk的文件体现较为明显,是否能够考虑增加文件读写的并发处理?

@Jacksgong
Copy link
Collaborator

Jacksgong commented Jun 21, 2016

谢谢你的细心,这是一个很好的思想,其实之前在处理有损体验强制IO的时候也有思考过这个,这里确实是在两块系统资源(网络资源、IO资源),虽然是一个优化的方向,不过由于各项的策略性的优化,因此目前这个并非瓶颈所在。

简单说来:

  1. 每次从buffer中读取资源到RAF并不会立马触发IO(RAF内部机制保证);
  2. 这里不像Fresco中的pipeline那么有效,Fresco是由于存在明显的CPU密集(decode图片)与IO/网络密集(图片下载);
  3. 如系统提供的DownloadManager也是放在同一个线程,如果说拆到两块线程: 一来在提高一定的复杂度的同时,由于这块是对称高频率的线程间调度,带来调度、数据传输(或共享变量同步)、数据安全性等问题,虽然叉开了两块资源,但是却带来另外一些资源的消耗(特别是CPU),因此效果有所折扣;

不过在未来的迭代中,这会作为一个方向,也许会结合多点下载,或者结合全局统一管理固定几个策略分配的IO线程等的一些方式,在策略方面进行优化妥协。


对于你说谈到的对于chunk明显的原因与解决方案:

特别是有些chunk资源,后端给回的资源分块非常细,导致通过buffer取资源就需要非常频繁,由于不会是写文件照成的block(由于RAF不会在每次写buffer的时候就产生IO(特别是这种小数据高频率的情况)),因此影响因素是下面几点:

一、回调造成资源稀缺

这块的 FileDownloadListener#progress 回调: 由于对于chunk资源,每次取完buffer都会进行回调(默认内部有做一个5ms的保护),由于非常非常细,导致回调非常的频繁,如果是FileDownloadService在独立进程(默认情况),会引起非常高的CPU占用与IO占用,也就使得整体的用于下载的系统可用的CPU资源与IO资源稀缺;如果是FileDownloadService共享UI进程(filedownloader.properties中配置),依然会引起非常高的CPU占用。

解决方案:

  1. 调整回调频率: BaseDownloadTask#setCallbackProgressMinInterval。 (对于chunk资源BaseDownloadTask#setCallbackProgressTimes 这个配置无效,由于未知content-length)。
  2. 设置为共享UI进程: filedownloader.properties

二、有损体验IO

这块并非目前瓶颈

为了确保在下载进程/应用进程被杀或Crash以后能够保证下次正常断点续传,每次下载了65536byte了并且2s了,会强制一次写文件(IO),以及数据库写操作。

解决方案:

配置 filedownloader.properties

@10045125
Copy link
Author

非常感谢你的回复。我这里简要的对整个框架分析了以下,以及一些自己的想法吧,地址:http://10045125.github.io/2016/06/21/%E5%BC%80%E6%BA%90%E5%BA%93FileDownloader%E7%9A%84%E7%AE%80%E8%A6%81%E5%8E%9F%E7%90%86%E5%88%86%E6%9E%90/

@Jacksgong
Copy link
Collaborator

💯 赞~。也十分欢迎PR,不过目前架构可能会由于 #157#158 会使得有一定程度的变化。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants