[英]How to write structured stream data to Cassandra table using pyspark?
[英]How to Write Structured Streaming Data into Cassandra with PySpark?
我想將Spark結構化的流數據寫入cassandra。 我的Spark版本是2.4.0。
我研究了一些帖子,並使用了DataStax企業平台。 我沒有使用它,而是找到了foreachBatch
方法,該方法有助於將流數據寫入接收器。
我已經審查了一個基於databricks 網站的文檔。 並自己嘗試。
這是我編寫的代碼:
parsed = parsed_opc \
.withWatermark("sourceTimeStamp", "10 minutes") \
.dropDuplicates(["id", "sourceTimeStamp"]) \
.groupBy(
window(parsed_opc.sourceTimeStamp, "4 seconds"),
parsed_opc.id
) \
.agg({"value": "avg"}) \
.withColumnRenamed("avg(value)", "avg")\
.withColumnRenamed("window", "sourceTime")
def writeToCassandra(writeDF, epochId):
writeDF.write \
.format("org.apache.spark.sql.cassandra")\
.mode('append')\
.options(table="opc", keyspace="poc")\
.save()
parsed.writeStream \
.foreachBatch(writeToCassandra) \
.outputMode("update") \
.start()
parsed
數據幀的架構為:
root
|-- sourceTime: struct (nullable = false)
| |-- start: timestamp (nullable = true)
| |-- end: timestamp (nullable = true)
|-- id: string (nullable = true)
|-- avg: double (nullable = true)
我可以成功地將此流df寫入控制台,如下所示:
query = parsed \
.writeStream \
.format("console")\
.outputMode("complete")\
.start()
控制台中的輸出如下:
+--------------------+----+---+
| sourceTime| id|avg|
+--------------------+----+---+
|[2019-07-20 18:55...|Temp|2.0|
+--------------------+----+---+
因此,當寫入控制台時,沒關系。 但是當我在cqlsh
查詢時,沒有記錄追加到表中。
這是cassandra中的表創建腳本:
CREATE TABLE poc.opc ( id text, avg float,sourceTime timestamp PRIMARY KEY );
所以,你能告訴我哪里出問題了嗎?
在研究主題之后,我找到了解決方案。
仔細查看終端日志,我發現有一個錯誤日志是: com.datastax.spark.connector.types.TypeConversionException: Cannot convert object [2019-07-20 18:55:00.0,2019-07-20 18:55:04.0] of type class org.apache.spark.sql.catalyst.expressions.GenericRowWithSchema to java.util.Date.
這是因為,當在spark中執行window
操作時,它將一個結構添加到timestamp列上的架構,在本例中為sourceTime
。 sourceTime
的架構如下所示:
sourceTime: struct (nullable = false)
| |-- start: timestamp (nullable = true)
| |-- end: timestamp (nullable = true)
但是我已經在cassandra中創建了一個列,該列已經是sourceTime
但是它只需要一個時間戳值。 如果查找錯誤,它將嘗試發送cassandra表中不存在的start
和end
timeStamp參數。
因此,從parsed
數據幀中選擇此列可解決問題: cassandra_df = parsed.select("sourcetime.start", "avg", "sourcetime.end", "id")
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.