【发布时间】:2020-09-09 02:42:48
【问题描述】:
我在 k8s 运算符上部署了一个结构化流作业,它只是从 kafka 读取、反序列化、添加 2 列并将结果存储在数据湖中(尝试了 delta 和 parquet),几天后执行器增加了内存,最终我得到OOM。输入记录的 kbs 非常低。 P.s 我使用完全相同的代码,但使用 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 会导致问题更快
【问题讨论】:
-
可以显示代码吗?
-
@Srinivas 我用代码更新了帖子
-
我使用 cassandra 作为接收器的确切代码,但我没有问题
-
你能发布 spark-submit 命令吗??
-
@Srinivas 使用 google-spark 运算符部署。所以我只以编程方式传递配置。 driver.memory 2g 以及 executor 和 sql.shuffle.partitions 10
标签: apache-spark apache-spark-sql spark-streaming spark-structured-streaming