flink sql demo

转载自:Flink 1.11 SQL 快速上手,内含Demo及详细分析和使用过程,亲测可行!_search-lemon的博客-CSDN博客文章目录1. 需引入的pom依赖2. Flink SQL批处理Demo3. Flink SQL流处理Demo4. Old Planner与Blink Planner4.1 Old Planner的使用4.2 Blink Planner的优势与局限Flink各个版本之间的API有比较大的gap,笔者将程序从Flink 1.7升级到Flink 1.11时,中间遇到了很多小问题。这里,给出一个使用Flink 1.11版本SQL API使用demo,并对需要注意的点和编写过程进行详细说明。1. 需引入的pom依https://blog.csdn.net/weixin_44056920/article/details/109499601?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_title~default-0.no_search_link&spm=1001.2101.3001.4242.1

文章目录

Flink各个版本之间的API有比较大的gap,笔者将程序从Flink 1.7升级到Flink 1.11时,中间遇到了很多小问题。这里,给出一个使用Flink 1.11版本SQL API使用demo,并对需要注意的点和编写过程进行详细说明。

1. 需引入的pom依赖

<dependency>
    <groupId>org.apache.flink</groupId>
    <artifactId>flink-clients_${scala.version}</artifactId>
    <version>${flink.version}</version>
</dependency>

<!-- Table API and SQL components -->
<dependency>
    <groupId>org.apache.flink</groupId>
    <artifactId>flink-table</artifactId>
    <version>${flink.version}</version>
    <type>pom</type>
</dependency>

上面两个是Flink API和Table&SQL开发基础依赖,没什么好说的,新建项目时引入就对了。

<!-- blink planner -->
<dependency>
    <groupId>org.apache.flink</groupId>
    <artifactId>flink-table-planner-blink_${scala.version}</artifactId>
    <version>${flink.version}</version>
</dependency>

<!-- flink planner -->
<dependency>
    <groupId>org.apache.flink</groupId>
    <artifactId>flink-table-planner_${scala.version}</artifactId>
    <version>${flink.version}</version>
</dependency>

Flink 1.9 到 Flink 1.11 版本中,Flink old Planner和Blink Planner并存,且Flink 1.11将Blink Planner设置为默认Planner。因此开发的时候,需要根据需要引入其一,或两个都引入也可以。

注意:从maven上直接拷贝下来的pom依赖的设置为provided,本地执行flink程序时,会报找不到相应planner。删掉<scope>provided</scope>即可。

Exception in thread “main” org.apache.flink.table.api.NoMatchingTableFactoryException: Could not find a suitable table factory for ‘org.apache.flink.table.delegation.ExecutorFactory’ in
the classpath.

<!-- use the Table API & SQL for defining pipelines -->
<dependency>
    <groupId>org.apache.flink</groupId>
    <artifactId>flink-table-api-java-bridge_${scala.version}</artifactId>
    <version>${flink.version}</version>
</dependency>

使用Flink Table API和SQL API时需要适配不同语言的pipelines,因此需要根据自己实际开发语言引入bridge依赖,这里笔者使用java开发。当使用scala开发时,则引入相应scala-bridge。

<!-- kafka connector -->
<dependency>
    <groupId>org.apache.flink</groupId>
    <artifactId>flink-connector-kafka_${scala.version}</artifactId>
    <version>${flink.version}</version>
</dependency>

<!-- flink-sql-connector-kafka -->
<dependency>
    <groupId>org.apache.flink</groupId>
    <artifactId>flink-sql-connector-kafka_${scala.version}</artifactId>
    <version>${flink.version}</version>
</dependency>

实时开发时使用最多的数据源就是kafka,上面两个依赖分别为Flink API 和Flink SQL 使用kafka的connector。

注意:要注意flink与kafka版本适配,flink 1.11只支持kafka 10和11,否则程序运行时会报错。

<!-- flink-json -->
<dependency>
    <groupId>org.apache.flink</groupId>
    <artifactId>flink-json</artifactId>
    <version>${flink.version}</version>
</dependency>

使用Flink的format格式解析文本时,需要引入相应format依赖。笔者程序中读取的数据为json格式,因此引入flink-json的依赖。

2. Flink SQL批处理Demo

import org.apache.flink.table.api.EnvironmentSettings;
import org.apache.flink.table.api.TableEnvironment;

/**
 * Created by search-lemon on 2020/10/27.
 * 读取本地url_parse_100.txt文件,解析后输出到控制台.
 */
public class BatchSqlTest {

    // use blink planner
    private static TableEnvironment tableEnv;

    public static void main(String[] args) {
        initBlinkEnv();
        registerFileSource();
        print();
    }

    private static void initBlinkEnv() {
        EnvironmentSettings tableEnvSettings = EnvironmentSettings
            .newInstance()
            .useBlinkPlanner() // 设置使用BlinkPlanner
            .inBatchMode() // 设置批处理模式
            .build();

        tableEnv = TableEnvironment.create(tableEnvSettings);
    }

    private static void registerFileSource() {

        String sourceSql = "CREATE TABLE url_parse_100 ("
            + " logtime STRING,"
            + " sign STRING,"
            + " version STRING"
            + " ) WITH ( "
            + " 'connector' = 'filesystem',"
            + " 'path' = 'E:/url_parse_100.txt',"
            + " 'format' = 'json'"
            + ")";

        tableEnv.executeSql(sourceSql); // 注册source表到env中
    }

