从Spark Streaming DataFrame中删除(损坏)不适合架构的行(从Kafka接收JSON数据)

时间:2018-08-07 18:25:56

标签: apache-spark apache-kafka spark-structured-streaming

我有一个我正在从Kafka读取的Spark结构化蒸汽应用程序。 这是我的代码的基本结构。

我创建Spark会话。

val spark = SparkSession
  .builder
  .appName("app_name")
  .getOrCreate()

然后我从信息流中阅读

val data_stream = spark
  .readStream
  .format("kafka")
  .option("kafka.bootstrap.servers", "server_list")
  .option("subscribe", "topic")
  .load()

在Kafka记录中,我将“值”转换为字符串。它从二进制转换为字符串。此时,数据框中有1列

val df = data_stream
    .select($"value".cast("string") as "json")

基于预定义的架构,我尝试将JSON结构解析为列。但是,这里的问题是,如果数据“错误”或其他格式,则与定义的架构不匹配。因此,下一个数据帧(df2)将空值放入列中。

val df2 = df.select(from_json($"json", schema) as "data")
  .select("data.*")

我希望能够从df2过滤出某一列中具有“ null”的行(我将其用作数据库的主键),即忽略与模式不匹配的不良数据?

编辑:我在某种程度上能够做到这一点,但没有达到我想要的方式。 在我的流程中,我使用了一个使用.foreach(writer)流程的查询。它的作用是打开与数据库的连接,处理每一行,然后关闭连接。 structured streaming的文档提到了此过程所需的必要条件。在处理方法中,我从每一行获取值,并检查主键是否为null,如果为null,则不将其插入数据库中。

2 个答案:

答案 0 :(得分:0)

Kafka将数据存储为原始字节数组格式。数据生产者和消费者需要同意要处理的数据结构。

如果产生的消息格式有变化,则消费者需要调整以读取相同的格式。问题出在数据结构不断发展时,您可能需要在用户端具有兼容性。

通过Protobuff定义消息格式可以解决此问题。

答案 1 :(得分:0)

只需过滤掉不需要的任何空值:

file