【数据湖Hudi-11-Hudi集成Hive】

7 篇文章 0 订阅
7 篇文章 0 订阅

Hudi集成Hive

Hudi 源表对应一份 HDFS 数据,通过 Spark,Flink 组件或者 Hudi CLI,可以将 Hudi 表的数据映射为 Hive 外部表,基于该外部表, Hive可以方便的进行实时视图,读优化视图以及增量视图的查询。

1.集成步骤

以 hive3.1.2、hudi 0.12.0为例,其他版本类似。

  • 1)拷贝编译好的jar包
    将 hudi-hadoop-mr-bundle-0.12.0.jar , hudi-hive-sync-bundle-0.12.0.jar 放到 hive 节点的lib目录下;
cp /opt/software/hudi-0.12.0/packaging/hudi-hadoop-mr-bundle/target/hudi-hadoop-mr-bundle-0.12.0.jar /opt/module/hive/lib/

cp /opt/software/hudi-0.12.0/packaging/hudi-hive-sync-bundle/target/hudi-hive-sync-bundle-0.12.0.jar /opt/module/hive/lib/
  • 2)配置完后重启 hive
    // 按照需求选择合适的方式重启
nohup hive --service metastore &
nohup hive --service hiveserver2 &

2.Hive同步

1 Flink 同步Hive

1)使用方式
Flink hive sync 现在支持两种 hive sync mode, 分别是 hms 和 jdbc 模式。 其中 hms 只需要配置 metastore uris;而 jdbc 模式需要同时配置 jdbc 属性 和 metastore uris,具体配置模版如下:

## hms mode 配置

CREATE TABLE t1(
  uuid VARCHAR(20),
  name VARCHAR(10),
  age INT,
  ts TIMESTAMP(3),
  `partition` VARCHAR(20)
)
PARTITIONED BY (`partition`)
with(
  'connector'='hudi',
  'path' = 'hdfs://xxx.xxx.xxx.xxx:9000/t1',
  'table.type'='COPY_ON_WRITE',        -- MERGE_ON_READ方式在没生成 parquet 文件前,hive不会有输出
  'hive_sync.enable'='true',           -- required,开启hive同步功能
  'hive_sync.table'='${hive_table}',              -- required, hive 新建的表名
  'hive_sync.db'='${hive_db}',             -- required, hive 新建的数据库名
  'hive_sync.mode' = 'hms',            -- required, 将hive sync mode设置为hms, 默认jdbc
  'hive_sync.metastore.uris' = 'thrift://ip:9083' -- required, metastore的端口
);

2)案例实操

CREATE TABLE t10(
  id int,
  num int,
  ts int,
  primary key (id) not enforced
)
PARTITIONED BY (num)
with(
  'connector'='hudi',
  'path' = 'hdfs://hadoop1:8020/tmp/hudi_flink/t10',
  'table.type'='COPY_ON_WRITE', 
  'hive_sync.enable'='true', 
  'hive_sync.table'='h10', 
  'hive_sync.db'='default', 
  'hive_sync.mode' = 'hms',
  'hive_sync.metastore.uris' = 'thrift://hadoop1:9083'
);


insert into t10 values(1,1,1); 

2 Spark 同步Hive

参数:https://hudi.apache.org/docs/basic_configurations#Write-Options
1)使用方式
以Spark shell为例:

 option("hoodie.datasource.hive_sync.enable","true").                         //设置数据集注册并同步到hive
  option("hoodie.datasource.hive_sync.mode","hms").                         //使用hms
  option("hoodie.datasource.hive_sync.metastore.uris", "thrift://ip:9083"). //hivemetastore地址
  option("hoodie.datasource.hive_sync.username","").                          //登入hiveserver2的用户
  option("hoodie.datasource.hive_sync.password","").                      //登入hiveserver2的密码
  option("hoodie.datasource.hive_sync.database", "").                   //设置hudi与hive同步的数据库
  option("hoodie.datasource.hive_sync.table", "").                        //设置hudi与hive同步的表名
  option("hoodie.datasource.hive_sync.partition_fields", "").               //hive表同步的分区列
  option("hoodie.datasource.hive_sync.partition_extractor_class", "org.apache.hudi.hive.MultiPartKeysValueExtractor"). // 分区提取器 按/ 提取分区

