将单个DStream拆分为多个Hive表

时间:2018-07-29 09:49:41

标签: apache-spark optimization apache-kafka spark-streaming

我正在研究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上,它显示未知阶段。 enter image description here

这是我的代码。

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)
              }

    }

}

我如何优化代码?

谢谢。

1 个答案:

答案 0 :(得分:1)

从管理的角度来看,我建议您将作业参数化以接受表名,然后运行15个单独的Spark应用程序。还要确保每个应用程序的kafka消费者组都不同

这样,您可以更轻松地监视哪个Spark作业的性能不及其他,而向一个表倾斜的数据不会引起其他问题。

尚不清楚Kafka消息密钥是什么,但是如果以表作为密钥来生成,则Spark可以随kafka分区一起扩展,并且可以确保每个表的所有消息都是有序的。 >

总体而言,我实际上将使用Kafka Connect或Streamsets来写入HDFS / Hive,而不必编写代码或调整Spark设置