flink - sink - hive

依赖

以下依赖均可以放到flink lib中,然后在pom中声明为provided

flink对hive的核心依赖

复制代码
<dependency>
    <groupId>org.apache.flink</groupId>
    <artifactId>flink-connector-hive_${scala.version}</artifactId>
    <version>${flink.version}</version>
    <scope>provided</scope>
</dependency>

没有hadoop环境时可以用此依赖代替

复制代码
<dependency>
    <groupId>org.apache.flink</groupId>
    <artifactId>flink-shaded-hadoop-3</artifactId>
    <version>${hadoop_version}</version>
    <scope>provided</scope>
</dependency>
hive-exec

hive的依赖,此依赖应该放在flink-shaded-hadoop后面,让工程优先访问flink-shaded-hadoop的依赖

复制代码
<dependency>
    <groupId>org.apache.hive</groupId>
    <artifactId>hive-exec</artifactId>
    <version>${hive.version}</version>
    <exclusions>
    <!-- remove conflict dependencies -->
    <exclusion>
            <groupId>org.apache.calcite</groupId>
            <artifactId>calcite-core</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.apache.calcite</groupId>
            <artifactId>calcite-druid</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.apache.calcite.avatica</groupId>
            <artifactId>avatica</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.apache.calcite</groupId>
            <artifactId>calcite-avatica</artifactId>
        </exclusion>
    </exclusions>
    <scope>provided</scope>
</dependency>
思路

dataStream转为flink table,再通过hive catalog写入到hive表中

写入到hive非分区表
复制代码
val streamEnv = ...
val dataStream = ...
val streamTableEnv = ...
streamTableEnv.createTemporaryView("自定义catalog表名", dataStream, *fields) # 当前flink存在bug,转换时必须指定fields或者schema,否则watermark无法流入table
val catalog = ...
streamTableEnv.registerCatalog("hive", catalog)
streamTableEnv.useCatalog("hive")
streamTableEnv.executeSql("insert sql").print()
写入到hive分区表
  1. streamEnv需要开启checkpoint,保证flink写入hive分区表的写入一致性
  2. hive表ddl中需要指定以下TBLPROPERTIES:
  • sink.partition-commit.trigger:分区提交触发器,单选,可选值为partition-time、process-time(默认), 其中==partition-time需要根据当前数据的watermark来判断分区是否需要提交,当watermark + delay大于等于分区上的时间时就会提交该分区元数据==;process-time的话根据当前系统处理时间来判断分区是否需要提交,当系统处理时间大于等于分区上的时间就会提交该分区元数据

  • partition.time-extractor.timestamp-pattern:使用partition-time触发器时使用该配置项。表示从表字段中提取出表达某个分区的时间的格式,==需要提取到的时间必须为yyyy-MM-dd HH:mm:ss的格式==。比如字段dt的格式为yyyy-MM-dd,则配置为$dt 00:00:00则表示分区时间取值为dt的value的0点0分0秒,可以选择多个表字段组合。当表字段无法抽取出符合的格式时,则使用自定义提取器partition.time-extractor.class。

  • sink.partition-commit.delay: 表示watermark允许event time的最大乱序时间,使用partition-time触发器时可以使用,默认为0s

  • sink.partition-commit.policy.kind:分区提交方式,多选,可选值为metastore、success-file、custom,metastore表示写入元数据库,success-file表示往hdfs分区目录写入一个标志文件,custom表示使用自定义提交方式,通常使用metastore,success-file组合

  • partition.time-extractor.kind:当要使用自定义分区时间提取器时需要配置此项,值配置为custom

  • partition.time-extractor.class:当要使用自定义分区时间提取器时需要配置此项,值配置为自定义提取器的类路径。在集群中运行时,需要把该类打成jar包放到flink lib目录下。

  • 某个分区触发提交后,后续再有此分区的数据进来,仍然会写入hive该分区。

    按process-time触发分区提交

    hive表ddl

    create table xxx(...)
    partitioned by(...)
    stored as orc
    tblproperties(
    'sink.partition-commit.trigger' = 'process-time',
    'sink.partition-commit.policy.kind'='metastore,success-file'
    )

    flink code

    val streamEnv = ...
    streamEnv.enableCheckpointing(...)
    val dataStream = ...
    val streamTableEnv = ...
    streamTableEnv.createTemporaryView("自定义catalog表名", dataStream)
    val catalog = ...
    streamTableEnv.registerCatalog("hive", catalog)
    streamTableEnv.useCatalog("hive")
    streamTableEnv.executeSql("insert sql").print()

    按partition-time触发分区提交

    hive表ddl, 使用默认分区时间提取器

    create table xxx(...)
    partitioned by(...)
    stored as orc
    tblproperties(
    'sink.partition-commit.trigger' = 'partition-time',
    'sink.partition-commit.policy.kind'='metastore,success-file',
    'partition.time-extractor.timestamp-pattern' = ...,
    'sink.partition-commit.delay' = ...,
    )

    flink code

    val streamEnv = ...
    streamEnv.enableCheckpointing(...)
    val dataStream = ... # 已添加watermark
    val streamTableEnv = ...
    streamTableEnv.createTemporaryView("自定义catalog表名", dataStream)
    val catalog = ...
    streamTableEnv.registerCatalog("hive", catalog)
    streamTableEnv.useCatalog("hive")
    streamTableEnv.executeSql("insert sql").print()

    按partition-time触发分区提交

    hive表ddl, 使用自定义分区时间提取器

    create table xxx(...)
    partitioned by(...)
    stored as orc
    tblproperties(
    'sink.partition-commit.trigger' = 'partition-time',
    'sink.partition-commit.policy.kind'='metastore,success-file',
    'partition.time-extractor.timestamp-pattern' = ...,
    'sink.partition-commit.delay' = ...,
    'partition.time-extractor.kind' = 'custom',
    'partition.time-extractor.class' = '自定义分区时间提取器类路径'
    )

    flink code

    以下自定义提取器实现从时间戳中提取出LocalDateTime,以符合partition.time-extractor的yyyy-MM-dd HH:mm:ss的格式要求

    class ExtractPartitionTimeFromUnixTimeStamp extends PartitionTimeExtractor {
    # 参数curPartitionValueList对应的是待作为分区时间提取的表分区字段中某个分区的值,每个分区都会调用一次此函数用来提取分区时间,来判断是否达到提交分区的条件
    # ConvertTimestampToDateTimeFunc返回的格式为yyyy-MM-dd HH:mm:ss的字符串
    # extract返回的LocalDateTime格式需要与分区粒度配合,例如按天分区时,LocalDateTime.parse中的参数格式可以为yyyy-MM-dd 00:00:00
    override def extract(curPartitionKeyList: util.List[String], curPartitionValueList: util.List[String]): LocalDateTime = {
    LocalDateTime.parse(ConvertTimestampToDateTimeFunc(curPartitionValueList.get(0)))
    }
    }

    val streamEnv = ...
    streamEnv.enableCheckpointing(...)
    val dataStream = ... # 已添加watermark
    val streamTableEnv = ...
    streamTableEnv.createTemporaryView("自定义catalog表名", dataStream)
    val catalog = ...
    streamTableEnv.registerCatalog("hive", catalog)
    streamTableEnv.useCatalog("hive")
    streamTableEnv.executeSql("insert sql").print()

