Hive数据导入到HBase
1. 背景
- 作为一个数据处理框架,hive本身并不计算和存储数据,计算引擎一般是mapreduce,tez,spark,数据存储则是在hdfs中,元数据一般在mysql中。
- hive将数据计算处理之后,如果数据结果需要对外提供并且有秒或亚秒级别的访问速度,并且跟hadoop生态有较好的兼容性,则hbase是一个很好的选择。当然实际上只是数据存储,mysql,elasticsearch,clickhouse都可以胜任亚秒级别的数据访问性能。
- 当业务需要,将hive数据导入hbase时,一般有2种场景。一种是数据流入hbase,也就是数据来一条,导入一条到hbase;另外一种就是一次性批量导入到habse;
- 上述2种在实际开发中都有应用,看业务场景不同做选择。
- hbase本身支持逐条导入,可以使用shell命令,jdbc方式将数据导入;也可以使用bulkload方式,使用shell或者代码方式,直接将数据批量导入。
2. 案例1
- 使用hive的api,逐条put插入即可
3. 案例2
- 使用hive自带的工具做buldkload,但对源数据文件格式有要求,必须是csv文件格式。
- 这样一来,要么先将数据转为这种格式,要么使用案例3的方式,一切自定义控制。
- 使用hive自带导入hbase工具
- 有一个csv文件
- 生成hfile文件
hadoop jar ${HBASE_HOME}/lib/hbase-mapreduce-2.0.6.jar \
importtsv -Dimporttsv.columns=HBASE_ROW_KEY,f:c1,f:c2 \
-Dimporttsv.bulk.output=hdfs://hfilefile/output <tablename> hdfs://input/file/path
-Dimporttsv.bulk.output=/path/for/output 输出目录
-Dimporttsv.skip.bad.lines=false 是否跳过脏数据行
‘-Dimporttsv.separator=|’ 指定分隔符
-Dimporttsv.timestamp=currentTimeAsLong 是否指定时间戳
-Dimporttsv.mapper.class=my.Mapper 替换默认的Mapper类
- 将hfile导入hbase
bin/hbase org.apache.hadoop.hbase.tool.LoadIncrementalHFiles <hdfs://hfilefile/output> <tablename>
4. 案例3
object ImportSessionAgr2Hbase {
def main(args: Array[String]): Unit = {
Logger.getLogger("org").setLevel(Level.WARN)
val spark = SparkSession.builder()
.appName("hive表 流量会话聚合表 导入 HBASE")
.master("local")
.enableHiveSupport()
.getOrCreate()
// 用spark去加载hive表
val agrTable = spark.read.table("dws.app_trf_agr_session").where("dt='2020-10-07'")
// guid|session_id|start_ts|end_ts|first_page_id|last_page_id|pv_cnt|isnew|hour_itv|country|province|city|region|device_type
// 整理成hbase的KV结构
val argTableFlat: RDD[(String, String, String, String)] = agrTable.rdd
.flatMap(row => {
val guid = row.getAs[String]("guid") + ""
val session_id = row.getAs[String]("session_id") + ""
val start_ts = row.getAs[Long]("start_ts") + ""</