2)案例实操

import org.apache.hudi.QuickstartUtils._
import scala.collection.JavaConversions._
import org.apache.spark.sql.SaveMode._
import org.apache.hudi.DataSourceReadOptions._
import org.apache.hudi.DataSourceWriteOptions._
import org.apache.hudi.config.HoodieWriteConfig._

val tableName = "hudi_trips_cow"
val basePath = "file:///tmp/hudi_trips_cow"
val dataGen = new DataGenerator

val inserts = convertToStringList(dataGen.generateInserts(10))
val df = spark.read.json(spark.sparkContext.parallelize(inserts, 2))
        .withColumn("a",split(col("partitionpath"),"\\/")(0))
        .withColumn("b",split(col("partitionpath"),"\\/")(1))
        .withColumn("c",split(col("partitionpath"),"\\/")(2))
df.write.format("hudi").
  options(getQuickstartWriteConfigs).
  option(PRECOMBINE_FIELD_OPT_KEY, "ts").
  option(RECORDKEY_FIELD_OPT_KEY, "uuid").
  option("hoodie.table.name", tableName). 
  option("hoodie.datasource.hive_sync.enable","true").
  option("hoodie.datasource.hive_sync.mode","hms").
  option("hoodie.datasource.hive_sync.metastore.uris", "thrift://hadoop1:9083").
  option("hoodie.datasource.hive_sync.database", "default").
  option("hoodie.datasource.hive_sync.table", "spark_hudi").
  option("hoodie.datasource.hive_sync.partition_fields", "a,b,c").
  option("hoodie.datasource.hive_sync.partition_extractor_class", "org.apache.hudi.hive.MultiPartKeysValueExtractor").
  mode(Overwrite).
  save(basePath)

3.Flink使用HiveCataLog

1.直接使用Hive Catalog

1)上传hive connector到flink的lib中
hive3.1.3的connector存在guava版本冲突,需要解决:官网下载connector后,用压缩软件打开jar包,删除/com/google文件夹。处理完后上传flink的lib中。

2)解决与hadoop的冲突
避免与hadoop的冲突,拷贝hadoop-mapreduce-client-core-3.1.3.jar到flink的lib中(5.2.1已经做过)
3)创建catalog

CREATE CATALOG hive_catalog
  WITH (
    'type' = 'hive',
    'default-database' = 'default',
    'hive-conf-dir' = '/opt/module/hive/conf',
'hadoop-conf-dir'='/opt/module/hadoop-3.1.3/etc/hadoop'
  );

use catalog hive_catalog;

– hive-connector内置了hive module,提供了hive自带的系统函数

load module hive with ('hive-version'='3.1.2');
show modules;
show functions;

– 可以调用hive的split函数

select split('a,b', ',');

2 Hudi Catalog使用hms

CREATE CATALOG hoodie_hms_catalog
WITH (
‘type’=‘hudi’,
‘catalog.path’ = ‘/tmp/hudi_hms_catalog’,
‘hive.conf.dir’ = ‘/opt/module/hive/conf’,
‘mode’=‘hms’,
‘table.external’ = ‘true’
);

4.创建Hive外表并查询

Hive同步Hudi的MOR 表时候,会映射两张Hive外部表:hudi_mor_ro(ro表)和 hudi_mor_rt(rt表)。

  • ro 表全称 read oprimized table,对于 MOR 表同步的 xxx_ro 表,只暴露压缩后的 parquet。
  • 增量查询针对的rt表

5.Hive Sync Tool

