flink1.11.0读取kafka数据写入hive中hive无分区信息及读取不到数据解决

一、前言

在上一博客中写了flink1.11.0读取kafka数据写入到hive中,发现hive中无法查询flink通过scala写入的数据,搜了些资料查找原因,参考了下文章:https://zhuanlan.zhihu.com/p/157899980 里无法读取hive数据的原因,但里面比较明确给出的解决方案是修改源码,我觉得太麻烦了。查了下官方和阅读些flink源码,终于找到一种我认为比较便捷的解决方案,具体分析方法如下:

完整的flink读取kafka数据动态写出hive,实现实时数仓的代码demo请参考上一篇文章:https://blog.csdn.net/m0_37592814/article/details/108044830

 

二、分析过程

1.StreamingFileCommitter 类中 commitPartitions 方法会调用PartitionTimeCommitTigger 类中的committablePartitions方法获取可提交的分区列表,然后变量分区提交分区。


2.主要是 PartitionTimeCommitTigger  类中的方法committablePartitions 用来获取需要提交分区的列表

里面需要  watermark > toMills(partTime) + commitDelay 成立 时才会把分区添加到需要提交分区列表中,这里是问题的关键,里面的 toMills(partTime) 方法转为毫秒时间时 会把 partTime 时间 往后8小时,所以会一直大于watermark 的值一直无法添加分区到需提交分区列表中

3.PartitionTimeExtractor 类   上图中的 extractor.extract()方法是实现了分区时间抽取接口 PartitionTimeExtractor 中的方法,查看flink官网:https://ci.apache.org/projects/flink/flink-docs-release-1.11/dev/table/connectors/filesystem.html 可以看出,可以自定义类实现 PartitionTimeExtractor 接口,重写里面的extract方法

4. PartitionTimeExtractor 实例对象 extractor 是由  PartitionTimeCommitTigger 类的构造方法根据读取配置信息来创建的,

当 'partition.time-extractor.kind'='custom' 是 使用自定义的实现PartitionTimeExtractor接口的分区时间抽取类,否则使用的是默认的DefaultPartTimeExtractor

5. 解决方案:使用自定义的分区抽取时间实现类MyPartTimeExtractor,重写 extract方法,方法的返回值partTime 时间减少8小时,如步骤2中所说  toMills(partTime)方法会把partTime时间因为时区问题多加8小时,这样一减一加则抵消掉时区的影响了。

三、解决方案实现

1.添加自定义分区时间抽取类 MyPartTimeExtractor 。  代码主要是复制默认PartitionTimeExtractor 另一实现类DefaultPartTimeExtractor 的逻辑,修改如下一行代码,减去8小时。并且添加无参构造函数,不然无法实例化

实现类完整代码参考 上一篇文章:https://blog.csdn.net/m0_37592814/article/details/108044830

2.hive建表是添加  partition.time-extractor.kind 和 partition.time-extractor.class 属性

如下:

