[英]Spark Streaming From Kafka and Write to HDFS in Avro Format
我基本上想使用来自 Kafka 的数据并将其写入 HDFS。 但碰巧的是它没有在 hdfs 中写入任何文件。 它创建空文件。
如果我想在 hdfs 中以 avro 格式编写,请指导我如何修改代码。
为了简单起见,我正在写入本地 C 驱动器。
import org.apache.spark.SparkConf
import org.apache.kafka.common.serialization.StringDeserializer
import org.apache.spark.SparkContext
import org.apache.spark.streaming.Seconds
import org.apache.spark.streaming.StreamingContext
import org.apache.spark.streaming.kafka010.ConsumerStrategies.Subscribe
import org.apache.spark.streaming.kafka010.KafkaUtils
import
org.apache.spark.streaming.kafka010.LocationStrategies.PreferConsistent
import org.apache.kafka.common.serialization.StringDeserializer
object KafkaStreaming extends App{
val conf = new org.apache.spark.SparkConf().setMaster("local[*]").setAppName("kafka-streaming")
val conext = new SparkContext(conf)
val ssc = new StreamingContext(conext, org.apache.spark.streaming.Milliseconds(1))
val kafkaParams = Map[String, Object](
"bootstrap.servers" -> "localhost:9092",
"key.deserializer" -> classOf[StringDeserializer],
"value.deserializer" -> classOf[StringDeserializer],
"group.id" -> "group",
"auto.offset.reset" -> "latest",
"enable.auto.commit" -> (true: java.lang.Boolean))
val topics = Array("topic")
val stream = KafkaUtils.createDirectStream[String, String](
ssc,
PreferConsistent,
Subscribe[String, String](topics, kafkaParams))
val lines = stream.map(_.value)
stream.foreachRDD(rdd => {
rdd.coalesce(1).saveAsTextFile("C:/data/spark/")
})
ssc.start()
ssc.awaitTermination()}
下面是 build.sbt
name := "spark-streaming"
version := "1.0"
scalaVersion := "2.11.8"
libraryDependencies += "org.apache.spark" % "spark-core_2.11" % "2.2.0"
libraryDependencies += "org.apache.spark" % "spark-streaming_2.11" % "2.2.0"
libraryDependencies += "org.apache.spark" % "spark-streaming-kafka-0-
10_2.11" % "2.2.0"
libraryDependencies += "org.apache.kafka" % "kafka-clients" % "0.11.0.1"
不在 hdfs 中写入任何文件。 它创建空文件。
请在此处查看如何调试
无法在 Spark 中看到来自 Kafka Stream 的消息
如果我想在 hdfs 中以 avro 格式编写,请指导我
https://github.com/sryza/simplesparkavroapp
package com.cloudera.sparkavro
import org.apache.avro.mapred.AvroKey
import org.apache.avro.mapreduce.{AvroJob, AvroKeyOutputFormat}
import org.apache.hadoop.fs.Path
import org.apache.hadoop.io.NullWritable
import org.apache.hadoop.mapreduce.Job
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat
import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.SparkContext._
object SparkSpecificAvroWriter {
def main(args: Array[String]) {
val outPath = args(0)
val sparkConf = new SparkConf().setAppName("Spark Avro")
MyKryoRegistrator.register(sparkConf)
val sc = new SparkContext(sparkConf)
val user1 = new User("Alyssa", 256, null)
val user2 = new User("Ben", 7, "red")
val records = sc.parallelize(Array(user1, user2))
val withValues = records.map((x) => (new AvroKey(x), NullWritable.get))
val conf = new Job()
FileOutputFormat.setOutputPath(conf, new Path(outPath))
val schema = User.SCHEMA$
AvroJob.setOutputKeySchema(conf, schema)
conf.setOutputFormatClass(classOf[AvroKeyOutputFormat[User]])
withValues.saveAsNewAPIHadoopDataset(conf.getConfiguration)
}
}
看到你的代码,你可以简单地将当前时间戳附加到你正在编写的文件中。
那应该可以解决您的问题。 :)
==========
如果要将所有文件附加到一个文件中,则可以使用如下数据帧:
由于此文件系统的设计方式,我不建议在 HDFS 中使用 append。 但这是您可以尝试的方法。
例如:
val 数据框 = youRdd.toDF(); dataframe.write().mode(SaveMode.Append).format(FILE_FORMAT)..save(path);
看看有没有帮助
以下运行点的卡夫卡消费者应用程序之前,你必须检查:
检查数据在 Kafka 中是否可用
将auto.offset.reset
earliest
这里的最早是指kafka自动将偏移量重置为最早的偏移量。
启动 Kafka 控制台生产者应用程序并开始输入一些消息。 然后启动您的 Kafka 消费者代码,再次在 Kafka 控制台生产者上键入一些消息,然后检查消息是否正在打印到消费者控制台。
您可以使用以下代码行以 avro 格式编写输出
spark.write.avro("<path>")
我希望这会帮助你
将其从“auto.offset.reset”更改为“最新”,
到
"auto.offset.reset" -> "最早",
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.