Scala 如何使用Spark结构化流媒体将数据从Kafka主题流到Delta表
我试图理解databricks delta并考虑使用Kafka进行POC。基本上,计划是使用来自Kafka的数据并将其插入到databricks delta表中 以下是我所做的步骤:Scala 如何使用Spark结构化流媒体将数据从Kafka主题流到Delta表,scala,apache-spark,apache-kafka,spark-structured-streaming,delta-lake,Scala,Apache Spark,Apache Kafka,Spark Structured Streaming,Delta Lake,我试图理解databricks delta并考虑使用Kafka进行POC。基本上,计划是使用来自Kafka的数据并将其插入到databricks delta表中 以下是我所做的步骤: 在数据块上创建增量表。 使用卡夫卡的数据。 import org.apache.spark.sql.types_ val kafkaBrokers=“broker1:port,broker2:port,broker3:port” val kafkaTopic=“kafkapoc” val kafka2=spark.
import org.apache.spark.sql.types_
val kafkaBrokers=“broker1:port,broker2:port,broker3:port”
val kafkaTopic=“kafkapoc”
val kafka2=spark.readStream
.格式(“卡夫卡”)
.option(“kafka.bootstrap.servers”,kafkaBrokers)
.选项(“订阅”,卡夫卡托克语)
.选项(“起始偏移量”、“最早”)
.选项(“maxOffsetsPerTrigger”,100)
.load()
。选择($“值”)
.withColumn(“值”,“值”。.cast(StringType))
.writeStream
.选项(“检查点位置”,“/delta/hazriq_delta_trial2/_检查点/测试”)
.表格(“hazriq_delta_trial2”)
但是,当我查询表时,它是空的。
我可以确认数据已经出来了。当我向卡夫卡主题发送消息时,我通过在图表中看到尖峰来验证这一点
我错过什么了吗
我需要有关如何将从Kafka获得的数据插入表的帮助。1)尝试验证您是否可以从Spark群集访问Kafka,有时您需要允许从Kafka中的某些IP访问
2) 尝试将此。选项(“起始偏移量”、“最早的”
)更改为此。选项(“起始偏移量”、“最新的”)
3) 也试试
下面是一个关于如何从Kafka读取数据并将其流式传输到增量表的工作示例。我使用的是Spark 3.0.1和delta core 0.7.0(如果您使用的是Spark 2.4版本,则需要使用0.6.0) 将数据从Kafka流式传输到Delta表
val spark=SparkSession.builder()
.appName(“卡夫卡三角洲”)
.master(“本地[*]”)
.getOrCreate()
//在生产中,这应该是一个更可靠的位置,如HDFS
瓦尔·德尔塔帕斯=”file:///tmp/delta/table"
val df=spark.readStream
.格式(“卡夫卡”)
.option(“kafka.bootstrap.servers”,“localhost:9092”)
.期权(“认购”、“测试”)
.选项(“起始偏移量”、“最早”)
.选项(“failOnDataLoss”、“false”)
.load()
.selectExpr(“转换(值为字符串)为值”)
val查询:StreamingQuery=df.writeStream
.格式(“增量”)
.选项(“检查点位置”,“/path/to/sparkCheckpoint”)
.start(deltaPath)
查询
为了进行测试,我只在卡夫卡主题中生成了字符“a”、“b”、“c”和“d”作为值。显然,如果Kafka输入数据是例如JSON字符串,则可以构建一些更复杂的数据帧
检查增量表中的数据
在deltaPath中创建的文件
只需在将数据发送到kafka之前运行代码,一旦代码运行,您就需要将数据发送到kafka。您是否可以尝试直接插入到增量表目录而不是插入到表中?例如,
kafka.writeStream.format(“delta”).outputMode(“append”).option(“checkpoint location”,“/delta/events/_checkpoints/etl from json”)。开始(“/delta/events”)//作为路径
%sql
CREATE TABLE hazriq_delta_trial2 (
value STRING
)
USING delta
LOCATION '/delta/hazriq_delta_trial2'
val kafka2 = spark.readStream
.format("kafka")
.option("kafka.bootstrap.servers", kafkaBrokers)
.option("subscribe", kafkaTopic)
.option("startingOffsets", "earliest")
.load()
.select($"value")
.withColumn("Value", $"value".cast(StringType))
.writeStream
.format("delta")
.outputMode("append")
.option("checkpointLocation", "/delta/hazriq_delta_trial2/_checkpoints/test")
.start("hazriq_delta_trial2")
val table = spark.read
.format("delta")
.load(deltaPath)
.createOrReplaceTempView("testTable")
spark.sql("SELECT * FROM testTable").show(false)
// result
+-----+
|value|
+-----+
|a |
|b |
|c |
|d |
+-----+
>/tmp/delta/table$ ll
total 44
drwxrwxr-x 3 x x 4096 Jan 11 17:12 ./
drwxrwxr-x 3 x x 4096 Jan 11 17:10 ../
drwxrwxr-x 2 x x 4096 Jan 11 17:12 _delta_log/
-rw-r--r-- 1 x x 414 Jan 11 17:12 part-00000-0a0ae7fb-2995-4da4-8284-1ab85899fe9c-c000.snappy.parquet
-rw-r--r-- 1 x x 12 Jan 11 17:12 .part-00000-0a0ae7fb-2995-4da4-8284-1ab85899fe9c-c000.snappy.parquet.crc
-rw-r--r-- 1 x x 306 Jan 11 17:12 part-00000-37eb0bb2-cd27-42a4-9db3-b79cb046b638-c000.snappy.parquet
-rw-r--r-- 1 x x 12 Jan 11 17:12 .part-00000-37eb0bb2-cd27-42a4-9db3-b79cb046b638-c000.snappy.parquet.crc
-rw-r--r-- 1 x x 414 Jan 11 17:12 part-00000-8d6b4236-1a12-4054-b016-3db7a007cbab-c000.snappy.parquet
-rw-r--r-- 1 x x 12 Jan 11 17:12 .part-00000-8d6b4236-1a12-4054-b016-3db7a007cbab-c000.snappy.parquet.crc
-rw-r--r-- 1 x x 407 Jan 11 17:12 part-00000-d2612eaa-3f48-4708-bf90-31dd3d83f124-c000.snappy.parquet
-rw-r--r-- 1 x x 12 Jan 11 17:12 .part-00000-d2612eaa-3f48-4708-bf90-31dd3d83f124-c000.snappy.parquet.crc