spark

目标

我们的spark目标 是作为一个backup来使用 当tez有bug的时候启用备用的spark来完成此sql。所以呢表信息是只要一份就好。所以必须呢是使用之前的hive的schema,这就要求spark和hive必须集合起来用。

一Spark  与 hive 结合方式

1 Spark on Hive :数据源是:hive  Spark 获取hive中的数据,然后进行SparkSQL的操作  (hive只是作为一个spark的数据源)。  (我们是这种)

2 Hvie on Spark :(数据源是hive本身)   Hvie 将自己的MapReduce计算引擎替换为Spark,当我们执行HiveSQL(HQL)时 (这种方式修改的地方比较多 比较麻烦)

二选择Spark on Hive之后

 Spark on Hive 两种sql方式

1:是spark-sql 提交sql到yarn里完成

2:thrift  server 服务端口10016 接受sql 然后提交到yarn

这两种都可以采用两种方式来完成sql

1  Clint

2  yarn-client

Spark 运行的sql的时候需要两个东西 1driver 2 task

当选Clint 的时候呢 driver 和 task都在服务器本地完成。

当选择yarn-clint的时候

Driver 在服务器上运行 task在yarn上执行

spark-sql  和 thrift -server 他们之间sql解析会有不同

thrift -server 非常不好用 多几个连接会死 需要定时重启 还有bug

三 Driver 和 task 的关系

Driver 将数据从hdfs里获取 然后分配任务给task,总而言之就是管理task,和相关数据的程序

四Spark-sql on yarn-cluster

yarn-client 里 driver 会运行在本地服务器上 而且占用大量内存,这样导致yarn分配到的数据变少。Ambari里每台机器分到的内存设置必须是一样的。所以呢如果yarn-client运行在本地服务器上会造成大量内存浪费。

所以呢最好是使用spark-sql在cluster上运行

spark-submit \
  --name test-of-spark-sql-cluter-mode \
  --class org.apache.spark.sql.hive.my.SparkSQLExecute \
  --master yarn \
  --deploy-mode cluster \
  --executor-cores 2 \
  --executor-memory 4G \
  --num-executors 8 \
  --conf spark.executor.memoryOverhead=1G \
  --conf spark.submit.deployMode=cluster \
/home/xaadmin/my-spark-sql-cluster.jar  'prd' 'info' 'ods' 'select * from xxxx limit 10'

将下面scala打包成jar包

package org.apache.spark.sql.hive.my


import org.apache.log4j.{Level, Logger}
import org.apache.spark.internal.Logging
import org.apache.spark.sql.hive.HiveContext
import org.apache.spark.{SparkConf, SparkContext}


object SparkSQLExecute extends Logging {

  def main(args: Array[String]): Unit = {

    val startTime = System.currentTimeMillis
    log.info("=======================> 开始 <==========================")

    val app = s"${this.getClass.getSimpleName}".filter(!_.equals('$'))

    println("appName:" + app)

    // TODO: 初始化参数集合
    println("参数集合....")

    //参数校验
    if (args.length < 4) {
      logError("Usage: 未指定参数列表 " +
        "[env][loglevel] [hive_db] [SQL]")
      System.exit(1)
    }

    // TODO: 运行环境 (研发、测试、生产)
    val env = args(0)
    println("运行模式:" + env)

    // TODO: 日志级别设置
    val logLevel = args(1)
    println("日志级别:" + logLevel)

    logLevel match {
      case "debug" => Logger.getLogger("org").setLevel(Level.DEBUG)
      case "info" => Logger.getLogger("org").setLevel(Level.INFO)
      case "warn" => Logger.getLogger("org").setLevel(Level.WARN)
      case "error" => Logger.getLogger("org").setLevel(Level.ERROR)
    }


    // TODO: 验证参数
    println("验证参数....")

    val hive_db = args(2)

    val sqlText = args(3)




    // TODO:初始化环境
    println("初始化环境....")


    val sparkConf = new SparkConf()
      .setAppName(app)
      .set /*spark.sql.codegen 是否预编译sql成java字节码,长时间或频繁的sql有优化效果*/ ("spark.sql.codegen", "true")
      .set /*spark.sql.inMemoryColumnarStorage.batchSize 一次处理的row数量,小心oom*/ ("spark.sql.inMemoryColumnarStorage.batchSize", "20000")
      .set /*spark.sql.inMemoryColumnarStorage.compressed 设置内存中的列存储是否需要压缩*/ ("spark.sql.inMemoryColumnarStorage.compressed", "true")
      .set /*spark.sql.autoBroadcastJoinThreshold,解决数据倾斜*/ ("spark.sql.autoBroadcastJoinThreshold", "20971520")
      .set("hive.execution.engine", "spark")
    //      .set("spark.sql.shuffle.partitions","200")


    if (env.equals("local")) {
      sparkConf.setMaster("local[*]")
    }

    val sc = new SparkContext(sparkConf)

    logLevel match {
      case "debug" => sc.setLogLevel(Level.DEBUG.toString)
      case "info" => sc.setLogLevel(Level.INFO.toString)
      case "warn" => sc.setLogLevel(Level.WARN.toString)
      case "error" => sc.setLogLevel(Level.ERROR.toString)
    }

    val hiveContext = new HiveContext(sc)

    if (env.equals("prd")) {
      hiveContext.sql("use " + hive_db)
      hiveContext.sql("set hive.exec.dynamic.partition = true")
      hiveContext.sql("set hive.exec.dynamic.partition.mode = nonstrict")
    }

    val arr = sqlText.split(";")

    for (i <- 0 until arr.length) {
      println(arr(i))
      hiveContext.sql(arr(i)).show(false)
    }

    // TODO:输出
    //    resRDD.cache()
    //    if(env=="local"){
    //      resRDD.foreach(println)
    //    }
    //    val result_table = "LAR_DCS_RESULT_IND"
    //
    //    println(s"$result_table 数据量:"+resRDD.count)
    //
    //    if(env=="prd"){
    //      resRDD.saveAsTextFile(paramConf.getString("out.hdfs.path")+"_"+System.currentTimeMillis())
    //    }


    //    hiveContext.sql(s"LOAD DATA LOCAL INPATH '${hdfsPath}' OVERWRITE INTO TABLE sx_core_safe.LAR_DCS_RESULT_IND")


    //    val hdfs = org.apache.hadoop.fs.FileSystem.get(sc.hadoopConfiguration)
    //    val path = new Path(hdfsPath)
    //    if(hdfs.exists(path)){
    //      //为防止误删,禁止递归删除
    //      hdfs.delete(path,false)
    //    }

    //TODO:结束
    sc.stop()
    val endTime = System.currentTimeMillis
    println("耗时:" + (endTime - startTime) / 1000 + " 秒")
    println("=======================> 结束<==========================")
  }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值