flinkSQL+kafka+iceberg

基于flinkSQL+kafka+iceberg的测试。参考的链接是:https://www.icode9.com/content-4-827451.html基于文档将测试中踩过的坑给详细的记录一下。

1、flinkSQL要支持iceberg和hive需要引进两个jar包,将两个jar包放至flink lib目录下。
   iceberg-flink-runtime-0.11.1.jar
   flink-sql-connector-hive-2.2.0_2.11-1.11.3.jar
2、编辑flinkSQL加载的配置文件sql-client-defaults.yaml,添加默认加载的hive catalog
catalogs:
   - name: myhive
     type: hive
     hive-conf-dir: /opt/cloudera/parcels/CDH/lib/hive/conf

   - name: hive_catalog
     type: iceberg
     warehouse: hdfs:///data/hive_iceberg/warehouse/
     uri: thrift://X.X.X.X:9083
     catalog-type: hive

   - name: hadoop_catalog
     type: iceberg
     warehouse: hdfs:///data/iceberg/warehouse/
     catalog-type: hadoop
3、使用bin/sql-client.sh  embedded 命令进入flink sql客户端
   进入客户端之后show catalogs可以看到默认加载的myhive catalog
4、基于myhive catalog创建kafka流表
    CREATE TABLE myhive.test.ods_kafka_stream (
                 user_id STRING, 
                 order_amount DOUBLE, 
                 log_ts TIMESTAMP(3), 
                ) WITH ( 
                  'connector'='kafka',                    //连接器
                  'topic'='test_kafka_stream',            //kafka topic 
                  'scan.startup.mode'='latest-offset',    //消费kafka topic的消费模式。
                  'properties.bootstrap.servers'='X.X.X.X:9092',   
                  'properties.group.id' = 'test_01', 
                  'format'='json'  //kafka消息的格式
                );
    官网链接:https://ci.apache.org/projects/flink/flink-docs-release-1.11/zh/dev/table/connectors/kafka.html#start-reading-position
    查表数据时会报如下错误:
    (1)select * from myhive.test.ods_kafka_stream 
         [ERROR] Could not execute SQL statement. Reason:
         java.lang.ClassNotFoundException: org.apache.flink.streaming.connectors.kafka.FlinkKafkaConsumer
         需要重启flink集群
    
    (2)Flink SQL> select * from myhive.test.ods_kafka_stream;
         [ERROR] Could not execute SQL statement. Reason:
         java.lang.ClassNotFoundException: org.apache.kafka.common.serialization.ByteArrayDeserializer
         报错的原因是kafka序列化的问题,需要将kafka-clients-2.4.1.jar放至flink lib目录下。
    
    (3)Flink SQL> select * from myhive.test.ods_kafka_stream;
         java.lang.ClassCastException: org.apache.flink.shaded.jackson2.com.fasterxml.jackson.databind.node.MissingNode cannot be cast to org.apache.flink.shaded.jackson2.com.fasterxml.jackson.databind.node.ObjectNode
         需要将flink-shaded-jackson-2.10.1-11.0.jar放到flink lib目录下。
    
    Flink SQL> select * from myhive.test.ods_kafka_stream;运行监听流表数据。
5、启动一个topic test_kafka_stream的console producer
   kafka-console-producer --broker-list X.X.X.X:9092 --topic test_kafka_stream
   生产消息:
   {"user_id":"a1111","order_amount":11.0,"log_ts":"2020-06-29 12:30:00"}
   {"user_id":"a1111","order_amount":11.0,"log_ts":"2021-07-26 12:15:00"}
6、在监听的流表能看到刚刚生产的消息。
   
