本文共 4150 字,大约阅读时间需要 13 分钟。
先看看官网是怎么描述Hive Streaming Sink的吧
SET table.sql-dialect=hive;CREATE TABLE hive_table ( user_id STRING, order_amount DOUBLE) PARTITIONED BY (dt STRING, hr STRING) STORED AS parquet TBLPROPERTIES ( 'partition.time-extractor.timestamp-pattern'='$dt $hr:00:00', 'sink.partition-commit.trigger'='partition-time', 'sink.partition-commit.delay'='1 h', 'sink.partition-commit.policy.kind'='metastore,success-file');SET table.sql-dialect=default;CREATE TABLE kafka_table ( user_id STRING, order_amount DOUBLE, log_ts TIMESTAMP(3), WATERMARK FOR log_ts AS log_ts - INTERVAL '5' SECOND) WITH (...);-- streaming sql, insert into hive tableINSERT INTO TABLE hive_table SELECT user_id, order_amount, DATE_FORMAT(log_ts, 'yyyy-MM-dd'), DATE_FORMAT(log_ts, 'HH') FROM kafka_table;-- batch sql, select with partition pruningSELECT * FROM hive_table WHERE dt='2020-05-20' and hr='12';
参数给大家稍微解析一下
partition.time-extractor.timestamp-pattern
:分区时间抽取器,与DDL中的分区字段保持一致sink.partition-commit.trigger
:分区触发器类型,需要Source表中定义watermark,当watermark > 提取到的分区时间+sink.partition-commit.delay
中定义的时间,那么就将当前分区提交sink.partition-commit.delay
:相当于延时时间吧sink.partition-commit.policy.kind
:怎么提交,一般提交成功之后,需要通知metastore,这样hive才能读到你最新分区的数据;如果需要合并小文件,也可以自定义Class,通过实现PartitionCommitPolicy接口说了这么多,光说不干假把式,下面就让我们来试一下Hive Streaming Sink
先搞个Source,让我们来试一下新的connector
%flink.ssqldrop table if exists datagen;CREATE TABLE datagen ( f_sequence INT, f_random INT, f_random_str STRING, ts AS localtimestamp, WATERMARK FOR ts AS ts) WITH ( 'connector' = 'datagen', -- optional options -- 'rows-per-second'='5', 'fields.f_sequence.kind'='sequence', 'fields.f_sequence.start'='1', 'fields.f_sequence.end'='50',-- 这个地方限制了一共会产生的条数 'fields.f_random.min'='1', 'fields.f_random.max'='50', 'fields.f_random_str.length'='10');
再注册一个Hive Sink Table,不过在建表之前,先使用Scala代码将Sql方言切换到hive
%flink//set table.dynamic-table-options.enabled=true// 使用默认方言// stenv.getConfig().setSqlDialect(SqlDialect.DEFAULT);// 使用hive方言,如果没有这一步的话,注册hive表的时候,会报错stenv.getConfig().setSqlDialect(SqlDialect.HIVE);// 如果需要使用Table Hints 功能,请执行这个stenv.getConfig().getConfiguration.setBoolean("table.dynamic-table-options.enabled",true)
%flink.ssqldrop table if exists hive_table;CREATE TABLE hive_table ( f_sequence INT, f_random INT, f_random_str STRING) PARTITIONED BY (dt STRING, hr STRING, mi STRING) STORED AS parquet TBLPROPERTIES ( 'partition.time-extractor.timestamp-pattern'='$dt $hr:$mi:00', 'sink.partition-commit.trigger'='partition-time', 'sink.partition-commit.delay'='1 min', 'sink.partition-commit.policy.kind'='metastore,success-file');
最关键的一步
%flink.ssqlinsert into hive_table select f_sequence,f_random,f_random_str ,DATE_FORMAT(ts, 'yyyy-MM-dd'), DATE_FORMAT(ts, 'HH') ,DATE_FORMAT(ts, 'mm') from datagen
最后,让我们用Batch模式查一下表里面的数据吧
因为我们的datagen一共产生了50条数据,所以上面也count(*)了一下,对一下数据总量,确定数据全部写入
Hive Streaming Sink先聊到这,下面让我们看看Hive Streaming Source
一样,先贴一下官网的描述,再给大家解释一下参数的意思
Hive中的表会有两种类型
再给大家说说参数的意思
stream-source.enable
:显而易见,表示是否开启流模式stream-source.monitor-interval
:监控新文件/分区产生的间隔stream-source.consume-order
:可以选create-time或者partition-time;create-time指的不是分区创建时间,而是在HDFS中文件/文件夹的创建时间;partition-time指的是分区的时间,看官网的意思,如果使用了这个,分区下有新文件产生了,会影响到数据,不过经过我的测试,并不会影响到,不知道是不是我的姿势不对,我是直接在HDFS目录下把文件又复制一遍,重启任务能读到数据,不重启的情况下,两个参数都不能读到已有分区下的新数据,大家如果有更好的理解可以指出来;对于非分区表,只能用create-time。stream-source.consume-start-offset
:表示从哪个分区开始读演示一下
%flink.ssql(type=update)SELECT count(*) FROM hive_table /*+ OPTIONS('streaming-source.enable'='true', 'streaming-source.consume-start-offset'='2020-07-19')*/;
如果此时通过HDFS命令行去往已有的分区插入新的文件,你会发现并不能读取到新文件的数据,大家可以自行尝试一下
再启动一下Hive Streaming Sink中,往Hive写入数据的任务,看看结果
没问题,看来我们整合的很成功!
最后,向大家宣传一下Flink on Zeppelin 的钉钉群,大家有问题可以在里面讨论,简锋大佬也在里面,有问题直接提问就好(一群已满,请加二群)
转载地址:http://edmo.baihongyu.com/