OSS資料卷是使用ossfs檔案進行掛載的FUSE檔案系統,適合於讀檔案情境。OSS為共用儲存,支援ReadOnlyMany和ReadWriteMany兩種訪問模式。ossfs適用於並發讀情境,建議您配置PVC和PV的訪問模式為ReadOnlyMany。本文介紹在讀多寫少情境下如何通過OSS SDK、ossutil工具等方式實現資料的讀寫分離。
前提條件
- 說明
若Bucket和ECS執行個體位於相同地區,請選擇私網網域名稱。
使用情境
OSS儲存常見的使用情境包含唯讀和讀寫。對於讀多寫少的情境,建議您將OSS資料的讀寫操作進行分離,然後通過配置緩衝參數最佳化資料讀取速度,並通過SDK等方式寫入資料。
唯讀
在巨量資料業務的推斷過程、資料分析、資料查詢等情境中使用時,為避免資料被誤刪除和誤修改,建議您將OSS儲存卷的訪問模式配置為ReadOnlyMany。具體操作,請參見使用OSS靜態儲存卷。
您還可以通過配置緩衝參數最佳化資料的讀取速度。
參數 | 說明 |
kernel_cache | 開啟後,通過核心緩衝最佳化讀效能。適用於不需要即時訪問最新內容的情境。 快取命中時,ossfs重複讀取檔案時,將通過核心緩衝區快取處理,僅使用未被其他進程使用的可用記憶體。 |
parallel_count | 以分區模式上傳或下載大檔案時,分區的並發數,預設值為20。 |
max_multireq | 列舉檔案時,訪問檔案元資訊的最大並發數。此處需大於等於parallel_count的值,預設值為20。 |
max_stat_cache_size | 用於指定檔案中繼資料的緩衝空間可緩衝多少個檔案的中繼資料。單位為個,預設值為1000。如需禁止使用中繼資料快取,可設定為0。 在不需要即時訪問最新內容的情境下,當目錄下檔案比較多時,可以根據執行個體規格增加支援的緩衝個數,加快ls的速度。 |
通過OSS控制台、SDK、ossutil工具等其他方式上傳的檔案及目錄,在ossfs中預設許可權為640。您可以根據實際業務需求,通過配置-o gid=xxx -o uid=xxx
或-o mask=022
參數,避免OSS掛載的目錄及子目錄不可讀的問題。更多資訊,請參見OSS儲存掛載許可權問題。更多ossfs配置項,請參見ossfs/README-CN.md。
讀寫
在讀寫情境中,您需要將OSS儲存卷的訪問模式配置為ReadWriteMany。通過ossfs進行寫操作時,注意事項如下。
在並發寫情境中,OSSFS無法保證資料寫入的一致性。
掛載狀態下,登入應用Pod或宿主機,在掛載路徑下刪除或變更檔案,都會直接刪除或變更OSS Bucket中對應的源檔案。您可以通過開啟OSS Bucket的版本控制,避免誤刪除重要資料,請參見版本控制概述。
在讀多寫少、尤其是讀寫路徑分離的情境中,例如,在巨量資料業務的訓練過程中,建議您將OSS資料的讀寫操作進行分離,即將OSS儲存卷的訪問模式配置為ReadOnlyMany,然後通過配置緩衝參數最佳化資料讀取速度,並通過SDK等方式寫入資料。具體操作,請參見使用樣本。
使用樣本
本文以手寫Image Recognition訓練應用為例,介紹如何?OSS儲存的讀寫分離。該樣本為一個簡單的深度學習模型訓練,業務通過唯讀OSS儲存卷從OSS的/data-dir目錄中讀取訓練集,並通過OSS SDK將checkpoint寫入OSS的/log-dir目錄。
通過ossfs實現讀寫
參考以下範本部署手寫Image Recognition訓練應用。該應用使用簡單的Python編寫,並掛載使用OSS靜態儲存卷。關於OSS儲存卷配置,請參見使用OSS靜態儲存卷。
以下樣本中,應用將OSS Bucket的子路徑
/tf-train
掛載至Pod的/mnt
目錄,在/tf-train/train/data
目錄中存放了MNIST手寫映像訓練集,供應用讀取。目錄如下圖所示。訓練開始前,
trainning_logs
目錄為空白。在訓練過程中,中間檔案將寫入Pod的/mnt/training_logs
目錄中,由ossfs上傳至OSS Bucket的/tf-train/trainning_logs
目錄中。驗證資料正常讀寫。
執行以下命令,查看Pod的狀態。
kubectl get pod tf-mnist
等待Pod狀態從Running轉換至Completed,約需要數分鐘,預期輸出為:
NAME READY STATUS RESTARTS AGE tf-mnist 1/1 Completed 0 2m
執行以下命令,查看Pod作業記錄。
通過Pod作業記錄查詢資料載入所需的時間,該時間包含從OSS下載檔案及TensorFlow載入的時間。
kubectl logs pod tf-mnist | grep dataload
預期輸出:
dataload cost time: 1.54191803932
實際查詢的時間與執行個體的效能和網路狀態相關。
登入OSS管理主控台。查看OSS Bucket的
/tf-train/trainning_logs
目錄中已出現相關檔案,表明資料可以正常從OSS中讀寫。
通過讀寫分離最佳化ossfs資料讀取速度
下文以手寫Image Recognition訓練應用和OSS SDK為例,介紹如何改造應用實現讀寫分離。
在容器環境中安裝SDK,可在構建鏡像時,增加以下內容。具體操作,請參見安裝。
RUN pip install oss2
參考OSS的官方文檔Python SDK demo修改原始碼。
以上述手寫Image Recognition訓練應用為例,源鏡像的相關原始碼如下。
def train(): ... saver = tf.train.Saver(max_to_keep=0) for i in range(FLAGS.max_steps): if i % 10 == 0: # Record summaries and test-set accuracy summary, acc = sess.run([merged, accuracy], feed_dict=feed_dict(False)) print('Accuracy at step %s: %s' % (i, acc)) if i % 100 == 0: print('Save checkpoint at step %s: %s' % (i, acc)) saver.save(sess, FLAGS.log_dir + '/model.ckpt', global_step=i)
以上代碼中,每進行100次迭代,會將中間檔案(checkpoint)存入指定的log_dir目錄,即Pod的
/mnt/training_logs
目錄。由於Saver的max_to_keep
參數為0,將維護所有的中間檔案。如果迭代1000次,則存放10組checkpoint檔案在OSS端。通過修改代碼,實現通過OSS SDK上傳中間檔案,修改要求如下:
配置訪問憑證,從環境變數中讀取AccessKey和Bucket資訊。具體操作,請參見配置訪問憑證。
為減少容器記憶體的使用,可將
max_to_keep
設定為1,即總是只儲存最新一組訓練中間檔案。每次儲存中間檔案時,通過put_object_from_file函數上傳至對應Bucket目錄。
說明在讀寫目錄分離的情境中,使用SDK時,還可以通過非同步讀寫進一步提升訓練效率。
import oss2 from oss2.credentials import EnvironmentVariableCredentialsProvider auth = oss2.ProviderAuth(EnvironmentVariableCredentialsProvider()) url = os.getenv('URL','<default-url>') bucketname = os.getenv('BUCKET','<default-bucket-name>') bucket = oss2.Bucket(auth, url, bucket) ... def train(): ... saver = tf.train.Saver(max_to_keep=1) for i in range(FLAGS.max_steps): if i % 10 == 0: # Record summaries and test-set accuracy summary, acc = sess.run([merged, accuracy], feed_dict=feed_dict(False)) print('Accuracy at step %s: %s' % (i, acc)) if i % 100 == 0: print('Save checkpoint at step %s: %s' % (i, acc)) saver.save(sess, FLAGS.log_dir + '/model.ckpt', global_step=i) # FLAGS.log_dir = os.path.join(os.getenv('TEST_TMPDIR', '/mnt'),'training_logs') for path,_,file_list in os.walk(FLAGS.log_dir) : for file_name in file_list: bucket.put_object_from_file(os.path.join('tf-train/training_logs', file_name), os.path.join(path, file_name))
修改後的容器鏡像為
registry.cn-beijing.aliyuncs.com/tool-sys/tf-train-demo:ro
。修改部分應用模板,使其通過唯讀方式訪問OSS。
將PV和PVC的
accessModes
均修改為ReadOnlyMany
,Bucket的掛載路徑可縮小至/tf-train/train/data
。在
otherOpts
中增加-o kernel_cache -o max_stat_cache_size=10000 -oumask=022
選項,使ossfs在讀取資料時能使用記憶體高速緩衝區加速處理,並增加中繼資料支援的緩衝個數(10000個中繼資料快取大約佔40M的記憶體,可根據執行個體規格及讀取的資料量多少進行調整),以及通過umask使容器進程以非root使用者運行時也有讀許可權。更多資訊,請參見使用情境。在Pod模板中增加OSS_ACCESS_KEY_ID、OSS_ACCESS_KEY_SECRET環境變數,其值可從oss-secret中擷取,與配置OSS儲存卷中的資訊保持一致。
驗證資料正常讀寫。
執行以下命令,查看Pod狀態。
kubectl get pod tf-mnist
等待Pod狀態從Running轉換至Completed,約需要數分鐘,預期輸出為:
NAME READY STATUS RESTARTS AGE tf-mnist 1/1 Completed 0 2m
執行以下命令,查看Pod作業記錄。
通過Pod作業記錄查詢資料載入所需的時間,該時間包含從OSS下載檔案及TensorFlow載入的時間。
kubectl logs pod tf-mnist | grep dataload
預期輸出:
dataload cost time: 0.843528985977
預期輸出表明,在唯讀模式中合理利用緩衝,可提升資料讀取的速度。在大規模訓練或其他持續載入資料的情境中,最佳化效果更加明顯。
登入OSS管理主控台。查看OSS Bucket的
/tf-train/trainning_logs
目錄中已出現相關檔案,表明資料可以正常從OSS中讀寫。
阿里雲官方OSS SDK參考代碼
阿里雲官方OSS SDK部分參考代碼如下。更多支援語言PHP、Node.js、Browser.js、.NET、Android、iOS、Ruby,請參見SDK參考。
程式設計語言 | 參考代碼 |
JAVA | |
Python | |
GO | |
C++ | |
C |
實現OSS讀寫分離的其他工具
工具 | 相關文檔 |
OpenAPI | |
ossutil命令列工具 | |
ossbrowser圖形化管理工具 |