Flink Sql教程(7)

Redis异步维表

概述

  • 之前和大家聊过维表,也聊过FLINK中如何使用维表,目前FLINK自带的维表有两种,一种是JDBC维表,一种是HBASE维表。其中JDBC维表支持缓存,HBASE暂不支持
  • 两种维表也都是同步维表,性能较弱
  • 我之前也说过会在后面的教程实现以下异步第三方维表,加上一个叫啤酒鸭的问我相关的问题,就抽空写了一把
  • redis异步客户端我用的是Lettuce,大家也可以用RedissionJedis是同步的,大家千万注意
  • 不过和我之前说的一样,缓存会遇到旧数据的问题,所以也相当于给大家留了一个小作业~~(主要没时间写,写完代码和博客就快下班了)~~ ,通过定时器,定时更新缓存的数据,保证尽可能拿到最新的维表数据
  • 下面的代码在我的github库里面都有,包括以前教程的代码也是一样

TablesFactory

  • 想通过DDL来定义我们的维表的话,就必须得实现StreamTableSourceFactoryStreamTableSinkFactory其中之一或者两者全部实现。一个对应数据源表,一个对应于数据结果表,需要哪个实现哪个吧
  • 之后需要实现4个方法
    • createStreamTableSink 创建流类型tableSink
    • createStreamTableSource创建流类型tableSource
    • requiredContext 只有DDL语句WITH里面的参数&值和该方法传递的参数完全一致,DDL才能映射到这个工厂类
    • supportedProperties 支持的参数&值,用于验证
  • 同时,需要在resource目录下建META-INF/services/org.apache.flink.table.factories.TableFactory路径以及文件,并在文件里面写入你的工厂类全路径。主要是为了通过SPI来发现你的工厂类
  • 下面贴一下代码
    package factory;
    
    import org.apache.flink.api.common.typeinfo.TypeInformation;
    import org.apache.flink.api.java.tuple.Tuple2;
    import org.apache.flink.table.api.TableSchema;
    import org.apache.flink.table.descriptors.DescriptorProperties;
    import org.apache.flink.table.descriptors.JDBCValidator;
    import org.apache.flink.table.descriptors.SchemaValidator;
    import org.apache.flink.table.factories.StreamTableSinkFactory;
    import org.apache.flink.table.factories.StreamTableSourceFactory;
    import org.apache.flink.table.sinks.StreamTableSink;
    import org.apache.flink.table.sources.StreamTableSource;
    import org.apache.flink.table.types.utils.TypeConversions;
    import org.apache.flink.table.utils.TableSchemaUtils;
    import org.apache.flink.types.Row;
    import source.RedisLookupTableSource;
    import util.RedisValidator;
    
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    import static org.apache.flink.table.descriptors.Schema.*;
    import static org.apache.flink.table.descriptors.Schema.SCHEMA_NAME;
    import static util.RedisValidator.*;
    
    public class RedisTableSourceSinkFactory implements
            StreamTableSourceFactory<Row>,
            StreamTableSinkFactory<Tuple2<Boolean, Row>> {
         
        //数据输出使用
        @Override
        public StreamTableSink<Tuple2<Boolean, Row>> createStreamTableSink(Map<String, String> properties) {
         
            throw new IllegalArgumentException("unSupport sink now");
        }
    
        //数据源使用,维表也算,其实感觉维表应该独立开
        @Override
        public StreamTableSource<Row> createStreamTableSource(Map<String, String> properties) {
         
            //校验参数
            DescriptorProperties descriptorProperties = getValidatedProperties(properties);
    
            TableSchema schema = TableSchemaUtils.getPhysicalSchema(descriptorProperties.getTableSchema(SCHEMA));
    
            RedisLookupTableSource.Builder builder = RedisLookupTableSource.builder()
                    .setFieldNames(schema.getFieldNames())
                    .setFieldTypes(schema.getFieldTypes())
                    .setIp(descriptorProperties.getString(CONNECTOR_IP))
                    .setPort(Integer.parseInt(descriptorProperties.getString(CONNECTOR_PORT)));
    		//当缓存相关参数为空时,不会出现异常
            descriptorProperties.getOptionalLong(CONNECTOR_LOOKUP_CACHE_MAX_ROWS).ifPresent(builder::setCacheMaxSize);
            descriptorProperties.getOptionalLong(CONNECTOR_LOOKUP_CACHE_TTL).ifPresent(builder::setCacheExpireMs);
    
            return builder.build();
    
        }
    
        //redis维表 需要参数值是这样的
        @Override
        public Map<String, String> requiredContext() {
         
            Map<String, String> context = new HashMap<>();
            context.put(CONNECTOR_TYPE, CONNECTOR_TYPE_VALUE_REDIS);
            context.put(CONNECTOR_PROPERTY_VERSION, "1"); // backwards compatibility
            return context;
        }
    
        //需要的参数
        @Override
        public List<String> supportedProperties() {
         
            List<String> properties = new ArrayList<>();
    
            properties.add(CONNECTOR_IP);
            properties.add(CONNECTOR_PORT);
            properties.add(CONNECTOR_VERSION);
            properties.add(CONNECTOR_LOOKUP_CACHE_MAX_ROWS);
            properties.add(CONNECTOR_LOOKUP_CACHE_TTL);
    
            // schema
            properties.add(SCHEMA + ".#." + SCHEMA_DATA_TYPE);
            properties.add(SCHEMA + ".#." + SCHEMA_TYPE);
            properties.add(SCHEMA + ".#." + SCHEMA_NAME);
    
            return properties;
        }
    
        private DescriptorProperties getValidatedProperties(Map<String, String> properties) {
         
            final DescriptorProperties descriptorProperties = new DescriptorProperties(true);
    
            descriptorProperties.putProperties(properties);
    
            new SchemaValidator(true, false, false).validate(descriptorProperties);
    
            new RedisValidator().validate(descriptorProperties);
    
            return descriptorProperties;
        }
    }
    
    

