Apache spark Spark dataframe在访问Kafka源后失去流媒体功能

Apache spark Spark dataframe在访问Kafka源后失去流媒体功能,apache-spark,pyspark,apache-kafka,apache-spark-sql,spark-streaming,Apache Spark,Pyspark,Apache Kafka,Apache Spark Sql,Spark Streaming,我使用Spark 2.4.3和Kafka 2.3.0。我想用从卡夫卡到Spark的数据做Spark结构化流媒体。一般来说,它确实在测试模式下工作,但由于我必须对数据进行一些处理(并且不知道其他方法),Spark数据帧不再具有流传输功能 #!/usr/bin/env python3 from pyspark.sql import SparkSession from pyspark.sql.functions import from_json from pyspark.sql.types impo

我使用Spark 2.4.3和Kafka 2.3.0。我想用从卡夫卡到Spark的数据做Spark结构化流媒体。一般来说,它确实在测试模式下工作,但由于我必须对数据进行一些处理(并且不知道其他方法),Spark数据帧不再具有流传输功能

#!/usr/bin/env python3

from pyspark.sql import SparkSession
from pyspark.sql.functions import from_json
from pyspark.sql.types import StructField, StructType, StringType, DoubleType

# create schema for data
schema = StructType([StructField("Signal", StringType()),StructField("Value", DoubleType())])

# create spark session
spark = SparkSession.builder.appName("streamer").getOrCreate()

# create DataFrame representing the stream
dsraw = spark.readStream \
  .format("kafka").option("kafka.bootstrap.servers", "localhost:9092") \
  .option("subscribe", "test")
print("dsraw.isStreaming: ", dsraw.isStreaming)

# Convert Kafka stream to something readable
ds = dsraw.selectExpr("CAST(value AS STRING)")
print("ds.isStreaming: ", ds.isStreaming)

# Do query on the converted data
dsQuery = ds.writeStream.queryName("ds_query").format("memory").start()
df1 = spark.sql("select * from ds_query")
print("df1.isStreaming: ", df1.isStreaming)

# convert json into spark dataframe cols
df2 = df1.withColumn("value", from_json("value", schema))
print("df2.isStreaming: ", df2.isStreaming)
输出为:

dsraw.isStreaming:  True
ds.isStreaming:  True
df1.isStreaming:  False
df2.isStreaming:  False

因此,当我创建第一个数据帧时,我就失去了流媒体功能。我怎样才能避免呢?如何从流中获取流式Spark数据帧?

不建议在生产应用程序中使用内存接收器,因为所有数据都将存储在驱动程序中

除调试目的外,也没有理由这样做,因为您可以像处理“正常”数据帧一样处理流数据帧。例如:

导入pyspark.sql.F函数
lines=spark.readStream.format(“socket”).option(“主机”、“XXX.XXX.XXX.XXX”).option(“端口”,XXXXX.load())
单词=行。选择(行。值)
words=words.filter(words.value.startswith('h'))
wordCounts=words.groupBy(“值”).count()
wordCounts=wordCounts.withColumn('count',F.col('count')+2)
query=wordCounts.writeStream.queryName(“测试”).outputMode(“完成”).format(“内存”).start()

如果您仍然希望使用您的方法:即使df.isStreaming告诉您它不是流数据帧(这是正确的),底层数据源是一个流,因此数据帧将随着每个处理的批处理而增长

我不明白你的问题
spark.sql()
不创建流。你能解释一下你想做什么吗?在后面的步骤中,我想对数据帧进行一些处理。我猜这些数据帧应该是流式的,我理解为未绑定数据帧的同义词。还是我错了?您需要将DF创建逻辑放在接收器'writestream'之前,使其成为流式DF。如果您只想在流数据上应用一些业务逻辑,还可以使用writeStream.foreachBatch。我找不到在readstream之后和writeStream之前执行DF操作的示例。我还想知道如何创建一个writestream,我可以使用sql访问它,然后执行DF操作。