【问题标题】:Azure Synapse Pipeline running Spark Notebook Generates Random Errors运行 Spark Notebook 的 Azure Synapse Pipeline 生成随机错误
【发布时间】:2022-07-11 16:51:53
【问题描述】:

我正在处理 Azure Synapse Spark 笔记本中大约 19,710 个包含 IIS 日志文件的目录。每个目录中有 3 个 IIS 日志文件。笔记本读取目录中的 3 个文件,并将它们从分隔的文本转换为 Parquet。没有分区。但有时我会莫名其妙地收到以下两个错误。

{
    "errorCode": "2011",
    "message": "An error occurred while sending the request.",
    "failureType": "UserError",
    "target": "Call Convert IIS To Raw Data Parquet",
    "details": []
}

当我收到上述错误时,所有数据都已成功写入 Azure Data Lake Storage Gen2 中的相应文件夹。

有时我会得到

{
    "errorCode": "6002",
    "message": "(3,17): error CS0234: The type or namespace name 'Spark' does not exist in the namespace 'Microsoft' (are you missing an assembly reference?)\n(4,17): error CS0234: The type or namespace name 'Spark' does not exist in the namespace 'Microsoft' (are you missing an assembly reference?)\n(12,13): error CS0103: The name 'spark' does not exist in the current context",
    "failureType": "UserError",
    "target": "Call Convert IIS To Raw Data Parquet",
    "details": []
}

当我收到上述错误时,没有任何数据被成功写入 Azure Data Lake Storage Gen2 中的相应文件夹。

在这两种情况下,您都可以看到笔记本确实运行了一段时间。 我在 spark 笔记本上启用了 1 次重试,它是一个 pyspark 笔记本,它使用 C# %%csharp 为参数执行 python 其余逻辑。 Spark 池很小(4 核/32GB),有 5 个节点。

笔记本中唯一的转换是将字符串列转换为时间戳。

var dfConverted = dfparquetTemp.WithColumn("Timestamp",Col("Timestamp").Cast("timestamp"));

当我说这是随机的,管道当前正在运行,在处理 215 个目录后,有 2 个是第一个失败,一个是第二个。

任何想法或建议将不胜感激。

【问题讨论】:

  • 看到另一个随机错误,我将在管道完成后进行调查"errorCode": "6002", "message": "[2022-03-02T12:09:41.8223708Z] [vm-18712171] [Error] [JvmBridge] JVM method execution failed: Nonstatic method 'collectToPython' failed for class '37' when called with no arguments\n[2022-03-02T12:09:41.8227074Z] [vm-18712171] [Error] [JvmBridge] java.io.IOException: Stream is corrupted

标签: c# azure-synapse spark-notebook


【解决方案1】:

运行 113 小时后正常(几乎完成)我仍然收到以下错误,但看起来所有数据都已写出

计数 1

{
    "errorCode": "6002",
    "message": "(3,17): error CS0234: The type or namespace name 'Spark' does not exist in the namespace 'Microsoft' (are you missing an assembly reference?)\n(4,17): error CS0234: The type or namespace name 'Spark' does not exist in the namespace 'Microsoft' (are you missing an assembly reference?)\n(12,13): error CS0103: The name 'spark' does not exist in the current context",
    "failureType": "UserError",
    "target": "Call Convert IIS To Raw Data Parquet",
    "details": []
}

计数 1

{
    "errorCode": "6002",
    "message": "Exception: Failed to create Livy session for executing notebook. LivySessionId: 4419, Notebook: Convert IIS to Raw Data Parquet.\n--> LivyHttpRequestFailure: Something went wrong while processing your request. Please try again later. HTTP status code: 500. Trace ID: e0860852-40e6-498f-b2df-4eff9fee504a.",
    "failureType": "UserError",
    "target": "Call Convert IIS To Raw Data Parquet",
    "details": []
}

计数 17

{
    "errorCode": "2011",
    "message": "An error occurred while sending the request.",
    "failureType": "UserError",
    "target": "Call Convert IIS To Raw Data Parquet",
    "details": []
}

不确定这些错误是关于什么的,当然我会重新运行管道中的特定数据,看看这是一次性的还是继续在这些特定数据上发生。但似乎这些错误或发生在将数据写入 parquet 格式之后。