相关推荐
数据与人工智能律师3 小时前
解码Web3:DeFi、GameFi、SocialFi的法律风险警示与合规路径
大数据·网络·人工智能·云计算·区块链
九河云4 小时前
TOS + 数字孪生:集装箱码头的智能进化密码
大数据·服务器·网络·数据库·数字化转型
说私域4 小时前
开源链动2+1模式AI智能名片S2B2C商城小程序在竞争激烈的中低端面膜服装行业中的应用与策略
大数据·人工智能·小程序
bemyrunningdog4 小时前
IntelliJ IDEA合并分支到master全攻略
大数据·elasticsearch·intellij-idea
孟意昶4 小时前
Doris专题17- 数据导入-文件格式
大数据·数据库·分布式·sql·doris
夫唯不争,故无尤也5 小时前
Maven创建Java项目实战全流程
java·数据仓库·hive·hadoop·maven
星光一影5 小时前
Java版小区物业管理系统/业主端/物业端/管理端/支持公众号、小程序、app
java·大数据·小程序
武子康5 小时前
大数据-125 - Flink 实时流计算中的动态逻辑更新:广播状态(Broadcast State)全解析
大数据·后端·flink
数在表哥5 小时前
从数据沼泽到智能决策:数据驱动与AI融合的中台建设方法论与技术实践指南(一)
大数据·人工智能
还是大剑师兰特6 小时前
Hadoop面试题及详细答案 110题 (71-85)-- 集群部署与运维
大数据·hadoop·大剑师·hadoop面试题