7、关联kafka流表和iceberg表
  (1)创建iceberg类型的hadoop catalog
   CREATE CATALOG hadoop_catalog WITH (
     'type'='iceberg',
     'catalog-type'='hadoop',
     'warehouse'='hdfs:///data/iceberg/warehouse/',
     'property-version'='1'
    );
  
  (2)创建iceberg表
    CREATE TABLE  hadoop_catalog.iceberg_db.ods_kafka_stream_iceberg ( 
                    user_id STRING COMMENT 'user_id', 
                    order_amount DOUBLE COMMENT 'order_amount', 
                    log_ts STRING 
                );
  (3)使用sql将kafka流表和iceberg表进行关联
    Flink SQL> insert into hadoop_catalog.iceberg_db.ods_kafka_stream_iceberg select  user_id, order_amount, DATE_FORMAT(log_ts, 'yyyy-MM-dd') FROM myhive.test.ods_kafka_stream;
    如果之前启动的kafka console producer没有关闭可以再利用这个console producer发送几条消息数据,如果已经关闭再启动kafka-console-producer --broker-list X.X.X.X:9092 --topic test_kafka_stream
    {"user_id":"a1111","order_amount":11.0,"log_ts":"2020-06-29 12:30:00"}
    {"user_id":"a1111","order_amount":11.0,"log_ts":"2021-07-26 12:15:00"}    
  
  (4)select * from hadoop_catalog.iceberg_db.ods_kafka_stream_iceberg会发现查找不到数据。
       原因:写数据到 Iceberg,data 目录数据一直在更新,但是 metadata 没有数据,导致查询的时候没有数据,因为 Iceberg 的查询是需要元数据来索引真实数据的。
       SQL Client 默认没有开启 checkpoint,需要通过配置文件来开启状态。所以会导致 data 目录写入数据而 metadata 目录不写入元数据。
       设置方法可以在flink-conf.yaml全局设置 或者sql-client-default.yaml文件下的configuration下设置 
       在sql-client-default.yaml下设置的:
       configuration:
          execution.checkpointing.interval: 10s
    设置之后重启flinkSQL客户端,然后将之前启动的insert JOB在webUI上面kill掉任务重新运行insert语句。
    如果之前启动的kafka console producer没有关闭可以再利用这个console producer发送几条消息数据,如果已经关闭再启动kafka-console-producer --broker-list X.X.X.X:9092 --topic test_kafka_stream
    {"user_id":"a1111","order_amount":11.0,"log_ts":"2020-06-29 12:30:00"}
    {"user_id":"a1111","order_amount":11.0,"log_ts":"2021-07-26 12:15:00"}    
    select * iceberg表能查看到新产生的数据。
8、使用hive客户端读取iceberg表数据
   hive读取iceberg数据需要用到iceberg-hive-runtime-0.11.1.jar包,将包放至hive的lib目录下。
   进入hive客户端创建外部表关联iceberg warehouse表目录
   CREATE EXTERNAL TABLE test.ods_kafka_stream_iceberg_hive(user_id STRING,order_amount DOUBLE,log_ts STRING)
   STORED BY 'org.apache.iceberg.mr.hive.HiveIcebergStorageHandler' 
   LOCATION '/data/iceberg/warehouse/iceberg_db/ods_kafka_stream_iceberg/'; //之前创建hadoop catalog时设置的warehouse目录。
   select * test.ods_kafka_stream_iceberg_hive能查看到表数据内容。

1、使用hive_catalog类型的iceberg表

创建hive_catalog
CREATE CATALOG hive_catalog WITH (
  'type'='iceberg',
  'catalog-type'='hive',
  'uri'='thrift://X.X.X.X:9083',
  'property-version'='1',
  'warehouse'='hdfs:///data/hive_iceberg/warehouse/'
);
】配置文件里面已经默认加载之后可以忽略创建
进入hive客户端创建iceberg的表
进入hive客户端后需要设置参数让hive支持iceberg

 -- 开启hive对iceberg的支持
SET engine.hive.enabled=true; 
SET iceberg.mr.catalog=hive;
set iceberg.engine.hive.enabled=true ;


