我正在Pyspark中编写一些分析脚本。而且我无法设置从Kafka到Cassandra的流式传输。当它是一个数据时就可以了,但是当进行流传输时它就行不通了。
我正在使用foreachBatch
进行某种方式的阅读,但是我是Pyspark的新手,我无法成功地写下来,因为该文档很la脚。
有人可以在我的脚本中为我提供有关foreachBatch
的帮助吗。
我正在从Kafka主题向Cassandra提供数据。
import os, json, time
from pyspark.sql import functions as F
from pyspark.sql import types
from pyspark.sql import SparkSession
def parse_value(value):
value_object = json.loads(value)
return [value_object["topicData"]["serialNumber"]+":"+str(value_object["msg"]["params"]["device_id"])+":"+str(value_object["msg"]["timestamp"]),
value_object["msg"]["params"]["service_name"],
str(value_object["msg"]["timestamp"]),
value_object["msg"]["params"]["property_value"]]
parse_value_udf = F.udf(lambda x: parse_value(x), types.ArrayType(types.StringType()))
spark = SparkSession \
.builder \
.appName("StructuredNetworkWordCount") \
.getOrCreate()
spark.sparkContext.setLogLevel("ERROR")
df = spark \
.readStream \
.format("kafka") \
.option("kafka.bootstrap.servers", "localhost:9092") \
.option("subscribe", "topicsForEvents123") \
.load() \
.selectExpr("CAST(value AS STRING)")
df = df.withColumn('_id', parse_value_udf(df.value)[0]).withColumn('property_name', parse_value_udf(df.value)[1]).withColumn('time', parse_value_udf(df.value)[2]).withColumn('value', parse_value_udf(df.value)[3])
df = df.select('_id','property_name','time','value')
query = df \
.writeStream \
.outputMode("append") \
.format("org.apache.spark.sql.cassandra") \
.option("property_change","strat_history_keyspace_cassandra_raw1")\
.start()
query.awaitTermination()
如果可以尝试的话,我只希望有人在Pyspark上向我展示foreachBatch
的示例。因为我不了解文档以及如何用我的代码来放置它。
文档说明:
def foreach_batch_function(df, epoch_id):
# Transform and write batchDF
pass
streamingDF.writeStream.foreachBatch(foreach_batch_function).start()
我不明白如何发送df
和epoch_id
。在何处找到id
,以及要发送哪个df
作为参数。
答案 0 :(得分:1)
foreachBatch
是一个输出接收器,可让您将每个流式微批处理作为非流式数据帧进行处理。
如果您想尝试一个最小的工作示例,则可以将数据框打印到控制台:
def foreach_batch_function(df, epoch_id):
df.show()
df.writeStream \
.outputMode("append") \
.foreachBatch(foreach_batch_function) \
.start() \
.awaitTermination()
没有其他事情可做。
Spark连续读取输入流(Kafka),并将每个微批处理自动发送到您定义的功能(foreach_batch_function
)。
该函数将接收数据框和批次ID。您不必手动调用该函数。
此时,您可以将数据框视为批处理数据框,并执行所需的所有转换和操作。
如果要将微批量数据帧输出到Cassandra,则需要编辑foreach_batch_function
函数,如
def foreach_batch_function(df, epoch_id):
df.write \
.format("org.apache.spark.sql.cassandra") \
.mode('append') \
.options(table="TABLE_NAME", keyspace="KEYSPACE_NAME") \
.save()