我正在尝试从Kafka中读取JSON消息,并将它们存储在具有Spark结构化流的HDFS中。
我遵循了示例here,并且当我的代码看起来像这样时:
date3 tID
sID dID
4321 5432 7/20 1234
5688 4567 9/15 7890
然后我在hdfs中获得带有二进制值的行。
df = spark \
.read \
.format("kafka") \
.option("kafka.bootstrap.servers", "host1:port1,host2:port2") \
.option("subscribe", "topic1") \
.load()
df.selectExpr("CAST(key AS STRING)", "CAST(value AS STRING)")
df.writeStream.format("json").option("checkpointLocation", "some/hdfs/path").start(/data")
这些行将按预期连续写入,但采用二进制格式。
我发现了这篇文章:
我正在尝试实现此示例:
{"value":"BINARY DATA","topic":"test_hdfs2","partition":0,"offset":3463075,"timestamp":"2018-07-24T20:51:33.655Z","timestampType":0}
但是在这里我有一个奇怪的行为。我有一个写到hdfs的小文件,其中有多个空的json行-{}
很快,作业失败,但出现以下异常:
schema = StructType().add("a", IntegerType()).add("b", StringType())
df.select( \
col("key").cast("string"),
from_json(col("value").cast("string"), schema))
有什么想法如何以正确的方式实现这一目标吗?
答案 0 :(得分:0)
如果看到错误(在压缩批处理409(compactInterval:10)时不存在399.compact,则其明确的错误是由于找不到紧凑文件夹。基本上在spark结构化流中,每个批处理运行都会创建一个。 _spark_metadata下的compact文件夹,并且为了防止过去运行时产生大量紧凑文件的开销,它会定期尝试合并这些文件。
我认为默认值是它尝试压缩的每10个批次。因此在这里,当它运行409批次并尝试压缩其未找到前一个并失败时。一种选择是设置。这并不是真正的业务错误,仅会引发簿记错误,并防止您的应用终止将failOnDataLoss
以下的内容添加为false。
spark.readStream
.format("kafka")
.option("kafka.bootstrap.servers", conf.servers)
.option("subscribe", conf.topics)
.option("failOnDataLoss",false)
使用以下属性增加压实间隔
spark.conf.set("spark.sql.streaming.fileSink.log.cleanupDelay", 60000)