Flink SQL系列 关于Stream中的Dynamic Tables

我们以前使用的关系型数据库,比如mysql这种,都是统一个静态表,供我们查询,不管我们有多少数据,最好低于百万级别,都可以对某个表的所有数据进行统一操作,但是这仅仅就是一个静态表而已,也就是说,你的一次操作就会让数据编程另一种状态,比如你在中午表的状态是A状态,到了晚上你修改了一条数据,那么现在就变成了B状态了。我们在某个时间点去看,因为有这么大的时间跨度,就是一种静态表,而且它里面的数据涵盖的时间范围也可能非常广的。
假如,我们现在有两种表,一种是下单的表orderTable,另一种是付款表也就是payTable,那么的话如果要计算在下单后10分钟内付款的总数的话,就需要直接将两个表join了,然后根据时间差来筛选对吧
但是呢,如果是对于美团,饿了吗等等,每时每刻都有人在下单,不可能每时每刻都要针对整个表的数据进行计算。而在Flink SQL的流处理中定义了一种Dynamic Table,数据流不断进来的一种流表,其实静态表也可以看成一种流表,只是我们自己对他的操作时间跨度大而已。

Dynamic Table

在这里插入图片描述
这是Stream和Dynamic Table之间的转换关系
如果最先进来了一些订单流,进而被我们转成了一个Dynamic Table,这个Dynamic Table其实也可以看成一个快照静态Table,这个快照应该很容易理解,就是某一瞬间某个时间点的这个Table所拥有的数据。
而对于这个Dynamic Table,可以在上面做一个Continious Query,即翻译过来连续查询,因为和传统静态的不同,在需要的时候去查,对于这种流数据,需要不断的去Query,即连续查询。在经过连续查询后又会生成一个Dynamic Table,然后这个Table又可以转成一些Stream了
下面,就针对这个图来一步一步解析

在流上去定义Dynamic Table

 EnvironmentSettings fsSettings = EnvironmentSettings.newInstance().useOldPlanner().inStreamingMode().build();
        StreamExecutionEnvironment fsenv = StreamExecutionEnvironment.getExecutionEnvironment();
        StreamTableEnvironment fsTabEnv = StreamTableEnvironment.create(fsenv,fsSettings);
        fsenv.setParallelism(1);

        /****************************/
        /***  开始创建一个表吧  ***/
        /***  应该也可以使用connect等等  ***/
        /****************************/
        DataStreamSource<order> orderDataStreamSource = fsenv.addSource(new orderSource());
        DataStreamSource<payment> paymentDataStreamSource = fsenv.addSource(new paysource());

        Table orderTable = fsTabEnv.fromDataStream(orderDataStreamSource).as("orderid,productname,timestampo");
        Table payTable = fsTabEnv.fromDataStream(paymentDataStreamSource).as("payid,paytype,timestampp");


这个很容易理解,它是一种以流的形式不断输入到Dynamic Table里面去的,所以是一种insert方式
比如一个点击流和一个点击Dynamic Table
在这里插入图片描述

Dynamic Table --Continious Query–>Dynamic Table

Table selectResult = orderTable.select("*");

如果一个点击表的话,就会是这个样子了,在左边,中间经过一个连续查询,看到没有,相应的每个查询会在右边对应一个表
在这里插入图片描述
当然,我们有时候的场景不需要那样重新计算所有的数据,可想而知,Stream中的窗口是最常用的对吧。每次查询都会针对某个时间段去查询,这样每次更新的结果表也是对应一个时间段的
在这里插入图片描述

样例

ClickSource生产实时流


public class ClickSource implements SourceFunction<click> {
    public boolean isRunning = true;
    @Override
    public void run(SourceContext<click> ctx) throws Exception {
        String[] users = {"Mary","Jack","Rose","Peter","Xiong","Zhou","Wang","Li","Tang","Xiao","Yang","He"};
        String[] urls = {"url1","url2","url3","url4","url5","url6","url7","url8"};
        Random rand = new Random();
        while(isRunning){
            click c = new click();
            c.setCtime(System.currentTimeMillis()+"");
            c.setUrl(urls[rand.nextInt(urls.length)]);
            c.setUser(users[rand.nextInt(users.length)]);
            ctx.collectWithTimestamp(c,Long.valueOf(c.getCtime()));
            ctx.emitWatermark(new Watermark(Long.valueOf(c.getCtime())));
            Thread.sleep(300);
        }
    }

    @Override
    public void cancel() {
        isRunning = false;
    }
}

然后在flink环境中去处理

        EnvironmentSettings environmentSettings = EnvironmentSettings.newInstance().useOldPlanner().inStreamingMode().build();
        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
        StreamTableEnvironment fsTableEnv = StreamTableEnvironment.create(env,environmentSettings);
        env.setParallelism(1);

        DataStreamSource<click> clickStream = env.addSource(new ClickSource());

        Table clickTable = fsTableEnv.fromDataStream(clickStream);
        Table selectResult = clickTable.groupBy("user").select("user,count(url) as cnt");

        fsTableEnv.toRetractStream(selectResult, Row.class).print();
//        fsTableEnv.toAppendStream(selectResult,Row.class).print();
        
        try {
            env.execute("new flink");
        } catch (Exception e) {
            e.printStackTrace();
        }

注意,这里不能将Table转换成Append流了,因为他不是那种需要insert结果表的,这个带有group和count的必须保证每个user在一张表中只有唯一值,不能说来一个user就插入到里面,那样就没了group和count的效果。所以他转换成的是一种delete+insert流
下面这个是运行效果,有true和false,true代表insert一个值,false代表删除一个值。比如前面三个true都分别加入了Zhou,Li,Mary的url个数,然后第四个流是false,代表的意思是将Li删除,然后下一条是一个true,Li,且Li的url个数变成了2了。可见,他用的这种insert+delete的方式达到更新效果
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小满锅lock

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值