在hive客户端创建iceberg表
CREATE TABLE  test.table_d ( 
         user_id STRING , 
         order_amount DOUBLE , 
         log_ts STRING 
     )
STORED BY 'org.apache.iceberg.mr.hive.HiveIcebergStorageHandler';


2、在flinkSQL中进行表关联
insert into hive_catalog.test.table_d select  user_id, order_amount, DATE_FORMAT(log_ts, 'yyyy-MM-dd') FROM  myhive.test.test_hive_iceberg;

对比hadoop_catalog和hive_catalog的区别:
如果使用hadoop_catalog则创建的iceberg表在hive中看不到需要重新创建外部表加载iceberg的数据目录。而hive_catalog的iceberg表则是和sparkSQL互通不需要再创建外部表。使用hadoop_catalog没有依赖版本依赖关系不依赖thrift就算thrift挂掉都不会影响iceberg表的读写。

hive_catalog统一的元数据管理,维护起来方便

在测试环境中用select * from table_d where user_id = '1'带where条件时报错:
java.lang.NoSuchMethodError: org.apache.hadoop.hive.ql.io.sarg.ConvertAstToSearchArg.create(Lorg/apache/hadoop/conf/Configuration;Lorg/apache/hadoop/hive/ql/plan/ExprNodeGenericFuncDesc;)Lorg/apache/hadoop/hive/ql/io/sarg/SearchArgument;
可用set hive.optimize.ppd=false;进行规避

Flink SQL中的维表JOIN是指将流式数据与外部数据源中的维表进行关联查询,为实时计算提供数据关联。在维表JOIN时,需要指明这条记录关联维表快照的时刻。需要注意的是,目前Flink SQL的维表JOIN仅支持对当前时刻维表快照的关联(处理时间语义),而不支持事实表rowtime所对应的维表快照(事件时间语义)。 下面是一个使用Flink SQL进行维表JOIN的例子: 假设我们有一个订单表order_table和一个商品表product_table,其中订单表中包含商品ID,我们需要将订单表中的商品ID关联到商品表中获取商品名称和价格等信息。这时我们可以使用维表JOIN来实现。 首先,我们需要在Flink SQL中创建订单表和商品表: ```sql CREATE TABLE order_table ( order_id BIGINT, product_id BIGINT, order_time TIMESTAMP(3), WATERMARK FOR order_time AS order_time - INTERVAL '5' SECOND ) WITH ( 'connector.type' = 'kafka', 'connector.version' = 'universal', 'connector.topic' = 'order_topic', 'connector.startup-mode' = 'latest-offset', 'connector.properties.zookeeper.connect' = 'localhost:2181', 'connector.properties.bootstrap.servers' = 'localhost:9092', 'format.type' = 'json' ); CREATE TABLE product_table ( product_id BIGINT, product_name STRING, price DECIMAL(10, 2), update_time TIMESTAMP(3), WATERMARK FOR update_time AS update_time - INTERVAL '5' SECOND ) WITH ( 'connector.type' = 'jdbc', 'connector.url' = 'jdbc:mysql://localhost:3306/test', 'connector.table' = 'product', 'connector.driver' = 'com.mysql.jdbc.Driver', 'connector.username' = 'root', 'connector.password' = '123456', 'connector.lookup.cache.max-rows' = '5000', 'connector.lookup.cache.ttl' = '10s' ); ``` 其中,order_table是从Kafka中读取的订单数据,product_table是从MySQL中读取的商品数据。 接下来,我们可以使用维表JOIN将订单表和商品表进行关联查询: ```sql SELECT o.order_id, o.product_id, p.product_name, p.price FROM order_table AS o JOIN product_table FOR SYSTEM_TIME AS OF o.order_time AS p ON o.product_id = p.product_id; ``` 在这个例子中,我们使用了FOR SYSTEM_TIME AS OF子句来指定关联维表的时刻为订单表中的订单时间。这样,我们就可以在Flink SQL中实现维表JOIN了。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值