我基本上想要从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"
答案 0 :(得分:1)
不在hdfs中写入任何文件。它会创建空文件。
请检查如何调试
Unable to see messages from Kafka Stream in Spark
如果我想在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)
}
}
答案 1 :(得分:1)
看到您的代码,您只需将当前时间戳附加到您正在编写的文件中即可。
那应该可以解决你的问题。 :)
==========
如果要将所有文件附加到一个文件中,则可以使用如下的数据框:
由于这个文件系统的设计方式,我不建议在HDFS中使用append。但这是你可以尝试的。
e.g:
val dataframe = youRdd.toDF(); 。dataframe.write()模式(SaveMode.Append).format(FILE_FORMAT)..保存(路径);
看看是否有帮助
答案 2 :(得分:0)
在点下运行Kafka消费者应用程序之前,您必须检查:
检查数据是否在Kafka中可用
将auto.offset.reset
更改为earliest
这里最早意味着kafka会自动将偏移重置为最早的偏移量。
启动Kafka控制台生产者应用程序并开始输入一些消息。然后启动您的Kafka消费者代码,再次在Kafka控制台生产者上键入一些消息,然后检查消息是否正在打印到消费者控制台。
您可以使用以下代码行以avro格式编写输出
spark.write.avro("<path>")
我希望这会对你有所帮助
答案 3 :(得分:0)
改成 "auto.offset.reset" -> "最新",
到
"auto.offset.reset" -> "最早",