全部产品
云市场

挂载OSS

更新时间:2019-11-13 11:18:53

1. 背景

对象存储 OSS 提供了与传统文件系统不同的 API,为了支持传统程序的快速迁移,BatchCompute 允许用户将 OSS 目录直接挂载到虚拟机的本地文件系统,应用程序无需针对 OSS 进行特殊编程即可访问 OSS 上的数据。

2. 说明

挂载类型:

  • 只读挂载用于访问程序的输入数据,通过只读挂载点的数据访问将会被自动转换为 OSS 的访问请求,数据不需要先下载到虚拟机本地。
  • 可写挂载目录下的结果数据将被先存放在虚拟机的本地,在作业运行结束时会被自动上传到 OSS 的相应位置。使用可写挂载时请确保虚拟机为结果数据分配了足够的磁盘空间。

命名限制:

  • 合法的文件名仅按照 UTF-8 字符集进行定义,其他字符集需转换为 UTF-8 之后进行合法性检查。您需要在集群/作业的描述中指定应用程序使用的字符集,这样经过挂载服务的转换,应用程序才可以访问到正确的文件。

文件锁:

  • 基于 NFS 的 DOS Share 和文件锁会影响性能,所以如果有频繁的 IO 操作,建议关闭文件锁(在挂载的时候增加 nolock 选项)。但是有些特定的应用程序如 3ds MAX 必须用的文件锁特性,如果缺失这个特性会导致应用程序执行不正确。

访问权限:

  • 考虑到多个节点向 OSS 写入文件的一致性问题,InputMapping 挂载服务本身针对 OSS 是只读行为,应用程序通过文件系统接口的操作,在 任何情况 下都不会修改 OSS 上对应文件的内容,也不会删除 OSS 上的对应文件。

修改限制:

  • 在应用程序运行期间,不应该修改 OSS 上已经挂载的数据,否则可能引起冲突。

访问权限:

  • 在挂载目录中,OSS 上已经存在的文件都会赋予读取、执行的权限,没有写入权限。所有对挂载目录的修改操作,都会缓存在本地,您的应用程序可以读取到修改后的内容,但这些数据不会同步到 OSS。
  • 在应用程序运行结束,unmount 文件系统并停止挂载服务后,所有本地缓存的改动都会被放弃,接下来如果重新启动挂载服务并 mount,那么本地看到文件同 OSS 上对应 Object 的内容一致,上次的改动不再保留。

3. 使用

3.1. 挂载数据目录

提交作业的时候,可以配置挂载,请参考如下示例。

3.1.1 使用 Java SDK

  1. TaskDescription taskDesc = new TaskDescription();
  2. taskDesc.addInputMapping("oss://mybucket/mydir/", "/home/admin/mydir/"); //只读挂载
  3. taskDesc.addOutputMapping("/home/admin/mydir/", "oss://mybucket/mydir/"); //可写挂载

3.1.2 使用 Python SDK

  1. # 只读挂载
  2. job_desc['DAG']['Tasks']['my-task']['InputMapping'] = {
  3. "oss://mybucket/mydir/": "/home/admin/mydir/"
  4. }
  5. # 可写挂载
  6. job_desc['DAG']['Tasks']['my-task']['OutputMapping'] = {
  7. "/home/admin/mydir/": "oss://mybucket/mydir/"
  8. }

3.1.3 使用命令行

  1. bcs sub "python main.py" -r oss://mybucket/mydir/:/home/admin/mydir/ # 如果有多个映射,请用逗号隔开

注意

  • 配置 InputMapping,是只读挂载,意思是只能读,不能写,不能删除。

  • 配置 OutputMapping,凡是写到 /home/admin/mydir/目录下的文件或目录,在任务运行完成后,会被自动上传到 oss://mybucket/mydir/ 下面。

  • InputMapping 和 OutputMapping 不能指定为同样的映射。

3.2 挂载程序目录

假如 main.py 在OSS上的路径为: oss://mybucket/myprograms/main.py,可以挂载 oss://mybucket/myprograms/ 为 /home/admin/myprograms/,然后指定运行命令行python /home/admin/myprograms/main.py 即可。

3.2.1 使用 Java SDK

  1. TaskDescription taskDesc = new TaskDescription();
  2. taskDesc.addInputMapping("oss://mybucket/myprograms/", "/home/admin/myprograms/"); //只读挂载
  3. Command cmd = new Command()
  4. cmd.setCommandLine("python /home/admin/myprograms/main.py")
  5. params.setCommand(cmd);
  6. taskDesc.setParameters(params);

3.2.2 使用 Python SDK

  1. # 只读挂载
  2. job_desc['DAG']['Tasks']['my-task']['InputMapping'] = {
  3. "oss://mybucket/myprograms/": "/home/admin/myprograms/"
  4. }
  5. job_desc['DAG']['Tasks']['my-task']['Parameters']['Command']['CommandLine']='python /home/admin/myprograms/main.py'

3.2.3 使用命令行

  1. bcs sub "python /home/admin/myprograms/main.py" -r oss://mybucket/myprograms/:/home/admin/myprograms/

3.3. 挂载文件

需求: 我在OSS上有多个不同前缀下的文件,需要挂载到批量计算VM中的同一个目录下,该如何使用;

假设 bucket1 和 bucket2 下有两个文件挂载到 VM 本地的/home/data/下:

  • oss://bucket1/data/file1挂载到/home/data/file1
  • oss://bucket2/data/file2挂载到/home/data/file2

另外,作业结束后有两个 VM 本地的文件分别上传到 bucket1 和 bucket2:

  • /home/output/output1挂载到oss://bucket1/output/file1
  • /home/output/output2挂载到oss://bucket2/output/file2

可以参考如下示例:

3.3.1 使用 Java SDK

  1. TaskDescription taskDesc = new TaskDescription();
  2. taskDesc.addInputMapping("oss://bucket1/data/file1", "/home/data/file1");
  3. taskDesc.addInputMapping("oss://bucket2/data/file2", "/home/data/file2");
  4. taskDesc.addOutputMapping("/home/output/output1", "oss://bucket1/output/file1");
  5. taskDesc.addOutputMapping("/home/output/output2", "oss://bucket2/output/file2");

3.3.2 使用 Python SDK

  1. # 只读挂载
  2. job_desc['DAG']['Tasks']['my-task']['InputMapping'] = {
  3. "oss://bucket1/data/file1": "/home/data/file1",
  4. "oss://bucket2/data/file2": "/home/data/file2"
  5. }
  6. # 可写挂载
  7. job_desc['DAG']['Tasks']['my-task']['OutputMapping'] = {
  8. "/home/output/output1": "oss://bucket1/output/file1",
  9. "/home/output/output2": "oss://bucket2/output/file2"
  10. }