【讨论】:

    【解决方案2】:

    我认为这是问题的一部分。请记住,我正在用 C# 编写逻辑的主要部分,因此您使用另一种语言的情况可能会有所不同。这些也是以空格分隔的 IIS 日志文件,它们的大小可以是数兆字节,例如一个文件可以是 30MB。

    我的新代码已经运行了 17 个小时,没有出现任何错误。我所做的所有更改都是为了确保我处理了会消耗内存的资源。示例如下:

    将文本分隔文件作为二进制文件读取时

        var df = spark.Read().Format("binaryFile").Option("inferSchema", false).Load(sourceFile) ;            
        byte[] rawData = df.First().GetAs<byte[]>("content");
    

    byte[] 中的数据最终被加载到 List&lt;GenericRow&gt; 中,但我从未将变量 rawData 设置为 null。

    从上面的数据框中填充字节[]后,我添加了

        df.Unpersist() ;
    

    在将所有数据从 byte[] 完全放入 List&lt;GenericRow&gt; rows 并使用下面的代码将其添加到数据框中后,我清除了 rows 变量。

        var dfparquetTemp = spark.CreateDataFrame(rows,inputSchema);
        rows.Clear() ;
    

    最后,在更改列类型并写出数据后,我对数据框进行了非持久化。

        var dfConverted = dfparquetTemp.WithColumn("Timestamp",Col("Timestamp").Cast("timestamp"));
        if(overwrite) {
            dfConverted.Write().Mode(SaveMode.Overwrite).Parquet(targetFile) ;
        }
        else {
            dfConverted.Write().Mode(SaveMode.Append).Parquet(targetFile) ;
        }
        dfConverted.Unpersist() ; 
    

    最后,我的大部分逻辑都包含在一个 C# 方法中,该方法在 foreach 循环中被调用,希望 CLR 能够处理我错过的任何其他内容。

    最后但并非最不重要的一个教训。

    • 在读取包含多个 parquet 文件的目录时,似乎 火花将所有文件读入数据框中。
    • 在读取包含多个文本分隔文件的目录时 将文件视为二进制文件 spark 仅将其中一个文件读入 数据框。

    因此,为了处理文件夹中的多个文本分隔文件,我必须传入多个文件的名称,并使用 SaveMode.Overwrite 处理第一个文件,并将其他文件作为 SaveMode.Append 处理。尝试使用任何类型的通配符并指定目录名称的每种方法都只会导致将一个文件读入数据框中。 (相信我,经过几个小时的 GoogleFu 我尝试了所有我能找到的方法。)

    又是 17 小时处理一个错误,所以重要的一课似乎是尽可能降低内存使用率。

    【讨论】:

      【解决方案3】:

      好的,我正在添加另一个答案,而不是编辑现有答案。 113 小时后,我有 52 个错误需要重新处理。我发现一些错误是由于Kryo serialization failed: Buffer overflow. Available: 0, required: 19938070. To avoid this, increase spark.kryoserializer.buffer.max 在使用 GoogleFu 几个小时后造成的,其中还包括将我的火花池的大小从小型增加到中型(没有效果)我将其添加为我笔记本中的第一个单元格

      %%configure
      {
          "conf":
          {
              "spark.kryoserializer.buffer.max" : "512"
          }
      }
      

      所以这解决了 Kryo 序列化失败的问题,我相信更大的火花池已经修复了所有剩余的错误,因为它们现在都已成功处理。此外,之前运行 2 小时后失败的作业现在在 30 分钟后完成。我怀疑这种速度增加是由于更大的火花池内存。所以吸取了教训。不要将小池用于 IIS 文件。

      终于有让我烦恼的事情了。当您在一个空单元格中键入 %%configure 时,微软如此无益地放入以下废话

      %%configure
      {
          # You can get a list of valid parameters to config the session from https://github.com/cloudera/livy#request-body.
          "driverMemory": "28g", # Recommended values: ["28g", "56g", "112g", "224g", "400g", "472g"]
          "driverCores": 4, # Recommended values: [4, 8, 16, 32, 64, 80]
          "executorMemory": "28g",
          "executorCores": 4,
          "jars": ["abfs[s]: //<file_system>@<account_name>.dfs.core.windows.net/<path>/myjar.jar", "wasb[s]: //<containername>@<accountname>.blob.core.windows.net/<path>/myjar1.jar"],
          "conf":
          {
              # Example of standard spark property, to find more available properties please visit: https://spark.apache.org/docs/latest/configuration.html#application-properties.
              "spark.driver.maxResultSize": "10g",
              # Example of customized property, you can specify count of lines that Spark SQL returns by configuring "livy.rsc.sql.num-rows".
              "livy.rsc.sql.num-rows": "3000"
          }
      }
      

      我称之为垃圾,因为它有评论。如果您尝试只添加您想要的一个设置,它将因 cmets 而失败。只是被警告。

      【讨论】:

        【解决方案4】:

        你在这方面有什么进展吗? 我也偶尔遇到 errorCode=6002:

        {
            "errorCode": "6002",
            "message": "Exception: Failed to create Livy session for executing notebook. Error: Something went wrong while processing your request. Please try again later. HTTP status code: 500. Trace ID: d65583a1-5e18-4553-bbe3-cbd0c4d4b633.",
            "failureType": "UserError",
            "target": "execute_notebook",
            "details": []
        }
        

        【讨论】:

          猜你喜欢
          • 2021-09-15
          • 2023-01-22
          • 1970-01-01
          • 2021-05-02
          • 2021-11-21
          • 1970-01-01
          • 2022-08-19
          • 2023-03-27
          • 2013-11-13
          相关资源
          最近更新 更多