TableSource

  • 有了工厂,下面就得有工厂的实现
  • 我们需要实现LookupableTableSourceStreamTableSource这两个类,并且实现这些个方法
    • getLookupFunction 返回真正去redis拿数据的工人类(同步模式)
    • getAsyncLookupFunction 返回真正去redis拿数据的工人类(异步模式)
    • isAsyncEnabled是否是异步模式
    • getTableSchema表结构
    • getDataStream获取数据流,我们这只支持维表使用,所以直接返回空吧
    • getProducedDataType产生的数据类型
    package source;
    
    import lookup.RedisLookupFunction;
    import org.apache.flink.api.common.typeinfo.TypeInformation;
    import org.apache.flink.api.java.typeutils.RowTypeInfo;
    import org.apache.flink.streaming.api.datastream.DataStream;
    import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
    import org.apache.flink.table.api.TableSchema;
    import org.apache.flink.table.functions.AsyncTableFunction;
    import org.apache.flink.table.functions.TableFunction;
    import org.apache.flink.table.sources.LookupableTableSource;
    import org.apache.flink.table.sources.StreamTableSource;
    import org.apache.flink.table.types.DataType;
    import org.apache.flink.table.types.utils.TypeConversions;
    import org.apache.flink.types.Row;
    
    public class RedisLookupTableSource implements
            LookupableTableSource<Row>, StreamTableSource<Row> {
         
    
  • 10
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
### 回答1: Flink 1.14的Table API和SQL教程可以在Flink官方文档中找到,其中包括了Table API和SQL的基础概念、语法、操作符、函数等内容,还有详细的示例代码和实战案例,非常适合初学者学习和入门。另外,Flink社区也有很多优秀的博客和视频教程,可以帮助大家更深入地理解和应用Table API和SQL。 ### 回答2: Flink是一个分布式计算引擎,是Apache Hadoop生态圈中用于处理流式数据的一种解决方案。Flink支持表格API和SQL语言,使得用户可以更加简单地实现流处理任务。而在Flink 1.14中,TableAPI和SQL引擎则得到了进一步的增强。 TableAPI和SQL将无需掌握Java或Scala编程语言就可以操作表格数据。TableAPI API支持Java和Scala,SQL则支持标准的SQL语言。如果你熟悉SQL语言,那么你很容易上手使用TableAPI和SQL引擎。 Flink TableAPI和SQL支持各种类型的表格操作,包括选择、过滤、分组、排序、连接等。此外,它们还支持窗口和聚合操作。这使得用户在处理流式数据时可以更加简单易懂地进行复杂的操作。 在Flink 1.14中,TableAPI和SQL引擎还提供了一系列新功能,包括: 1. 时间特征支持——TableAPI和SQL中的数据时间戳可以通过时间特征进行定义和控制。通过时间特征,用户可以定义数据的时间属性,例如事件时间或处理时间。 2. 详细的窗口管理——当窗口中的数据到期时,Flink 1.14会自动清除过期数据,避免数据量过大导致性能下降。 3. 支持更多的流数据源——在Flink 1.14中,TableAPI和SQL引擎可以直接从Kafka、Kinesis、Hive等数据源中读取数据。这可以让用户更加方便地读取数据,而无需编写额外的代码。 TableAPI和SQL引擎对于Flink用户来说是非常重要的工具,无需掌握Java或Scala编程语言即可操作表格数据。并且在Flink 1.14中,这两个工具得到了进一步的增强,包括更好的窗口管理和更多的数据源支持。因此,学习TableAPI和SQL引擎对于想要使用Flink进行流处理的人来说是非常有益的。 ### 回答3: Flink 1.14 TableAPI和SQL是一个非常好用的数据处理工具,可帮助数据分析师快速进行数据查询、聚合和处理。下面详细介绍一下Flink 1.14的TableAPI和SQL教程。 1. 如何配置Flink 1.14的TableAPI和SQL环境? 在进行Flink 1.14的TableAPI和SQL开发之前,需要先进行环境的配置。可以在官网下载Flink的安装包,解压后找到/bin目录下的start-cluster.sh脚本进行启动。启动之后,即可通过WebUI的页面查看Flink的运行状态。 2. TableAPI的基本操作 TableAPI是Flink的一个高层次数据处理API,可以通过编写代码来进行数据的处理。TableAPI的基本操作有以下几个: (1) 创建Table,可以使用StreamTableEnvironment的fromDataStream或fromTableSource方法,将DataStream或TableSource转换成Table。 (2) Table的转换,可以使用多种转换操作,包括filter、select、orderBy、groupBy、join等。 (3) 将Table转化为DataStream,可以使用StreamTableEnvironment的toDataStream方法。 3. SQL的基本操作 SQLFlink提供的一种快速数据处理方式,用户只需要编写SQL语句即可完成数据处理。SQL的基本操作有以下几个: (1) 注册Table,可以使用StreamTableEnvironment的registerTable或registerTableSource方法,将Table或TableSource注册到环境中。 (2) 执行SQL,可以使用StreamTableEnvironment的executeSql方法,执行SQL语句并返回结果。 (3) 将结果转换为DataStream,可以使用StreamTableEnvironment的toDataStream方法。 4. 如何优化Flink 1.14的TableAPI和SQL的执行效率? 在进行TableAPI和SQL开发时,为了保证其执行效率,需要注意以下几点: (1) 避免使用复杂的JOIN操作,可以使用Broadcast和TableFunction等方式来避免JOIN操作。 (2) 注意Table的Schema定义,Schema的设计合理与否直接影响SQL性能。 (3) 避免使用无限制的聚合操作,可以进行分批次聚合来避免。 总的来说,Flink 1.14的TableAPI和SQL是非常强大的数据处理工具,能够帮助开发者快速高效的进行数据处理。上述内容是入门级别的教程,如果想要更深入的了解,可以参考官方文档进行学习。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值