簡體   English   中英

結構化流媒體OOM

[英]Structured Streaming OOM

我在 k8s 運算符上部署了一個結構化的流作業,它只是從 kafka 讀取、反序列化、添加 2 列並將結果存儲在數據湖中(嘗試了 delta 和 parquet),幾天后,執行器增加了 memory,最終我得到了 OOM。 輸入記錄的 kbs 非常低。 Ps 我使用完全相同的代碼,但使用 cassandra 作為接收器,現在運行了將近一個月,沒有任何問題。 有什么想法嗎?

在此處輸入圖像描述

在此處輸入圖像描述

我的代碼

spark
    .readStream
    .format("kafka")
    .option("kafka.bootstrap.servers", MetisStreamsConfig.bootstrapServers)
    .option("subscribe", MetisStreamsConfig.topics.head)
    .option("startingOffsets", startingOffsets)
    .option("maxOffsetsPerTrigger", MetisStreamsConfig.maxOffsetsPerTrigger)
    .load()
    .selectExpr("CAST(value AS STRING)")
    .as[String]
    .withColumn("payload", from_json($"value", schema))

    // selection + filtering
    .select("payload.*")
    .select($"vesselQuantity.qid" as "qid", $"vesselQuantity.vesselId" as "vessel_id", explode($"measurements"))
    .select($"qid", $"vessel_id", $"col.*")
    .filter($"timestamp".isNotNull)
    .filter($"qid".isNotNull and !($"qid"===""))
    .withColumn("ingestion_time", current_timestamp())
    .withColumn("mapping", MappingUDF($"qid"))
  writeStream
    .foreachBatch { (batchDF: DataFrame, batchId: Long) =>
      log.info(s"Storing batch with id: `$batchId`")
      val calendarInstance = Calendar.getInstance()

      val year = calendarInstance.get(Calendar.YEAR)
      val month = calendarInstance.get(Calendar.MONTH) + 1
      val day = calendarInstance.get(Calendar.DAY_OF_MONTH)
      batchDF.write
        .mode("append")
        .parquet(streamOutputDir + s"/$year/$month/$day")
    }
    .option("checkpointLocation", checkpointDir)
    .start()

我改為 foreachBatch 因為使用 delta 或 parquet 和 partitionBy 會導致問題更快

Spark 3.1.0 中解決了一個錯誤。

https://github.com/apache/spark/pull/28904

克服問題的其他方法和調試的功勞:

https://www.waitingforcode.com/apache-spark-structured-streaming/file-sink-out-of-memory-risk/read

即使您正在使用 foreachBatch,您也會發現這很有幫助...

對於一些使用partitionBy編寫一些 Delta 湖(或鑲木地板) output 的 Structured Streaming Spark 2.4.4 應用程序,我遇到了同樣的問題。

似乎與容器內的 jvm memory 分配有關,正如此處徹底解釋的那樣: https://merikan.com/2019//4/j-vm--

我的解決方案(但取決於您的 jvm 版本)是在我的 spark 應用程序的yaml定義中添加一些選項:

spec:
    javaOptions: >-
        -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap

這樣我的 Streamin 應用程序運行正常,正常數量的 memory(驅動程序 1GB,執行程序 2GB)

編輯:雖然第一個問題似乎已經解決(控制器殺死了 memory 消耗的 pod),但非堆 memory 大小緩慢增長仍然存在問題; 幾個小時后,司機/執行者被殺......

暫無
暫無

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

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