Scala Spark HFileOutputFormat2.configureIncrementalLoadMap写HFile并doBulkLoad方式导入到HBase

 Spark写HFile不太建议:

1)一般写HFile是因为数据量很大,才使用这种方式,不然一般的API就可以满足;

2)用Spark写大量数据,中途需要去做排序,需要很大的内存与CPU,这种资源的使用是巨大的。

3)因为Executor内存的限制,CPU的限制,每次能写的数据量是有限的,并不能像MR一样可以写2T的数据或者更多。

4)Spark代码还是很费时的,在排序的时候。MR3个月的数据5个小时可以搞定。Spark一天的数据需要一个小时。可能还会有      GC时长过长,内存不足等问题。算子的优化也很难解决。

注:代码中很多注释是中途遇到的问题以及改善方式。

package com.xxx

import java.text.SimpleDateFormat

import com.xxx.HDFSUtil
import com.xxx.HFileUtil.COLUMN_FAMILY_NAME_LIST
import org.apache.hadoop.conf.Configuration
import org.apache.hadoop.fs.Path
import org.apache.hadoop.hbase.{HBaseConfiguration, KeyValue, TableName}
import org.apache.hadoop.hbase.client.{ConnectionFactory, Put}
import org.apache.hadoop.hbase.io.ImmutableBytesWritable
import org.apache.hadoop.hbase.mapred.TableOutputFormat
import org.apache.hadoop.hbase.mapreduce.{HFileOutputFormat2, LoadIncrementalHFiles}
import org.apache.hadoop.hbase.util.Bytes
import org.apache.hadoop.mapreduce.Job
import org.apache.spark.sql.{DataFrame, SparkSession}

import scala.collection.mutable.ListBuffer

/**
  * 需求:把历史通用数据,所有Qu ID每五分钟汇总最后一个ID数据为一条,保存于HBase
  * 例如: 1573149159 0000000001....  1573149229 0000000001...
  * 1573149160 00000002...
  * 汇总:2019/11/08 01:55:00 0000000001...00000002...
  * 本代码:
  *    1.把所有已配ID统计列出,保存于HDFS
  *    2.把ID读于哈希表中,对照数据,分类统计
  *    3.按分区读Hive表的HDFS文件,统计每个ID最后一条数据,汇总成一条,存于HBase
  *
  * @author wang.nengjie
  *
  */
object HFileQuFiveMinV2 {
  def main(args: Array[String]): Unit = {
    //    val format = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss")
    //    //本地模式
    //    System.setProperty("hadoop.home.dir", "D:\\D\\softs\\hadoop-2.8.1\\hadoop-common-2.2.0-bin-master")
    //    val warehouseLocation = "/spark-warehouse"
    //    val spark = SparkSession.builder()
    //      .appName("QuFiveMin")
    //      .config("hadoop.home.dir", "D:\\D\\softs\\hadoop-2.8.1\\hadoop-common-2.2.0-bin-master")
    //      .config("spark.sql.warehouse.dir", warehouseLocation)
    //      .config("spark.serializer", "org.apache.spark.serializer.KryoSerializer")
    //      .enableHiveSupport() //orc file must be hive support 本地Hive使用调试
    //      .master("local[*]")
    //      .getOrCreate()
    //集群环境
    val instances: Int = args(0).toInt
    val cores: Int = args(1).toInt
    val spark = SparkSession.builder()
      .appName("spark-QuFiveMin-hfile" + "-" + args.mkString("-"))
      .config("spark.executor.instances", instances) //executor个数
      .config("spark.default.parallelism", 10 * instances * cores) //该参数用于设置每个stage的默认task数量
      .config("spark.serializer", "org.apache.spark.serializer.KryoSerializer")
      .enableHiveSupport()
      .getOrCreate()
    spark.sparkContext.setLogLevel("ERROR")
    //    val path = "hdfs://10.44.200.101:8020/user/wang.nengjie/output/output_hdfs_path_charged_today/"
    //    val path = "hdfs://10.44.200.101:8020/user/xxx/xxx/xxx/funct=007/years=2018/months=01/days=01"
    //    println("获取目录下的一级文件和目录")
    //    HDFSUtil.getFilesAndDirs(path).foreach(println)
    //    println("获取目录下的一级文件")
    //    HDFSUtil.getFiles(path).foreach(println)
    //    println("获取目录下的一级目录")
    //    HDFSUtil.getDirs(path).foreach(println)
    //    println("获取目录下所有文件")//通过HDFS读数据
    //    HDFSUtil.getAllFiles(path).foreach(println)
    //因为读HDFS,文件比较多,一个个读比较繁琐
    //直接Hive SQL 方式,比较方便处理数据
    val columFamilyNamePath = "/user/wang.nengjie/input/five_min_qu_data_column_family_name" //有子ID的数据,QuID+子ID作为列名
    //    val columCommonNamePath =
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值