版权声明:本文为博主原创文章,未经博主同意不得转载。 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. Codeforces 989D A Shade of Moonlight

    A Shade of Moonlight 列列式子发现, 对于同一个云来说只有反向的云才能和它相交, 然后我们发现这个东西有单调性,然后二分就好啦. #include<bits/stdc++.h ...

  2. /bin/sh ./xxxxx.sh出现:“Syntax error: “(” unexpected”

    Ubuntu/Debian为了加快开机速度,用dash代替了bash. dpkg-reconfigure dash 选择 No,取消dash即可,要重新开启dpkg-reconfigure dash选 ...

  3. 五种UML工具

    ProcessOn是一款在线流程图软件(https://www.processon.com/),能够高效的完成在线流程图.UI原型图.UML以及组织图,网络拓扑图的构建.该软件最大的特点是,无需安装, ...

  4. react 环境搭建

    1:需要给系统装一个node  https://nodejs.org/zh-cn/ 2:然后需要到cmd安装一个淘宝镜像 (在cmd上面执行): npm install -g cnpm --regis ...

  5. Addition Chains POJ - 2248 (bfs / dfs / 迭代加深)

    An addition chain for n is an integer sequence <a0, a1,a2,...,am=""> with the follow ...

  6. HDU-1247 Hat’s Words (暴力)【Trie树】

    <题目链接> 题目大意: 给你一些单词,要求输出将该单词完全分成前.后两个单词之后,若这两个单词都在单词库中出现,则输出该单词. 解题分析: 将每个单词的每一位能够拆分的位置全部暴力枚举一 ...

  7. PAT (Advanced Level) Practise 1004 解题报告

    GitHub markdownPDF 问题描述 解题思路 代码 提交记录 问题描述 Counting Leaves (30) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 1600 ...

  8. Android 一个Activity 里面放置多个 Fragment 实现点击切换的Tab 页面效果

    // BaseActivity 是实现的一些公共的变量和方法,可以暂时为空的类 public class HomeActivity extends BaseActivity implements Vi ...

  9. padding和margin设置成百分比

    Margin和Padding是我们在网页设计经常使用到的CSS样式,他们分别是间距和填充,一个作用于盒子外面,一个作用于盒子里面,默认的情况下,这些属性的值都会被计算在盒子的面积里面,在网页开发中的流 ...

  10. [python]UnicodeEncodeError: 'gbk' codec can't encode character '\ufffd'

    有关编码问题,一直以来都是十分头疼的问题.代码中的字符编码其实还好,但是由于使用的window系统,会用Window的默认编码去解析文本. 今天用脚本在写文件的时候,就总是弹出UnicodeEncod ...