版权声明:本文为博主原创文章,未经博主同意不得转载。 https://blog.csdn.net/rlnLo2pNEfx9c/article/details/83422587

场景

近期在做一个画像的任务,sql实现的,当中有一个udf,会做非常多事情,包含将从redis读出历史值加权,并将中间结果和加权后的结果更新到redis。

大家都知道,flink 是能够支持事件处理的。也就是能够没有时间的概念,那么在聚合,join等操作的时候,flink内部会维护一个状态,假如此时你也用redis维护了历史状态,也即是相似 result = currentState(flink)+lastState(redis)。且此时要针对计算的结果用where进行筛选.

SQL例如以下


CREATE VIEW view_count AS
select
 `time`,
 gid,
 cid,
 count(feed_id) * 1 as strength
FROM
 view_cid
GROUP BY
 gid,
 cid,`time`;

CREATE VIEW view_strength AS select
 `time`,
 gid,
 cid ,
 Get_Strength_Weaken(gid, cid, cast(strength as double), `time`, 0.95)  as `result`
FROM
 view_count
;

insert into
 hx_app_server_sink_common
SELECT
 gid,
 cid,
 `result`
FROM
 view_strength
where `result` <> '0.0'
GROUP BY
 gid,
 cid,
 `result`;

业务分析

第一个sql视图完毕的是首先分组,然后统计某一个字段并乘以权重;

第二个sql视图。udf :Get_Strength_Weaken完毕当前值和历史值叠加工作,历史值存储在redis。同一时候将结果返回并更新redis,返回值作为result字段。

第三个sql在输出的时候,result字段作为了where的条件和group by里的字段。

这时候生成的flink概图例如以下:

观察中间的结构图能够发现。Get_Strength_Weaken被调用两次:

1. where条件。这个的生成是因为第三条sql


where `result` <> '0.0'

产生的运行计划,是不是看起来非常懵逼。。

2. select里面另一次调用Get_Strength_Weaken。这个非常明显。

当然。能够打印一下flink udf里eval函数的调用细节日志,非常easy发现反复调用的问题。浪院长这个也是通过分析日志。对照输出结果来得出的论。

综合上面分析和udf调用日志,结论就是udf被调用了两次。

对于这个flink的udf被多次调用引起的结果偏大。整整调试了一下午。

因为上面分析能够得出结论,flink将where条件下推了,where 条件推断会先运行,而select里后运行,那么能够调整SQL。例如以下:


CREATE VIEW view_count AS
select
`time`,
gid,
cid,
count(feed_id) * 1 as strength
FROM
view_cid
GROUP BY
gid,
cid,`time`;

CREATE VIEW view_strength AS select
`time`,
gid,
cid ,
getResult(gid,cid) as `result`
FROM
view_count
where Get_Strength_Weaken(gid, cid, cast(strength as double), `time`, 0.95)  as `result` <> '0.0'
;

insert into
hx_app_server_sink_common
SELECT
gid,
cid,
`result`
FROM
view_strength
GROUP BY
gid,
cid,
`result`;

那么实际上。select里的udf主要目的是取出来计算结果。那么这个时候能够写个简单的udf--getResult,仅仅让他从redis获取 where条件里更新到redis里的结果,因为该udf是无状态的即使多次调用。也无所谓。

所以。总结一下,对于flink 来说,因为基于事件的处理,聚合、join等操作会有状态缓存,那么此时再用到含有外部存储状态的udf,一定要谨慎,结合运行计划,来合理放置udf的位置,避免出错。

当然。调试阶段最好是有具体的日志。便于分析和定位问题。

flink 状态删除

事实上。flink聚合等内部状态有配置能够使其自己主动删除的,具体配置使用例如以下:

StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
StreamTableEnvironment tableEnv = TableEnvironment.getTableEnvironment(env); // obtain query configuration from TableEnvironment
StreamQueryConfig qConfig = tableEnv.queryConfig();
// set query parameters
qConfig.withIdleStateRetentionTime(Time.hours(12)); // define query
Table result = ... // create TableSink
TableSink<Row> sink = ... // emit result Table via a TableSink
result.writeToSink(sink, qConfig); // convert result Table into a DataStream<Row>
DataStream<Row> stream = tableEnv.toAppendStream(result, Row.class, qConfig);

[完]

推荐阅读:

推荐两个不错的flink项目

__biz=MzA3MDY0NTMxOQ==&mid=2247485504&idx=1&sn=e19460f43aa2fe388140a2241e9ea219&chksm=9f38eb68a84f627ee0b6dac115f0684dddba573be04ae7e4e54d17c084cf1946282f81b1fd43&scene=21#wechat_redirect" rel="nofollow" style="font-size:16px;text-decoration:underline;">Spark SQL从入门到精通

重要 : 优化flink的四种方式

flink超越Spark的Checkpoint机制