3.hive验证

  • 6
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Apache Flink 是一个处理框架,支持从 Apache Kafka 读取数据,并将其写入 Apache HiveFlinkKafkaHive 输入/输出接口可以方便地配置和使用,以实现从 KafkaHive数据转。 ### 回答2: Flink是目前非常行的分布式数据处理引擎,而Kafka则是高性能、高可靠的分布式消息队列系统,而Hive是一种基于Hadoop的数据仓库系统。那么如何将FlinkKafka读取数据,并将数据写入Hive呢?下面介绍一下具体实现方式: 首先,需要在项目导入FlinkKafka的依赖包,然后配置Kafka连接信息,如Kafka的地址、zookeeper地址、Topic名称以及消费组的名称等信息。然后,就可以通过Flink提供的Kafka Consumer API来读取Kafka数据。在代码可以使用Flink DataStream API来进行数据转换、处理以及写入Hive等操作。 下面是一个FlinkKafka读取数据,然后将数据写入Hive的示例代码: ```java public class FlinkKafkaHiveDemo { public static void main(String[] args) throws Exception { StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment(); env.enableCheckpointing(5000); Properties properties = new Properties(); properties.setProperty("bootstrap.servers", "localhost:9092"); properties.setProperty("group.id", "test-consumer-group"); properties.setProperty("zookeeper.connect", "localhost:2181"); properties.setProperty("auto.offset.reset", "earliest"); properties.setProperty("enable.auto.commit", "false"); FlinkKafkaConsumer<String> consumer = new FlinkKafkaConsumer<>("test", new SimpleStringSchema(), properties); DataStream<String> stream = env.addSource(consumer); // 处理数据 DataStream<Tuple2<String, Integer>> result = stream .flatMap(new FlatMapFunction<String, Tuple2<String, Integer>>() { @Override public void flatMap(String s, Collector<Tuple2<String, Integer>> collector) throws Exception { String[] words = s.split("\\s+"); for (String word : words) { collector.collect(new Tuple2<>(word, 1)); } } }) .keyBy(0) .sum(1); // 将结果写入Hive final String dbName = "testDb"; final String tblName = "testTbl"; final String warehouseDir = "/user/hive/warehouse"; final String hiveConfDir = "/usr/local/hive/conf"; Configuration config = new Configuration(); config.set("hive.metastore.uris", "thrift://localhost:9083"); HiveConf hiveConf = new HiveConf(config, HiveConf.class); result.writeAsText("file:///home/user/result.txt"); result.addSink(new HiveSink<>(hiveConf, dbName, tblName, warehouseDir, new Tuple2RowConverter())); env.execute("Flink Kafka Hive Demo"); } } ``` 在代码,我们使用FlinkKafkaConsumer来读取Kafka名为test的Topic的数据,然后使用flatMap和sum对数据进行处理。接着,将结果写入Hive。在使用HiveSink对结果进行写入时,需要指定Hive相关的元数据信息,以及数据Hive的存储路径等信息的具体实现方法。最后,在命令行执行该代码即可。 总之,Flink读取Kafka并将数据写入Hive是非常常见且实用的一种方式,通过简单的配置和代码实现,可以实现对数据的高效处理和快速存储。 ### 回答3: Apache Flink作为一款实时大数据处理框架,支持读取来自Kafka数据并将其写入Hive,这也是Flink的常见应用场景之一。在介绍如何将数据Kafka写入Hive之前,有必要了解一下FlinkHive的相关知识。 Flink是一个开源的处理框架,具有高吞吐、低延迟、容错性强等优点。它支持多种数据源,包括Kafka、HDFS、文件、Socket、JDBC等。同时,Flink也支持将数据写入多种数据存储系统,如Hive、HBase、Cassandra等。 Hive是一个开源的数据仓库系统,它可以在Hadoop上进行数据管理和查询。通过Hive,用户可以使用SQL语言对数据进行查询、汇总、分析等操作。Hive数据存储在HDFS上,支持多种文件格式,如ORC、Parquet、Avro等。 要将数据Kafka写入Hive,需要先创建一个Flink数据,然后通过Flink提供的Kafka Consumer将数据读取数据。接着,使用Flink提供的HiveWriter将数据写入Hive。以下是具体步骤: 1. 创建Flink数据:使用Flink提供的StreamExecutionEnvironment创建数据,并为其指定数据源和数据存储方式。 2. 配置Kafka Consumer:使用Flink提供的Kafka Consumer将数据Kafka读取Flink数据。需要指定Kafka集群的地址、主题名称等参数。 3. 解析数据:在数据,每条数据可以是一个JSON对象、XML节点等格式,需要将其解析为可读取Hive的结构化数据,例如CSV格式。 4. 创建Hive表:在Hive创建一个表,用于存储来自Kafka数据。需要指定表的结构和文件格式,例如CSV、Parquet等。 5. 配置HiveWriter:使用Flink提供的HiveWriter将数据写入Hive。需要指定Hive表的名称、文件格式、文件路径等参数。 6. 启动任务:将以上步骤整合到一个Flink任务,并启动该任务,即可将来自Kafka数据写入Hive。 综上所述,Flink读取Kafka数据并将其写入Hive表的过程涉及到FlinkKafkaHive等多方面的知识,需要仔细地配置所有参数和细节,确保数据能够顺利地传输和存储。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值