Spark读ES写入Hive

490 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第2天,点击查看活动详情

背景

公司有一部分的历史数据存储在es,现在需要es的数据与hive的数据关联处理得到新的数据,所以需要把es数据导入到hive

方案

  1. 使用SeaTunnel(seatunnel.apache.org/),但是由于版本不兼容…
  2. 自己写一个spark任务处理

结果

由于翻墙原因,很多jar依赖一直下载失败,所以使用自己写一个简单的spark任务处理

任务解析

环境初始化

val builder: SparkSession.Builder = SparkSession.builder.enableHiveSupport
val parameterMap: mutable.Map[String, String] = paramsMap.asScala
if(parameterMap != null){
  for ((k, v) <- parameterMap) {
    builder.config(k, v)
  }
}
val spark: SparkSession  = builder.getOrCreate

参数配置详解

var paramsMap = new util.HashMap[String, String]()
//是否开启动态资源配置,根据工作负载来衡量是否应该增加或减少executor,默认false
paramsMap.put("spark.dynamicAllocation.enabled", "false")
//任务名称,可在命令行指定
paramsMap.put("spark.app.name", "EsToHive")
//es地址
paramsMap.put("es.nodes", "xxx")
//es端口号
paramsMap.put("es.port", "9200")
//默认为 false,设置为 true 之后,会关闭节点的自动 discovery,只使用es.nodes声明的节点进行数据读写操作;如果你需要通过域名进行数据访问,则设置该选项为 true,否则请务必设置为 false;
paramsMap.put("es.nodes.wan.only", "true")
//默认情况下richDate为true,如果为false,则时间戳会当作Long处理,时间字符串当作Text处理
paramsMap.put("es.mapping.date.rich", "true")
//时间类型的格式
paramsMap.put("es.date.format", "epoch_millis")
//在DML/DDL中是否支持动态分区,默认false
paramsMap.put("hive.exec.dynamic.partition", "true")
//默认strict,在strict模式下,动态分区的使用必须在一个静态分区确认的情况下,其他分区可以是动态
paramsMap.put("hive.exec.dynamic.partition.mode", "nonstrict")
//每个mapper/reducer节点可以创建的最大动态分区数,默认100
paramsMap.put("hive.exec.max.dynamic.partitions.pernode", "10000")
//动态分区的上限,默认1000
paramsMap.put("hive.exec.max.dynamic.partitions", "10000")
//spark.sql.warehouse.dir是spark.sql运行hive的默认路径,如果想运行在hdfs上,可以通过这个配置项来实现,但是一定要是部署好的hive才会生效,spark内置的hive是会将元信息放到spark_home/bin目录下。
//spark.sql.warehouse.dir指定的就是数据的存放位置
paramsMap.put("spark.sql.warehouse.dir","hdfs://xxx/xxx/hive/warehouse")

执行过程

//生成es查询的dsl
val dsl =
  """
    |{"query":{"match_all":{}}}
    |""".stripMargin
//执行dsl
val ds = EsSparkSQL.esDF(spark, "xxx/_doc", dsl)
//创建临时视图表
ds.createOrReplaceTempView("tmp")
//数据写入hive表的sql
val sql =
  """
    |insert overwrite table ads.ads_xxx partition (staticdate)
    |select * from tmp
    |""".stripMargin

val dataFrame = spark.sql("select x from tmp")
dataFrame.show()
//数据写入hive表
spark.sql(sql)

关闭操作

spark.close()

任务提交命令

spark-submit --master yarn --deploy-mode cluster --class 全类名<com.xxx.xxx>  --driver-cores 1 --driver-memory 1G --num-executors 1 --executor-cores 1 --executor-memory 1G --name EsToHive --queue root.default  xxx.jar