若写入引擎没有开启自动同步,则需要手动利用 Hudi 客户端工具进行同步,Hudi提供Hive sync tool用于同步Hudi最新的元数据(包含自动建表、增加字段、同步分区信息)到hive metastore。
Hive sync tool提供三种同步模式,JDBC,HMS,HIVEQL。这些模式只是针对Hive执行DDL的三种不同方式。在这些模式中,JDBC或HMS优于HIVEQL, HIVEQL主要用于运行DML而不是DDL。

  • 1.使用语法及参数
    脚本位置在hudi源码路径下的hudi-sync/hudi-hive-sync/run_sync_tool.sh

  • 2 .解决依赖问题
    run_sync_tool.sh这个脚本就是查找hadoop、hive和bundle包的依赖,实际上使用的时候会报错各种ClassNotFoundException、NoSuchMethod,所以要动手修改依赖的加载逻辑,如下
    1)修改hadoop、hive、hudi-hive-sync-bundle-0.12.0.jar的依赖加载
    (1)将34行 HUDI_HIVE_UBER_JAR=xxxx 注释掉
    在这里插入图片描述
    (2)将52行 HADOOP_HIVE_JARS=xxx注释掉
    #在 54行 添加如下:

HADOOP_HIVE_JARS=`hadoop classpath`:$HIVE_HOME/lib/*
HUDI_HIVE_UBER_JAR=/opt/software/hudi-0.12.0/packaging/hudi-hive-sync-bundle/target/hudi-hive-sync-bundle-0.12.0.jar

在这里插入图片描述

2)解决parquet-column的版本冲突
(1)上传parquet-column-1.12.2.jar到/opt/software/,脚本中添加如下:

PARQUET_JAR=/opt/software/parquet-column-1.12.2.jar

在这里插入图片描述

(2)拼接路径到命令最前面(只能最前面!)
在这里插入图片描述
(3)保存退出

  • 3.JDBC模式同步
    通过hive2 jdbc协议同步,提供的是hive server2的地址,如jdbc:hive2://hive-server:10000。默认为jdbc。
cd /opt/software/hudi-0.12.0/hudi-sync/hudi-hive-sync

./run_sync_tool.sh \
--base-path hdfs://hadoop1:8020/tmp/hudi_flink/t2/ \
--database default \
--table t2_flink \
--jdbc-url jdbc:hive2://hadoop1:10000 \
--user atguigu \
--pass atguigu \
--partitioned-by num
  • 4.HMS模式同步
    提供hive metastore的地址,如thrift://hms:9083,通过hive metastore的接口完成同步。使用时需要设置 --sync-mode=hms。
    如果使用的是远程metastore,那么确保hive-site.xml配置文件中设置
hive.metastore.uris。
./run_sync_tool.sh  \
--base-path hdfs://hadoop1:8020/tmp/hudi_flink/t3 \
--database default \
--table t3_flink  \
--user atguigu \
--pass atguigu \
--partitioned-by age \
--sync-mode hms \
--jdbc-url thrift://hadoop1:9083 

6.湖仓一体能力

门店相关的需求任务,实现了湖仓一体能力。
具体过程如下:
1.使用一站式大数据开发平台StreamX,在线编写FlinkCDC,mysql开启binlog,编写FlinkCDC程序,将mysql数据同步到kafka中,继续编写FlinkCDC程序,将kafka数据同步到Hudi中。
2.Hudi的MOR类型表格数据同步到Hive中,使用Hive Sync Tool同步工具,此刻Hive中就有xxx_ro表和xxx_rt表。ro表是 Compaction之后全部的parquet文件,不包括log文件,查询可以获取此刻的全量数据;rt表是增量的数据,两个表格同步查询,可以实现近实时的这种业务需求。做到真正的湖仓一体。

  • 注意:
    • 1.使用kafka做中间缓存件,而不直接使用FlinkCDC写入hudi,这样做的考虑:
      • kafka作为中间缓存件,有效避免了,像双11这种活动的大促情况,在mysql频繁更新的情况下,减少了flink端的数据背压情况。
      • 出现了大促这种频繁更新mysql的情况,可以使用Hudi的限流机制,这样也可以减少flink端背压情况。
    • 2.hudi作为数据存储的底层,而不是直接使用HDFS,一方面可以有效减少小文件的产生,Hudi天生就对小文件有优化机制;另一方面数据更新等操作,直接在Hudi中实现,减少了原始拉链表这种情况的发生,数据资源得到了极大地释放。
    • 3.历史全量数据的同步,需要使用全量转增量的机制,或者可以使用hudi的限流机制。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值