spark Hiveテーブルとの構造化ストリーミング統合に関する1つのクエリ。
spark構造化ストリーミングの例をいくつか試してみました。
これが私の例です
val spark =SparkSession.builder().appName("StatsAnalyzer")
.enableHiveSupport()
.config("Hive.exec.dynamic.partition", "true")
.config("Hive.exec.dynamic.partition.mode", "nonstrict")
.config("spark.sql.streaming.checkpointLocation", "hdfs://pp/apps/Hive/warehouse/ab.db")
.getOrCreate()
// Register the dataframe as a Hive table
val userSchema = new StructType().add("name", "string").add("age", "integer")
val csvDF = spark.readStream.option("sep", ",").schema(userSchema).csv("file:///home/su/testdelta")
csvDF.createOrReplaceTempView("updates")
val query= spark.sql("insert into table_abcd select * from updates")
query.writeStream.start()
Hdfsの場所にデータフレームを書き込んでいる間の最後のステップでわかるように、データはエキサイティングなディレクトリ(「age」で分割された古いデータを持つ既存のディレクトリ)に挿入されていません。
私は得ています
spark.sql.AnalysisException:ストリーミングソースのクエリは、writeStream start()で実行する必要があります
Hdfsの場所にある既存のディレクトリにデータを挿入できないのはなぜですか?または、Hiveテーブルで「挿入」操作を実行できる他の方法はありますか?
解決策を探しています
Spark Structured Streamingは、Hiveテーブルへのストリーミングクエリの結果の書き込みをサポートしていません。
scala> println(spark.version)
2.4.0
val sq = spark.readStream.format("rate").load
scala> :type sq
org.Apache.spark.sql.DataFrame
scala> assert(sq.isStreaming)
scala> sq.writeStream.format("Hive").start
org.Apache.spark.sql.AnalysisException: Hive data source can only be used with tables, you can not write files of Hive data source directly.;
at org.Apache.spark.sql.streaming.DataStreamWriter.start(DataStreamWriter.scala:246)
... 49 elided
ターゲットシステム(別名sink)がサポートされていない場合は、 foreachおよびforeachBatch操作 (ハイライト鉱山)を使用できます。
foreach
およびforeachBatch
操作を使用すると、任意の操作を適用し、ストリーミングクエリの出力にロジックを書き込むことができます。使用例は少し異なります。foreach
はすべての行でカスタム書き込みロジックを許可しますが、foreachBatch
は任意の操作と各マイクロバッチの出力でカスタムロジックを許可します。
foreachBatch
が最善の策だと思います。
import org.Apache.spark.sql.DataFrame
sq.writeStream.foreachBatch { case (ds: DataFrame, batchId: Long) =>
// do whatever you want with your input DataFrame
// incl. writing to Hive
// I simply decided to print out the rows to the console
ds.show
}.start
Apache Hive Warehouse Connector もありますが、これまで使用したことがありませんが、何らかの助けになるようです。
誰かが実際にJacek Laskowskiからのコードを実際に試した場合に備えて、Spark 2.4.0で実際にはコンパイルされないことを確認します(AWS-EMR 5.20でテストされた Gist を確認してください)。 0とバニラスパーク)だから、私はそれが将来どのように機能するかについての彼の考えだったと思いますSparkバージョン。実際のコードは次のとおりです:
scala> import org.Apache.spark.sql.Dataset
import org.Apache.spark.sql.Dataset
scala> sq.writeStream.foreachBatch((batchDs: Dataset[_], batchId: Long) => batchDs.show).start
res0: org.Apache.spark.sql.streaming.StreamingQuery =
org.Apache.spark.sql.execution.streaming.StreamingQueryWrapper@5ebc0bf5