簡體   English   中英

如何使用PySpark將結構化流數據寫入Cassandra?

[英]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表中不存在的startend timeStamp參數。

因此,從parsed數據幀中選擇此列可解決問題: cassandra_df = parsed.select("sourcetime.start", "avg", "sourcetime.end", "id")

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM