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

关于文件上传 #1902

Closed
gongweibao opened this issue Apr 26, 2017 · 14 comments
Closed

关于文件上传 #1902

gongweibao opened this issue Apr 26, 2017 · 14 comments
Assignees

Comments

@gongweibao
Copy link
Contributor

gongweibao commented Apr 26, 2017

经过调研,发现网页上传文件已经比较成熟,文件断点续传和大文件分片上传已经是标配
比如 jQuery File Upload,开源协议MIT

  • Resumable uploads:
    Aborted uploads can be resumed with browsers supporting the Blob API.
  • Chunked uploads:
    Large files can be uploaded in smaller chunks with browsers supporting the Blob API.

另外:百度开源的webuploader

  • 分片、并发
    分片与并发结合,将一个大文件分割成多块,并发上传,极大地提高大文件的上传速度。
    当网络问题导致传输错误时,只需要重传出错分片,而不是整个文件。另外分片传输能够更加实时的跟踪上传进度
  • MD5秒传
    当文件体积大、量比较多时,支持上传前做文件md5值验证,一致则可直接跳过。
    如果服务端与前端统一修改算法,取段md5,可大大提升验证性能,耗时在20ms左右。

这个比我们一开始设计的用命令行工具上传文件更加的简单直接
附:
我们第一期可以考虑不给一个file的explorer用来管理文件,类似elFinder,开源协议BSD-3

@helinwang
Copy link
Contributor

