[英]Pyspark streaming from Kafka source and save to hdfs
我有一个 kafka 主题,我想使用 PySpark 流从 kafka 生产者读取数据,进行一些转换,然后保存到 HDFS。我希望每次从 kafka 源捕获数据时都完成数据。 我认为问题出在我的“更新”function 中。下面是我的代码:
orders_df = spark \
.readStream \
.format("kafka") \
.option("kafka.bootstrap.servers", kafka_bootstrap_servers) \
.option("subscribe", kafka_topic_name) \
.option("startingOffsets", "latest") \
.load()
orders_df1 = orders_df.selectExpr("CAST(value AS STRING)", "timestamp")
stock_price_schema = types.StructType([
types.StructField("symbol", types.StringType(), True),
types.StructField("date", types.DateType(), True),
types.StructField("open", types.DoubleType(), True),
types.StructField("high", types.DoubleType(), True),
types.StructField("low", types.DoubleType(), True),
types.StructField("close", types.DoubleType(), True),
types.StructField("volume", types.IntegerType(), True)
])
orders_df2 = orders_df1\
.select(from_json(col("value"), stock_price_schema)\
.alias("orders"), "timestamp")
# orders_df3 = orders_df2.select("orders.*", "timestamp")
stock_df = orders_df2.select("orders.*")
# Write final result into console for debugging purpose
orders_agg_write_stream = stock_df \
.writeStream \
.trigger(processingTime='5 seconds') \
.outputMode("update") \
.option("truncate", "false")\
.format("console") \
.start()
def update(stock_df):
if stock_df.count() == 0:
return
for row in stock_df.rdd.collect():
symbol = row["symbol"]
df_new = stock_df[stock_df["symbol"] == symbol]
df_old = spark.read.parquet(f"data/pq/{symbol}/")
df_new = df_old.union(df_new).distinct()
df_new.repartition(4).write.parquet(f"data/pq/{symbol}/")
update(orders_agg_write_stream)
orders_agg_write_stream.awaitTermination()
print("Stream Data Processing Application Completed.")
首先 - 你不能简单地在.rdd.collect
上执行 .rdd.collect - stream 根据定义是无限的。 相反,您需要对微批处理执行您的逻辑,如果您使用foreachBatch function正是因为这个原因而存在。
此外,我建议使用Delta Lake数据格式而不是普通的 Parquet(顺便说一句,Delta Lake 也是建立在 Parquet 之上的)。 有几个原因:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.