    /**
     * 注册print table并输出数据.
     */
    private static void print() {

        String printTable = "CREATE TABLE print_table"
            + " WITH ('connector' = 'print')"
            + " LIKE url_parse_100 (EXCLUDING ALL)"; // 注册print表到env中

        tableEnv.executeSql(printTable);

        String printData = "INSERT INTO print_table"
            + " SELECT logtime, sign, version"
            + " FROM url_parse_100";

        tableEnv.executeSql(printData); // 输出数据到控制台

    }

上例很好理解,读取文本格式为json的 E:/url_parse_100.txt 文件,解析出 logtime, sign, version 三个字段,再将其输出到控制台。

3. Flink SQL流处理Demo

import org.apache.flink.table.api.EnvironmentSettings;
import org.apache.flink.table.api.TableEnvironment;

/**
 * Created by search-lemon on 2020/10/27.
 * 读取kafka数据,解析后输出到控制台.
 */
public class StreamSqlTest {

    // use blink planner
    private static TableEnvironment tableEnv;

    public static void main(String[] args) throws Exception {
        initBlinkEnv();
        registerKafkaSource();
        print();
    }

    private static void initBlinkEnv() {
        EnvironmentSettings tableEnvSettings = EnvironmentSettings
            .newInstance()
            .useBlinkPlanner()
            .inStreamingMode()
            .build();

        // stream也可使用StreamTableEnvironment
        tableEnv = TableEnvironment.create(tableEnvSettings);
    }

    /**
     * Flink 1.11只支持kafka 10和11版本.
     */
    private static void registerKafkaSource() {

        String sourceSql = "CREATE TABLE flink_input_test ("
            + " logtime STRING,"
            + " sign STRING,"
            + " version STRING"
            + " ) WITH ( "
            + " 'connector' = 'kafka',"
            + " 'topic' = 'flink_input_test'," // kafak topic
            + " 'properties.bootstrap.servers' = '*******'," // kafak brokers
            + " 'properties.group.id' = 'test_20201102'," // kafka group.id
            + " 'format' = 'json'," // kafka中数据格式
            + " 'scan.startup.mode' = 'latest-offset'" // 设置从最新offset开始消费
            + ")";

        tableEnv.executeSql(sourceSql);
    }

    /**
     * 注册print table并输出数据.
     */
    private static void print() {

        String printTable = "CREATE TABLE print_table"
            + " WITH ('connector' = 'print')"
            + " LIKE flink_input_test (EXCLUDING ALL)"; // 这里使用LIKE直接创建注册print表

        tableEnv.executeSql(printTable);

        String printData = "INSERT INTO print_table"
            + " SELECT logtime, sign, version"
            + " FROM flink_input_test";

        tableEnv.executeSql(printData);

    }

上述Batch和Stream的程序都使用了BlinkPlanner(),可以看出它们的程序非常相似,这是由于Flink 1.11的Blink Planner在Table&SQL API上已经实现了批流合一,都可以使用TableEnvironment对象作为程序运行环境,通过配置EnvironmentSettings控制运行的是实时还是离线程序。这样(除了source源表的注册)实时和离线系统完全可使用同一套代码,减少了大量重复的开发工作。
 

4. Old Planner与Blink Planner

4.1 Old Planner的使用

import org.apache.flink.api.java.ExecutionEnvironment;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.table.api.EnvironmentSettings;
import org.apache.flink.table.api.bridge.java.BatchTableEnvironment;
import org.apache.flink.table.api.bridge.java.StreamTableEnvironment;

/**
 * Created by search-lemon on 2020/10/27.
 * 测试初始化 Old Planner运行环境.
 */
public class InitEnvTest {

    // use flink old planner
    private static StreamTableEnvironment streamTableEnv;
    private static BatchTableEnvironment bTableEnv;

    public static void main(String[] args) {
        initFlinkBatchEnv(); // 初始化batch环境
        initFlinkStreamEnv(); // 初始化stream环境
    }

    private static void initFlinkBatchEnv() {
        ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
        bTableEnv = BatchTableEnvironment.create(env);
    }

    private static void initFlinkStreamEnv() {
        EnvironmentSettings settings = EnvironmentSettings
            .newInstance()
            .useOldPlanner()
            .inStreamingMode()
            .build();

        StreamExecutionEnvironment streamEnv = StreamExecutionEnvironment.getExecutionEnvironment();
        streamTableEnv = StreamTableEnvironment.create(streamEnv, settings);
    }

可以看出,Flink Old Planner中批和流处理环境是分离的,需要分别使用StreamTableEnvironment和BatchTableEnvironment来运行实时和离线程序。

不同的Environment和Planner是配套使用的。当然,如果使用Blink Planner来处理流数据也可以使用StreamExecutionEnvironment。反之,Flink Old Planner没法儿使用批流合一的TableEnvironment。


4.2 Blink Planner的优势与局限

从Flink最近几个版本的发展来看,Blink Planner逐渐成为主流。Flink Old Planner是将Flink 1.9版本之前的核心执行计划优化和转化部分提取出来形成一个模块,与新开发的Blink Planner并列,提供两个Planner供用户自行选择。

Old Planner中,Table&SQL API是对底层API(DataStream和DataSet)的封装,批和流的处理完全是两套逻辑代码。而Blink Planner中很多SQL逻辑执行计划可直接转换为物理执行计划执行。架构上,Blink Planner Table&SQL API与DataStream API平行,不再是其简单的封装,舍弃了DataSet API,批和流处理使用同一套转换执行逻辑代码,实现了批流合一。但是局限也是很明显的,TableEnvironment不支持Table&SQL API和DataStream API之间的相互转换,是一个纯SQL的处理过程。这样从低版本直接升级上来的程序如果想要使用新特性就需要做较多适配工作。
 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值