今天跟@wangkuiyi 讨论了一下,结论是文件的管理会是整个训练流程的核心:数据partition是对文件的操作,这些partition的数据会被到用户的根目录里,trainer需要能够访问文件来读训练集,模型会被输出到用户的根目录里,最后用户还需要能够下载训练好的模型。
这样看来,我们应该是需要一个很方便的文件管理接口。最符合用户习惯的应该是上传、cpmvrename,下载的命令行了。因为网页的灵活性不够,可能还是类似于shell的直接对分布式文件系统操作的命令行比较合适。(比如说这个:https://gluster.readthedocs.io/en/latest/Administrator%20Guide/GlusterFS%20Coreutils/

不好意思,现在讲的跟之前的和大家讨论的结果其实是有冲突的,之前是只用一个接口paddle upload来完成数据集的上传(这样的话用网页上传的方法替代我认为是合理的)。今天和@wangkuiyi 讨论下来,可很可能需要改成上一段提到的方式,我们开会的时候细聊。

@gongweibao
Copy link
Contributor Author

可能需要讨论的问题:

  • 公网安全
  • 命令行是否支持正则表达式?
  • 客户端library生成我们的格式
    • windows,linux?docker?
    • 接口
  • 断点续传?

@helinwang
Copy link
Contributor

helinwang commented Apr 27, 2017

@Yancey1989 ,请问把file server暴露给用户能否通过k8s的ingress?

初步想法:

正则表达式要看看cephfs的api支不支持正则表达式。

客户端可以考虑用golang,因为服务器也是golang,传输可以考虑gorpc。

断点续传可以通过算文件md5作为唯一标识,把文件切成多个小块,分批上传。服务器上面收到每个小块需要存到磁盘里并写入CRC校验值,并把存的路径写入数据库(数据库可以考虑boltdb),等到小块满了之后再拼起来。

目前需要支持的命令感觉有:

cp
mv
rm
sync
ls
mkdir

参考:http://docs.aws.amazon.com/cli/latest/reference/s3/

@Yancey1989
Copy link
Contributor

@helinwang 要通过k8s的ingress,理论上来说外网的流量都要统一通过ingress转发才行。

@gongweibao gongweibao self-assigned this May 1, 2017
@gongweibao
Copy link
Contributor Author

gongweibao commented May 1, 2017

@helinwang 文件切成小块然后sync到服务器是一个非常好的办法。

  • 我们是否可以不用数据库?可以生成一个sparse文件,然后写对应的偏移。这样,可以省去最后的merge的过程。而且boltdb貌似是嵌入式的db,本身不是分布式的。
  • 用户可能有意或者无意的开启多个线程,或者服务器本身也可能出现多个写同一个chunk的情况。我们是否引入etcd(或者filelock?),保证一个文件同时只有一个fileserver在处理,这样可以简化多线程(进程)写冲突的问题。

s3的命令行参数我去整理一下

@gongweibao
Copy link
Contributor Author

gongweibao commented May 1, 2017

用文件的最后修改时间来判断文件是否修改过是否靠谱那?这个主要是为了考虑上传的时候,不用每次都要计算MD5值来判断client端和server端的文件是否一致。

@gongweibao gongweibao assigned ghost , helinwang, typhoonzero and wangkuiyi and unassigned ghost May 1, 2017
@gongweibao
Copy link
Contributor Author

gongweibao commented May 2, 2017

@helinwang讨论了一下,做了一些简化:

  • 把文件拆分为多个chunk,单线程上传。
  • 断点续传的时候重新读chunk计算checkSum和服务器对应的chunk做对比,不做chunk的checkSum值的加速
  • fileserver只有一个,有kubernets来做管理,这样有多进程写入的冲突问题极大减少。第一版本不加入多个fileserver的考虑。
  • 文件写完之后用其MD5值检查是否写入成功,出错告诉用户重新传。

多谢helin,有些优化我纠结了很长时间。

@typhoonzero
Copy link
Contributor

fileserver只有一个,有kubernets来做管理,这样有多进程写入的冲突问题极大减少。第一版本不加入多个fileserver的考虑。

这里我理解fileserver仍然是一个进程池/线程池模型的 server,这样可以处理来自多个用户的并发请求,但是对于同一用户来说仍然是单线程处理文件写入?这样是否需要为每个用户引入一个文件上传的队列,在用户上传多个文件(一个文件夹)的时候可以保证"单线程上传"

@gongweibao
Copy link
Contributor Author

gongweibao commented May 2, 2017

@typhoonzero聊了一下

  • ingress端做session保持,这样一个用户的请求可以发送到同一个fileserver,这样fileserver可以多个。client端是否多线程也就没啥冲突了(极大概率情况下)
  • fileserver端做一个map池,保存handle句柄,不用filelock了,大部分的写入可以append。

@gongweibao
Copy link
Contributor Author

客户端可以考虑用golang,因为服务器也是golang,传输可以考虑gorpc。

@typhoonzero@Yancey1989 建议用http来做文件管理,这样可以利用现有的框架做用户认证。
@helinwang 这个地方要不我们讨论一下:

@helinwang
Copy link
Contributor

helinwang commented May 2, 2017

@gongweibao @typhoonzero @Yancey1989 好的,golang RPC是基于HTTP的,理论上可以做HTTP的认证。要是麻烦的话我们可以用HTTP service。
需要知道现有的框架是怎么做认证的,有没有文档呢?

@typhoonzero
Copy link
Contributor

现在框架的认证说明: https://docs.djangoproject.com/en/1.11/topics/auth/

感觉比较重要的需要决定的问题是:fileserver是否作为单独的http server运行,还是集成在现在的web site中,把一种url pattern作为fileserver的API入口

以单独方式运行:符合“微服务”架构,即每个service只负责部分功能,服务之间使用HTTP协议互相调用;服务调用方式更佳统一和一致(cloud website调用kubernetes api也是通过HTTP方式调用);缺点是系统组件变多,服务依赖会导致未来更新某个微服务会影响诸多服务。

@helinwang
Copy link
Contributor

helinwang commented May 4, 2017

我粗略看了一下django的框架认证,貌似是基于HTTP header的token认证,django做好了一套权限管理的系统,对每个URL pattern,可以给不同用户组单独设立权限。

我觉得的好处是这套系统已经做好了,不需要做额外的认证以及权限管理。
进一步想,其实认证已经有现成的了:咱们现在会分发证书给用户作为用户标识,这个证书可以作为认证。权限管理貌似也只有上传下载的统一的一个权限,不需要更加细粒度的管理。
所以我比较偏向于利用用户证书做认证(类似于kubectl方法)单独运行。这样涉及的模块少,调试与测试
也比较简单。

@typhoonzero
Copy link
Contributor

根据讨论,关于权限部分,fileserver和client使用golang编写(可以参考是否使用swagger),用户认证使用PaddlePaddle/cloud网站生成的X509 cert。简化权限管理:每个用户独享一部分存储空间。公开数据集单独使用一个ceph volume,在用户启动pod时只读挂载。

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

No branches or pull requests

5 participants