flink sql lookup join学习demo

flink sql lookup join demo

本文主要是通过一个小的案例,记录使用flinksql lookup join的使用,其中mysql作为lookup join的维表

1.source数据源准备

-- 在mysql中创建表source源表
DROP TABLE IF EXISTS `show_log`;
CREATE TABLE `show_log` (
  `log_id` int(11) NOT NULL,
  `timestamp` datetime DEFAULT NULL,
  `user_id` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`log_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

-- 插入数据
INSERT INTO `show_log` VALUES ('1', '2021-11-01 00:01:03', 'a'), ('2', '2021-11-01 00:03:00', 'b'), ('3', '2021-11-01 00:05:00', 'c'), ('4', '2021-11-01 00:06:00', 'b'), ('5', '2021-11-01 00:07:00', 'c');

2.维表数据准备

-- 在mysql中创建维度表
DROP TABLE IF EXISTS `user_profile`;
CREATE TABLE `user_profile` (
  `user_id` varchar(255) NOT NULL,
  `age` varchar(255) DEFAULT NULL,
  `sex` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

-- 插入数据
INSERT INTO `user_profile` VALUES ('a', '12-18', '男'), ('b', '18-24', '女'), ('c', '18-24', '男');

3.创建flink映射表

3.1创建source端映射表
CREATE TABLE show_log (
    log_id BIGINT,
    `timestamp` as cast(CURRENT_TIMESTAMP as timestamp(3)),
    user_id STRING,
    proctime AS PROCTIME()
)
WITH (
    'connector' = 'mysql-cdc',
    'hostname' = 'localhost',
    'username' = 'xx',
    'port' = '3306',
    'password' = 'xxx',
    'database-name' = 'flink',
    'table-name' = 'show_log',
    'scan.startup.mode' = 'initial',
    'scan.incremental.snapshot.enabled' = 'false'
);
3.2创建维度映射表
CREATE TABLE user_profile (
    user_id STRING,
    age STRING,
    sex STRING
    ) WITH (
        'connector' = 'jdbc',
        'url' = 'jdbc:mysql://localhost:3306/flink?characterEncoding=UTF8',
        'username' = 'xx',
        'password' = 'xx',
        'table-name' = 'user_profile',
        'lookup.cache.max-rows' = '100',
        'lookup.cache.ttl' = '6000s'
);
3.3创建sink端映射表
-- 使用print connector在flink web ui中打印输出
CREATE TABLE sink_table (
    log_id BIGINT,
    `timestamp` TIMESTAMP(3),
    user_id STRING,
    proctime TIMESTAMP(3),
    age STRING,
    sex STRING
) WITH (
  'connector' = 'print'
);

4sql-client提交

INSERT INTO sink_table
SELECT 
    s.log_id as log_id
    , s.`timestamp` as `timestamp`
    , s.user_id as user_id
    , s.proctime as proctime
    , u.sex as sex
    , u.age as age
FROM show_log AS s
LEFT JOIN user_profile FOR SYSTEM_TIME AS OF s.proctime AS u
ON s.user_id = u.user_id;

在这里插入图片描述

5flink web ui查看任务信息

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
如果任务在运行过程中taskmanager日志有报GC,可查看taskmanager metrics信息,观察对应指标是否打满,从而重新修改对应配置文件的参数重启集群。
在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
这是一个基于 Flink SQL 实现的简单实时处理的 demo,其中包含了一个 join 操作。 首先,我们需要准备两个数据流,分别是订单数据和用户数据。可以使用 Flink 的 DataStream API 从 Kafka 中读取实时数据,也可以使用模拟数据生成工具来生成测试数据。 ```java // 订单数据流 DataStream<Order> orderStream = env.addSource(new FlinkKafkaConsumer<>("order-topic", new OrderDeserializationSchema(), properties)) .assignTimestampsAndWatermarks(new OrderTimestampExtractor()); // 用户数据流 DataStream<User> userStream = env.addSource(new FlinkKafkaConsumer<>("user-topic", new UserDeserializationSchema(), properties)) .assignTimestampsAndWatermarks(new UserTimestampExtractor()); ``` 接下来,我们使用 Flink SQL 将两个数据流进行 join 操作。需要注意的是,Flink SQL 中的 join 操作需要指定连接条件和窗口类型。 ```java // 注册临时视图 tableEnv.createTemporaryView("orders", orderStream, $("orderId"), $("userId"), $("orderTime").rowtime()); tableEnv.createTemporaryView("users", userStream, $("userId"), $("userName"), $("gender")); // 执行 join 操作 Table resultTable = tableEnv.sqlQuery("SELECT o.orderId, o.orderTime, u.userName FROM orders o " + "JOIN users u ON o.userId = u.userId " + "WHERE o.orderTime BETWEEN u.rowtime - INTERVAL '5' SECOND AND u.rowtime + INTERVAL '5' SECOND"); // 将结果转换为数据流 DataStream<Result> resultStream = tableEnv.toAppendStream(resultTable, Result.class); ``` 最后,我们可以将结果数据流写入到 Kafka 中,或者直接打印出来。 ```java // 将结果写入到 Kafka 中 resultStream.addSink(new FlinkKafkaProducer<>("result-topic", new ResultSerializationSchema(), properties)); // 打印结果 resultStream.print(); ``` 完整的示例代码如下: ```java // 定义订单数据结构 public class Order { public long orderId; public long userId; public Timestamp orderTime; } // 定义用户数据结构 public class User { public long userId; public String userName; public String gender; } // 定义 join 结果数据结构 public class Result { public long orderId; public Timestamp orderTime; public String userName; } // 订单数据流的时间戳提取器 public class OrderTimestampExtractor extends BoundedOutOfOrdernessTimestampExtractor<Order> { public OrderTimestampExtractor() { super(Time.seconds(10)); } @Override public long extractTimestamp(Order element) { return element.orderTime.getTime(); } } // 用户数据流的时间戳提取器 public class UserTimestampExtractor extends BoundedOutOfOrdernessTimestampExtractor<User> { public UserTimestampExtractor() { super(Time.seconds(10)); } @Override public long extractTimestamp(User element) { return System.currentTimeMillis(); } } public class FlinkSQLJoinDemo { public static void main(String[] args) throws Exception { StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment(); env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime); StreamTableEnvironment tableEnv = StreamTableEnvironment.create(env); Properties properties = new Properties(); properties.setProperty("bootstrap.servers", "localhost:9092"); properties.setProperty("group.id", "test-group"); // 订单数据流 DataStream<Order> orderStream = env.addSource(new FlinkKafkaConsumer<>("order-topic", new OrderDeserializationSchema(), properties)) .assignTimestampsAndWatermarks(new OrderTimestampExtractor()); // 用户数据流 DataStream<User> userStream = env.addSource(new FlinkKafkaConsumer<>("user-topic", new UserDeserializationSchema(), properties)) .assignTimestampsAndWatermarks(new UserTimestampExtractor()); // 注册临时视图 tableEnv.createTemporaryView("orders", orderStream, $("orderId"), $("userId"), $("orderTime").rowtime()); tableEnv.createTemporaryView("users", userStream, $("userId"), $("userName"), $("gender")); // 执行 join 操作 Table resultTable = tableEnv.sqlQuery("SELECT o.orderId, o.orderTime, u.userName FROM orders o " + "JOIN users u ON o.userId = u.userId " + "WHERE o.orderTime BETWEEN u.rowtime - INTERVAL '5' SECOND AND u.rowtime + INTERVAL '5' SECOND"); // 将结果转换为数据流 DataStream<Result> resultStream = tableEnv.toAppendStream(resultTable, Result.class); // 将结果写入到 Kafka 中 resultStream.addSink(new FlinkKafkaProducer<>("result-topic", new ResultSerializationSchema(), properties)); // 打印结果 resultStream.print(); env.execute("Flink SQL Join Demo"); } } ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值