Flink 自定义维表

写这个博客主要是看了袋鼠云的flinkStreamSQL git地址:https://github.com/DTStack/flinkStreamSQL  自己还往上提交了kudu的sink和side 第一次commit到github上面还是很开心的。

这里重点说的是flinkStreamSQL是如何完成side的,主要其实是两种缓存方案LRU和ALL。这里忽略所有的sql解析 注册等等,单纯的从流的角度完成维表join。

ALL相对比较简单先介绍ALL: 
从KuduAllReqRow开始,这里是维表的加载以及如何join。先查看继承关系,只看需要关心的。先看AllReqRow,AllReqRow只需要关心open()方法。这里是同步缓存,缓存完毕后数据才继续往下走。

     @Override
    public void open(Configuration parameters) throws Exception {
        super.open(parameters);
        //初始化全量维表数据
        initCache();
        System.out.println("----- all cacheRef init end-----");

        //start reload cache thread
        SideTableInfo sideTableInfo = sideInfo.getSideTableInfo();
        //创建线程池 开启调度线程 每隔一段时间查询全量数据 覆盖原有数据
        es = Executors.newSingleThreadScheduledExecutor(new DTThreadFactory("cache-all-reload"));
        es.scheduleAtFixedRate(() -> reloadCache(), sideTableInfo.getCacheTimeout(), sideTableInfo.getCacheTimeout(), TimeUnit.MILLISECONDS);
    }

这里其实就是主要的思想了,开启一个调度线程不停的去查询数据然后缓存。这里缓存用的是
AtomicReference<Map<String, List<Map<String, Object>>>> cacheRef = new AtomicReference<>(); 
第一个string: join的条件 List:维表中本条数据的 字段名 字段值 

以此条sql为例
insert into  MyResult
    select m.id,m.title,m.amount,s.tablename1
	from MyTable m  left join sideTable s on m.id=s.id ;

从streamAPI角度就是 MyTable流来了根据m.id的值去Map中查找是否存在对应的List,如果存在则根据字段名取出对应的值拼接到MyTable流中。

LRU: 主要是在SideAsyncOperator类中 主要方法getSideJoinDataStream()
 

    public static DataStream getSideJoinDataStream(DataStream inputStream, String sideType, String sqlRootDir, RowTypeInfo rowTypeInfo,  JoinInfo joinInfo,
                                            List<FieldInfo> outFieldInfoList, SideTableInfo sideTableInfo) throws Exception {
        AsyncReqRow asyncDbReq = loadAsyncReq(sideType, sqlRootDir, rowTypeInfo, joinInfo, outFieldInfoList, sideTableInfo);
        //TODO How much should be set for the degree of parallelism? Timeout? capacity settings?
        return AsyncDataStream.orderedWait(inputStream, asyncDbReq, 10000, TimeUnit.MILLISECONDS, asyncCapacity)
                .setParallelism(sideTableInfo.getParallelism());
    }

依然只看需要关注的类:

可以看到这里是用的异步IO查询,这里的查询是根据on后的条件 ,还是上面的逻辑代码 传入m.id=3  此时就会到数据库中查询s.id=3的数据 缓存到Cache<String, CacheObj> cache中 String是存入的值 如 3,CacheObj= new CacheObj(type, content)  type为枚举字段MissVal(为查询到数据),SingleLine(查询的数据只会有一条(1对1)),MultiLine(查询的数据有多条(1对多)) 。content为Object,如果是MultiLine 则表明content中需要存入多个数据。
缓存时间:
 

 cache = CacheBuilder.newBuilder()
                .maximumSize(sideTableInfo.getCacheSize())
                .expireAfterWrite(sideTableInfo.getCacheTimeout(), TimeUnit.MILLISECONDS)
                .build();

在初始化Cache<String, CacheObj> cache时已经决定了缓存的大小和时间。
从streamAPI角度就是 MyTable流来了根据m.id的值去数据库中查询,如果存在放入SingleLine或MultiLine,不存在则放入MissVal。然后缓存起来,这里调用的是异步IO查询。当有重复的key到来时就直接从缓存中获取数据往下发送。

Flink SQL中进行关联的方法有多种。其中一种常见的方法是使用Redis作为存储介质,以获得较快的响应速度。然而,在写入和查询时,需要使用concat和table function函数进行处理,这种方式比较繁琐。有没有更简单的方法呢?可以通过以下几种方式进行关联: 1. 实时查询:即在每个事件流中动态查询数据。这种方式适用于数据量较小的情况。 2. 预加载全量数据:将数据提前加载到内存中,以便在查询时直接从内存中获取数据。这种方式适用于数据量较大但不会频繁变动的情况。 3. LRU缓存:使用Least Recently Used (LRU)算法,将最近使用的数据缓存到内存中,以提高查询速度。这种方式适用于数据量较大且经常变动的情况。 4. 广播:将数据广播到所有的任务节点,以避免网络通信开销。这种方式适用于数据较小且较为常用的情况。 5. 自定义线程池访问:通过自定义线程池来并发地查询数据,以提高查询效率。这种方式适用于数据量较大且需要频繁查询的情况。 6. 自己扩展Flink SQL中关联的方式:根据具体需求,可以自己扩展Flink SQL中关联的方式,以满足特定的业务需求。 综上所述,根据实际情况和需求,可以选择上述的一种或多种方式来进行Flink SQL中的关联操作。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [Flink SQL多字段的关联查询-flink-connector-redis](https://blog.youkuaiyun.com/zilong00007/article/details/127111163)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [轻松通关Flink第19讲:Flink 如何做关联](https://blog.youkuaiyun.com/sucaiwa/article/details/129808043)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值