flink 有状态udf 引起血案一的更多相关文章

  1. Flink的状态与容错

    本文主要运行到Flink以下内容 检查点机制(CheckPoint) 状态管理器(StateBackend) 状态周期(StateTtlConfig) 关系 首先要将state和checkpoint概 ...

  2. Flink Streaming状态处理(Working with State)

    参考来源: https://www.jianshu.com/p/6ed0ef5e2b74 https://blog.csdn.net/Fenggms/article/details/102855159 ...

  3. Flink之状态之savepoint

    1.总览 savepoints是外部存储的自包含的checkpoints,可以用来stop and resume,或者程序升级.savepoints利用checkpointing机制来创建流式作业的状 ...

  4. Flink之状态之checkpointing

    1.前言 在Flink中,函数和操作符都可以是有状态的.在处理每个消息或者元素时,有状态的函数都会储存信息,使得状态成为精密操作中关键的组成部分. 为了使状态能够容错,Flink会checkpoint ...

  5. Flink之状态之状态存储 state backends

    流计算中可能有各种方式来保存状态: 窗口操作 使用 了KV操作的函数 继承了CheckpointedFunction的函数 当开始做checkpointing的时候,状态会被持久化到checkpoin ...

  6. Flink之状态之状态获取

    1.什么是状态 对于任何一个操作,都可以被看成是一个函数,比如y=f(x),如果对于同一个x的任何一次输入,得到的y都是相同的,则可以认为这个函数是无状态,否则,这个函数就是有状态的.Flink的一大 ...

  7. flink checkpoint状态储存三种方式选择

    Flink 提供了三种可用的状态后端:MemoryStateBackend,FsStateBackend,和RocksDBStateBackend. MemoryStateBackend Memory ...

  8. 「Flink」Flink的状态管理与容错

    在Flink中的每个函数和运算符都是有状态的.在处理过程中可以用状态来存储数据,这样可以利用状态来构建复杂操作.为了让状态容错,Flink需要设置checkpoint状态.Flink程序是通过chec ...

  9. 9、flink的状态与容错

    1.理解State(状态) 1.1.State 对象的状态 Flink中的状态:一般指一个具体的task/operator某时刻在内存中的状态(例如某属性的值) 注意:State和Checkpoint ...

随机推荐

  1. Rsync + Sersync 实现数据增量同步

    部分引用自:https://blog.csdn.net/tmchongye/article/details/68956808 一.什么是Rsync? Rsync(Remote Synchronize) ...

  2. BZOJ4003 [JLOI2015]城池攻占 左偏树 可并堆

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ4003 题意概括 题意有点复杂,直接放原题了. 小铭铭最近获得了一副新的桌游,游戏中需要用 m 个骑 ...

  3. 最终一致性2PC复杂场景,事务报数据库操作超时。

    稀里糊涂的,忘了开启SqlServer的is read committed snapshot on

  4. P1057 传球游戏 dp

    题目描述 上体育课的时候,小蛮的老师经常带着同学们一起做游戏.这次,老师带着同学们一起做传球游戏. 游戏规则是这样的:nn个同学站成一个圆圈,其中的一个同学手里拿着一个球,当老师吹哨子时开始传球,每个 ...

  5. 关系网络数据可视化:3. 案例:公司职员关系图表 & 导演演员关系网络可视化

    1. 公司职员关系图表 节点和边界数据 节点是指每个节点本身的数据,代表公司职工的名称:属性(Country).分类(Category)和地区(Region,给每个节点定义的属性数据).文件必须是.c ...

  6. SEED-DVS6467_SDK的交叉编译环境搭建问题

    今天在ubuntu16.04上安装arm的交叉编译器arm_v5t_le-gcc,环境变量配置好以后,运行arm_v5t_le-gcc命令,总提示No such file or directory.然 ...

  7. hive_连续天次计算

    drop table sospdm.tmp_yinfei_yuanzuan_redbag; create table sospdm.tmp_yinfei_yuanzuan_redbag stored ...

  8. UVA 315 Network (模板题)(无向图求割点)

    <题目链接> 题目大意: 给出一个无向图,求出其中的割点数量. 解题分析: 无向图求割点模板题. 一个顶点u是割点,当且仅当满足 (1) u为树根,且u有多于一个子树. (2) u不为树根 ...

  9. Codeforces 300C Beautiful Numbers 【组合数】+【逆元】

    <题目链接> 题目大意: 给出a和b,如果一个数每一位都是a或b,那么我们称这个数为good,在good的基础上,如果这个数的每一位之和也是good,那么这个数是excellent.求长度 ...

  10. ReentrantLock和condition源码浅析(一)

    转载请注明出处..... 一.介绍 大家都知道,在java中如果要对一段代码做线程安全操作,都用到了锁,当然锁的实现很多,用的比较多的是sysnchronize和reentrantLock,前者是ja ...