有没有办法使用pyspark从Kafka到Cassandra设置结构化流

时间:2019-08-23 06:13:07

标签: python apache-spark pyspark spark-structured-streaming

我正在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()  

我不明白如何发送dfepoch_id。在何处找到id,以及要发送哪个df作为参数。

1 个答案:

答案 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()