使用ApacheSpark流上的ApacheBahir Stuctured Streaming连接器丢失架构

时间:2017-02-06 15:48:10

标签: scala apache-spark mqtt watson-iot apache-bahir

我试图将ApacheSpark结构化流连接到MQTT主题(在这种情况下,IBM Bluemix上的IBM Watson IoT平台)。

我按如下方式创建结构化流:

val df = spark.readStream 
    .format("org.apache.bahir.sql.streaming.mqtt.MQTTStreamSourceProvider")
    .option("username","a-vy0z2s-q6s8r693hv")
    .option("password","B+UX(aWuFPvX")
    .option("clientId","a:vy0z2s:a-vy0z2s-zfzzckrnqf")
    .option("topic", "iot-2/type/WashingMachine/id/Washer02/evt/voltage/fmt/json")
    .load("tcp://vy0z2s.messaging.internetofthings.ibmcloud.com:1883")

到目前为止一直很好,在REPL中我得到了这个df对象如下:

  

df:org.apache.spark.sql.DataFrame = [value:string,timestamp:   时间戳]

我从this thread了解到每次连接时都必须更改客户端ID。所以这已经解决了,但如果我开始使用这一行从流中读取:

  

val query = df.writeStream。输出outputmode("附加&#34)
。   格式("控制台&#34)。启动()

然后生成的架构如下所示:

  

df:org.apache.spark.sql.DataFrame = [value:string,timestamp:timestamp]

数据如下:

enter image description here

这意味着我的JSON流被转换为包含JSON表示的字符串对象流。

这是ApacheBahir的限制吗?

同样提供架构也没有帮助,因为以下代码类似于相同的结果:

import org.apache.spark.sql.types._
val schema = StructType(
    StructField("count",LongType,true)::
    StructField("flowrate",LongType,true)::
    StructField("fluidlevel",StringType,true)::
    StructField("frequency",LongType,true)::
    StructField("hardness",LongType,true)::
    StructField("speed",LongType,true)::
    StructField("temperature",LongType,true)::
    StructField("ts",LongType,true)::
    StructField("voltage",LongType,true)::
Nil)

:paste
val df = spark.readStream
    .schema(schema)
    .format("org.apache.bahir.sql.streaming.mqtt.MQTTStreamSourceProvider")
    .option("username","a-vy0z2s-q6s8r693hv")
    .option("password","B+UX(a8GFPvX")
    .option("clientId","a:vy0z2s:a-vy0z2s-zfzzckrnqf4")
.option("topic", "iot-2/type/WashingMachine/id/Washer02/evt/voltage/fmt/json")
    .load("tcp://vy0z2s.messaging.internetofthings.ibmcloud.com:1883")

2 个答案:

答案 0 :(得分:1)

许多DataSources,包括but not limited to MQTTStreamSource,都有固定的架构,其中包含一条消息和一个时间戳。模式不会丢失,根本不会被解析,这是预期的行为。

如果架构已修复并且预先知道,则应该能够使用from_json函数:

import org.apache.spark.sql.functions.from_json

df.withColumn("value", from_json($"value", schema))

答案 1 :(得分:0)

对于解析(因为我不再使用“from_json”方法)我已经使用了

  

import org.apache.spark.sql.functions.json_tuple

以及以下代码,它也有效:

  

df.withColumn( “值”,json_tuple($ “值”, “myColumnName”))