問題
當你嚐試用Spark在WASB上讀取文件時,你會得到以下異常:
org.apache.spark.SparkException: Job aborted to stage failure: Task 0 in stage 1.0 failed 4 times,最近失敗:Lost Task 0.3 in stage 1.0 (TID 19, 10.139.64.5, executor 0): shaded.databricks.org.apache.hadoop.fs.azure.AzureException: com.microsoft.azure.storage.StorageException:錯誤的Blob類型,請使用正確的Blob類型訪問服務器上的Blob。期望的BLOCK_BLOB,實際的APPEND_BLOB。
當您嚐試使用dbutils.fs.ls或者Hadoop API,你會得到以下異常:
java.io.FileNotFoundException: File/does not exist。
導致
WASB文件係統支持三種類型的blob:塊、頁和附加。
- 塊塊是為上傳大數據塊而優化的(Hadoop中的默認值)。
- 頁麵blob針對隨機讀和寫操作進行了優化。
- 追加blob針對追加操作進行了優化。
看到理解塊團、附加團和頁麵團獲取詳細信息。
如果試圖讀取追加blob或列出僅包含追加blob的目錄,就會出現上述錯誤。磚和Hadoop AzureWASB實現不支持讀取附加blob。類似地,在列出目錄時,附加blob將被忽略。
沒有其他方法可以讀取追加blob或列出隻包含追加blob的目錄。但是,您可以使用Azure CLI或用於Python的Azure Storage SDK來識別目錄是否包含追加blob或文件是否為追加blob。
您可以通過運行以下Azure CLI命令來驗證一個目錄是否包含追加blobs:
Az storage blob list \——auth-mode key \——account-name\——container-name \——prefix
結果以JSON文檔的形式返回,您可以在其中輕鬆找到每個文件的blob類型。
如果目錄很大,可以使用標誌限製結果的數量——num-results < num >.
你也可以使用Azure Storage SDK for Python來列出和瀏覽WASB文件係統中的文件:
%python iter = service.list_blobs(“容器”)用於iter中的blob:blob_type == "AppendBlob": print("\t Blob name: %s, %s" % (Blob .name, Blob .properties.blob_type))
Databricks確實支持使用Hadoop API訪問追加blob,但隻有在追加到文件時才支持。
解決方案
這個問題沒有變通辦法。
使用Azure CLI或用於Python的Azure Storage SDK來識別目錄是否包含追加blob,或者對象是否為追加blob。
您可以使用RDD API實現Spark SQL UDF或自定義函數,使用Azure Storage SDK for Python加載、讀取或轉換blob。