我正在研究Kafka Spark流媒体项目。 Spark流从Kafka获取数据。数据为json格式。样本输入
{ “ table”:“ tableA”, “ Product_ID”:“ AGSVGF.upf”, “ file_timestamp”:“ 2018-07-26T18:58:08.4485558Z000000000000000”, “ hdfs_file_name”:“ null_1532631600050”, “ Date_Time”:“ 2018-07-26T13:45:01.0000000Z”, “ User_Name”:“ UBAHTSD” }
{ “ table”:“ tableB”, “ Test_ID”:“ FAGS.upf”, “ timestamp”:“ 2018-07-26T18:58:08.4485558Z000000000000000”, “ name”:“ flink”, “ time”:“ 2018-07-26T13:45:01.0000000Z”, “ Id”:“ UBAHTGADSGSCVDGHASD” }
一个JSON字符串就是一条消息。 JSON字符串有15种类型,可以使用表列进行区分。现在,我想在Apache Hive中保存这15种不同的JSON。因此,我创建了一个dstream,并在表列的基础上过滤了rdd并保存到Hive中。代码工作正常。但是有些时候,它会花费很多时间,然后产生批处理。我已经使用spark.streaming.kafka.maxRatePerPartition=10
控制了输入。我已经将rdd重新分区为9分区,但是在Spark UI上,它显示未知阶段。
这是我的代码。
val dStream = dataStream.transform(rdd => rdd.repartition(9)).map(_._2)
dStream.foreachRDD { rdd =>
if (!rdd.isEmpty()) {
val sparkContext = rdd.sparkContext
rdd.persist(StorageLevel.MEMORY_AND_DISK)
val hiveContext = getInstance(sparkContext)
val tableA = rdd.filter(_.contains("tableA"))
if (!tableA.isEmpty()) {
HiveUtil.tableA(hiveContext.read.json(tableA))
tableA.unpersist(true)
}
val tableB = rdd.filter(_.contains("tableB"))
if (!tableB.isEmpty()) {
HiveUtil.tableB(hiveContext.read.json(tableB))
tableB.unpersist(true)
}
.....
.... upto 15 tables
....
val tableK = rdd.filter(_.contains("tableK"))
if (!tableB.isEmpty()) {
HiveUtil.tableB(hiveContext.read.json(tableK))
tableB.unpersist(true)
}
}
}
我如何优化代码?
谢谢。
答案 0 :(得分:1)
从管理的角度来看,我建议您将作业参数化以接受表名,然后运行15个单独的Spark应用程序。还要确保每个应用程序的kafka消费者组都不同
这样,您可以更轻松地监视哪个Spark作业的性能不及其他,而向一个表倾斜的数据不会引起其他问题。
尚不清楚Kafka消息密钥是什么,但是如果以表作为密钥来生成,则Spark可以随kafka分区一起扩展,并且可以确保每个表的所有消息都是有序的。 >
总体而言,我实际上将使用Kafka Connect或Streamsets来写入HDFS / Hive,而不必编写代码或调整Spark设置