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
TaskDescription taskDesc = new TaskDescription();
taskDesc.addInputMapping("oss://mybucket/mydir/", "/home/admin/mydir/"); //只讀掛載
taskDesc.addOutputMapping("/home/admin/mydir/", "oss://mybucket/mydir/"); //可寫掛載
3.1.2 使用 Python SDK
# 只讀掛載
job_desc['DAG']['Tasks']['my-task']['InputMapping'] = {
"oss://mybucket/mydir/": "/home/admin/mydir/"
}
# 可寫掛載
job_desc['DAG']['Tasks']['my-task']['OutputMapping'] = {
"/home/admin/mydir/": "oss://mybucket/mydir/"
}
3.1.3 使用命令行
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
TaskDescription taskDesc = new TaskDescription();
taskDesc.addInputMapping("oss://mybucket/myprograms/", "/home/admin/myprograms/"); //只讀掛載
Command cmd = new Command()
cmd.setCommandLine("python /home/admin/myprograms/main.py")
params.setCommand(cmd);
taskDesc.setParameters(params);
3.2.2 使用 Python SDK
# 只讀掛載
job_desc['DAG']['Tasks']['my-task']['InputMapping'] = {
"oss://mybucket/myprograms/": "/home/admin/myprograms/"
}
job_desc['DAG']['Tasks']['my-task']['Parameters']['Command']['CommandLine']='python /home/admin/myprograms/main.py'
3.2.3 使用命令行
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
TaskDescription taskDesc = new TaskDescription();
taskDesc.addInputMapping("oss://bucket1/data/file1", "/home/data/file1");
taskDesc.addInputMapping("oss://bucket2/data/file2", "/home/data/file2");
taskDesc.addOutputMapping("/home/output/output1", "oss://bucket1/output/file1");
taskDesc.addOutputMapping("/home/output/output2", "oss://bucket2/output/file2");
3.3.2 使用 Python SDK
# 只讀掛載
job_desc['DAG']['Tasks']['my-task']['InputMapping'] = {
"oss://bucket1/data/file1": "/home/data/file1",
"oss://bucket2/data/file2": "/home/data/file2"
}
# 可寫掛載
job_desc['DAG']['Tasks']['my-task']['OutputMapping'] = {
"/home/output/output1": "oss://bucket1/output/file1",
"/home/output/output2": "oss://bucket2/output/file2"
}