簡體   English   中英

無法使用 Apache Spark 在 AWS Glue 中讀取 json 個文件

[英]Unable to read json files in AWS Glue using Apache Spark

對於我們的用例,我們需要從 S3 存儲桶加載 json 個文件。 作為處理工具,我們使用 AWS Glue。 但是因為我們很快就會遷移到 Amazon EMR,所以我們已經在開發僅具有 Spark 功能的 Glue 作業。 這樣以后遷移會更容易。 這意味着對於我們的用例,我們不能使用任何 Glue 功能,例如對輸入文件進行分組

我們面臨的問題是,當我們讀取這些 JSON 文件時,我們看到我們的驅動程序的 memory 將達到 100%,直到最終作業因 OOM 異常而失敗。

我們已經嘗試通過使用 G.2X 實例並向我們的 Glue 作業添加--conf spark.driver.memory=20g參數來最大化驅動程序 memory。

我們使用的代碼非常簡單:

spark.read.option("inferSchema", value = true).json("s3://bucket_with_json/sub_folder")

輸入數據為 21 個 json 個文件,大小為 100MB。 文件本身不是有效的 json 對象,但每個文件包含多個 json 對象。 例如:

{
  "RecordNumber": 2,
  "Zipcode": 704,
  "ZipCodeType": "STANDARD",
  "City": "PASEO COSTA DEL SUR",
  "State": "PR"
}
{
  "RecordNumber": 10,
  "Zipcode": 709,
  "ZipCodeType": "STANDARD",
  "City": "BDA SAN LUIS",
  "State": "PR"
}

(不是真正的數據集)

我們目前使用的 Glue Job 規范:

  • 工人類型:G.2X
  • 工人人數:20
  • 額外的 Spark arguments: '--conf': 'spark.driver.maxResultSize=2g --conf spark.yarn.executor.memory=7g --conf spark.driver.memory=20g'
  • 工作語言:scala
  • 打膠版本:3.0

此視覺顯示 memory 如何超過驅動程序的最大值與執行程序的 memory:

在此處輸入圖像描述

我們在 +- 10 分鍾后得到的錯誤是:

由於超出 Memory 命令失敗

java.lang.OutOfMemoryError: Java heap space -XX:OnOutOfMemoryError="kill -9 %p" Executing /bin/sh -c "kill -9 8"...

同樣值得注意的是,當我們在較小的數據集上運行時,一切正常。

在這一點上我有點別無選擇。 有人可以幫我解決這個問題或指出正確的方向嗎? 另外,如果有人可以解釋為什么我的司機被淹沒了。 我一直以為json個文件是executor讀取的。 讀入數據后,我沒有向驅動程序收集任何數據,所以我無法解釋為什么會這樣。

** 編輯 **

我試圖將輸入文件轉換為一個有效的 json。因此轉換為以下格式:

[{
  "RecordNumber": 2,
  "Zipcode": 704,
  "ZipCodeType": "STANDARD",
  "City": "PASEO COSTA DEL SUR",
  "State": "PR"
},
{
  "RecordNumber": 10,
  "Zipcode": 709,
  "ZipCodeType": "STANDARD",
  "City": "BDA SAN LUIS",
  "State": "PR"
}]

並使用選項:

.option("multiline", "true")

但不幸的是,這給了我同樣的結果/錯誤..

**編輯**

我想補充一點,上面的數據示例及其結構與我正在使用的數據不同。 向您提供有關我的數據的一些信息:

結構非常嵌套。 它包含 25 個頂級字段。 其中 7 個是嵌套的。 如果您將所有內容展平,您最終會得到 +- 200 個字段。 可能是inferSchema選項導致了我的問題。

我認為設置inferSchema == true可能是問題所在,因為這是在驅動程序中執行的。 那么為什么要在讀取時推斷模式(需要額外傳遞數據,需要更多驅動程序資源)? 也許在這個玩具示例中找不到原因,但也許您可以試試這個?

首先......你的第二種文件格式工作正常(第一次沒有)......我創建了一些這樣的文件並將它們全部放在S3上的一個文件夾中。

[{
  "RecordNumber": 2,
  "Zipcode": 704,
  "ZipCodeType": "STANDARD",
  "City": "PASEO COSTA DEL SUR",
  "State": "PR"
},
{
  "RecordNumber": 10,
  "Zipcode": 709,
  "ZipCodeType": "STANDARD",
  "City": "BDA SAN LUIS",
  "State": "PR"
}]

我嘗試的一種替代方法是在您閱讀時自己提供架構。

import org.apache.spark.sql.types.{ IntegerType, StringType, StructField, StructType }

val schema = {
    new StructType()
      .add(StructField("RecordNumber", IntegerType, false))
      .add(StructField("Zipcode", IntegerType, true))
      .add(StructField("ZipCodeType", StringType, true))
      .add(StructField("City", StringType, true))
      .add(StructField("State", StringType, true))
  }

val df = spark.read.option("multiline", value = true).schema(schema).json("s3://bucket/path/")

另一件事要嘗試......只是在閱讀時跳過推斷模式。 我不知道下面是否以相同的方式使用驅動程序資源,但我似乎記得它可能使用了一小部分行。

val df = spark.read.option("multiline", value = true).json("s3://bucket/path/")

val schema = df.schema
schema.printTreeString

df.printSchema

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM