Apache Flink 误用的是示例分析

Apache Flink 误用的是示例分析,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。

摘要: 下面根据 Flink Forward 全球在线会议 · 中文精华版整理而成, 围绕着项目的 开始、需求分析、开发, 以及测试、上线、运维整个生命周期展开,介绍了 Apache Flink 实践中的一些典型误用情况,并给出了相应的更优实践方案。                    
                 
Flink 实践中最首当其冲的误用就是不按迭代开发的过程操作。  

1. 项目开始


在开始开发前,我们需要选择正确的切入方式,以下几种往往是最糟糕的开始:

    a) 从一个具有挑战性的用例开始(端对端的 Exactly-once、大状态、复杂的业务逻辑、强实时SLA的组合)       
    b) 之前没有流处理经验       
    c) 不对团队做相关的培训       
    d) 不利用社区

在开发的过程中,其实要认认真真的来规划我们的切入点,首先,要从简单的任务开始循序渐进。要有一定的大数据和流处理的知识积累,尽量参加一些培训,也要利用好社区资源。基于这样的想法,我们就能很快找到切入点。

怎么样去做?社区提供了很多的培训,包括 Flink Forward 和 Vererica 网站上有各种培训课程,大家可以去看。同时,可以充分利用社区。社区还建立了中文的邮件列表,大家可以充分利用中文邮件列表来解决手头的疑难杂症。另外,Stack Overflow 也是个提问的好地方,但在提问前尽量去看一看已有的提问,做到心中有数。

  • 邮件列表:

    user@flink.apache.com/user-zh@flink.apache.org 

  • Stack Overflow:

    www.stackoverflow.com


2. 设计分析


方案设计中的一些常见错误思维,往往是由于没有充分思考需求导致的,比如:

    a) 不考虑数据一致性和交付保证       
    b) 不考虑业务升级和应用改进       
    c) 不考虑业务规模问题       
    d) 不深入思考实际业务需求
我们要认真分析需求,同时认真考虑实际交付情况。提到一致性和交付保障,其实可以通过几个问题来引导大家完成这件事,如下图所示:

Apache Flink 误用的是示例分析


第1个问题,是否在乎数据的丢失?

 如  果不在乎,你可以没有 Checkpoint。

 第2个问题,是否在乎结果的正确性?

 在很多的场景里面,我们非常关注结果的正确性,比如金融领域,但是另外一些场景比如监控或其他简单的使用场景仅需要一个概要的数据统计。如果不在乎结果的正确性,  可以考虑用 at-least-once 的模式配置并使用可回放的数据源。相反,如果  结果的准确性十分重要,且下游不关心重复记录,那么仅需设置 exactly-once 模式并使用可回放的数据源。  如果下游要求数据不能重复,哪怕数据正确也只能发送一次,这种时候就对 sink 有更进一步的限制,在 exactly-once 的模式下,使用可回放的数据源,并且 sink 需要支持事务。

带着这样的思维方式分析业务,才能非常清晰地知道,怎么去使用 Flink,进而避免一些糟糕的事情发生。

完成分析之后,最终目的是什么?  我们为什么要有这种选择,而不是一上来就选一个最好的方案?

 因为世界上永远没有“最好”,这里的核心因素就是延迟,要根据业务的延迟和准确性需求来均衡去做选择。

当需求都分析好之后,还需要去思考应用是否需要升级。从一个正常的 Flink 作业来讲,我们有几个问题要考虑。第一个,Flink 作业一般都有状态读取,做升级时需要有 savepoint 机制来保障,将状态存储保留在远端,再恢复到新的作业上去。很多场景下都会有升级的需求,这简单列了几点:

a 升级集群版本   
b 业务 bug 的修复
c 业务逻辑(拓扑)的变更

在比较复杂的场景下,作业会有拓扑的变化,如下图:

Apache Flink 误用的是示例分析


此处需要添加一个算子,去掉一个 sink 。对于这样的变化,我们要考虑状态的恢复。当 Flink 发现新作业有节点没了,对应的状态无法恢复,就会抛出异常导致升级失败。这时候可以使用参数 --allowNonRestoreState 来忽略此类问题。

另外新作业中还有新建的节点,这个节点就用空状态去初始化即可。除此之外,还需要注意,为了保证作业成功启动并且状态恢复不受影响,我们应该为算子设置 StreamAPI 中的 uid 。当然,如果状态的结构发生了变化,Avro Types 和 POJO 的类型都是支持的,Kryo 是不支持的。最后建议所有 key 的类型尽量不要修改,因为这会涉及 shuffle 和 状态的正确性。

资源的使用情况也是必须要考虑的因素之一,下面是一个评估内存和网络 IO 使用的思路。这里我们假设使用的是 Fs State,所有运行时状态都在内存中。不恰当的资源配置可能会造成 OOM 等严重的问题。

Apache Flink 误用的是示例分析


完成资源评估后,还需要考虑事件时间和乱序问题。下面是一个具体的例子:

Apache Flink 误用的是示例分析


在这个例子中选择哪种时间窗口、何时触发计算,仅凭一句话的需求是无法描述清楚的。只有根据流处理的特性结合实际的业务去认真分析需求,才能将 Flink 技术进行恰当的运用。

还需要注意,Flink 是流批统一的计算引擎,不是所有的业务都能用流处理或者都能用批处理来实现,需要分析自己的场景适合用哪种方式来实现。  

3. 开发



3.1 API 的选择  

在 DataStream API 和 Table API/SQL 的选择上,如果有强烈的需求控制状态和每条状态到来的行为,要使用 DataStream API;如果是简单的数据提取和关系代数的运算,可以选择 Table API/SQL。在一些场景下,只能选择 DataStream API:

a) 在升级过程中要改变状态
b) 不能丢失迟到的数据
c) 在运行时更改程序的行为
     

3.2 数据类型


在开发过程中,关于数据类型,有两种误用场景:


a) 使用深度嵌套的复杂数据类型b) KeySelector 中使用任意类型

正确的做法是选择尽可能简单的状态类型,在 KeySelector 中不使用 Flink 不能自动识别的类型。


3.3 序列化


数据类型越简单越好,基于序列化成本的考虑,尽量使用 POJO 和 Avro SpecificRecords。也鼓励大家开发完使用 IDE 的工具本地调试一下,看一下性能瓶颈在哪。

序列化器    
Opts/s    
PojoSeriallizer    
813    
Kryo    
294    
Avro(Reflect API)    
114    
Avro(SpecificRecord API)    
632    

图5中是一种效率较低的处理过程,我们应该先进行过滤和投影操作,防止不需要的数据进行多余的处理。

Apache Flink 误用的是示例分析




3.4 并发性


两种误用场景及相应容易造成的问题:

  • 任务之间共享静态变量


容易引起 bug;容易造成死锁和竞争问题;带来额外的同步开销。

  • 在用户函数中生成线程


检查点变得复杂易错。

对于想用线程的情况,如果是需要加速作业,可以调整并行度和资源,使用异步IO;如果是需要一些定时任务的触发,可以使用 Flink 自带的 Timer 定时调度任务。


3.5 窗口


尽量避免像图6这样自定义 Window,使用 KeyedProcessFunction 可以使得实现更加简单和稳定。

Apache Flink 误用的是示例分析


另外,也要避免图7中的这种滑动窗口,在图7中每个记录被50万个窗口计算,无论是计算资源还是业务延迟都会非常糟糕。

Apache Flink 误用的是示例分析


3.6 可查询状态  

Queryable State 目前还在不断的完善中,可以用于监控和查询,但在实际投产时还是有一些问题需要注意的,比如对于线程安全访问,RocksDB 状态后端是支持的,而 FS 状态后端是不支持的,另外还有性能和一致性保障等问题需要注意。

3.7 DataStream API 的应用  

对图8这种场景,可以使用 DataStreamUtils#reinterpretAsKeyedStream 这个方法,避免面对相同的 key 进行多次 shuffle 。

Apache Flink 误用的是示例分析


对图9这种场景,应该把一些初始化的逻辑写在 RichFunction 的 open 方法里。

Apache Flink 误用的是示例分析

4. 测试

Apache Flink 误用的是示例分析


除了系统测试和 UDF 的单元测试,还应该做 Mini Cluster 测试,在本机运行一个 Mini Cluster 把端到端的业务跑起来,可以及早地发现一些问题。

还有 Harness 测试,它可以精准地帮助完成有状态的任务测试。它可以精准的控制 watermark、元素的 event time 等。可以参考:

 https://github.com/knaufk/flink-testing-pyramid  。

5. 上线


很多场景会导致业务抖动,一种是实际业务本身就有抖动,其他的比如 Timer、CP 的对齐、GC 等正常现象的发生,还有追数据的场景,开始和追平的时候状态是不一样的,这种情况下也不用担心,有意识地识别这种状况,进而判断这种是正常还是非预期状况。

在线上监控时要注意,metrics 过多会对 JVM 造成很大压力,上报的频率不要选择  subtask,这对资源的开销是很高的。

配置时要注意,一开始尽量不用 RocksDB 状态后端,FS 状态后端的部署成本低速度也更快。少用网络的文件系统。SlotSharingGroups 的配置尽量使用默认的,避免引发欠机制的破坏,导致资源浪费。

6. 维护


像 Flink 这样快节奏的项目,每个版本都有很多 bug 被修复,及时升级也很重要。

7.PyFlink/SQL/TableAPI 的补充


  1. 使用 TableEnvironment 还是 StreamTableEnvironment?推荐 TableEnvironment 。(分段优化)

  2. State TTL 未设置,导致 State 无限增长,或者 State TTL 设置不结合业务需求,导致数据正确性问题。

  • 不支持作业升级,例如增加一个 COUNT SUM 会导致作业 state 不兼容。

  • 解析 JSON 时,重复调度 UDF,严重影响性能,建议替换成 UDTF。

  • 多流 JOIN 的时候,先做小表 JOIN,再做大表 JOIN。目前,Flink 还没有表的 meta 信息,没法在 plan 优化时自动做 join reorder。

关于Apache Flink 误用的是示例分析问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注编程之家行业资讯频道了解更多相关知识。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


可以认为OpenFeign是Feign的增强版,不同的是OpenFeign支持Spring MVC注解。OpenFeign和Feign底层都内置了Ribbon负载均衡组件,在导入OpenFeign依赖后无需专门导入Ribbon依赖,用做客户端负载均衡,去调用注册中心服务。
为进一步规范小程序交易生态、提升用户购物体验、满足用户在有交易的小程序中便捷查看订单信息的诉求,自2022年12月31日起,对于有“选择商品/服务-下单-支付”功能的小程序,需按照平台制定的规范,在小程序内设置订单中心页。开发者可通过小程序代码提审环节,或通过「设置-基础设置-小程序订单中心path设置」模块设置订单中心页path。1、 新注册或有版本迭代需求的小程序,可在提审时通过参数配置该商家小程序的订单中心页path。2、无版本迭代需求的小程序,可在小程序订单中心path设置入口进行设置。
云原生之使用Docker部署Dashdot服务器仪表盘
本文主要描述TensorFlow之回归模型的基本原理
1.漏洞描述Apache Druid 是一个集时间序列数据库、数据仓库和全文检索系统特点于一体的分析性数据平台。Apache Druid对用户指定的HTTP InputSource没有做限制,并且Apache Druid默认管理页面是不需要认证即可访问的,可以通过将文件URL传递给HTTP InputSource来绕过。因此未经授权的远程攻击者可以通过构造恶意参数读取服务器上的任意文件,造成服务器敏感性信息泄露。2.影响版本Apache Druid <= 0.21.13...
内部类(当作类中的一个普通成员变量,只不过此成员变量是class的类型):一个Java文件中可以包含多个class,但是只能有一个public class 如果一个类定义在另一个类的内部,此时可以称之为内部类使用:创建内部类的时候,跟之前的方法不一样,需要在内部类的前面添加外部类来进行修饰 OuterClass.InnerClass innerclass = new OuterClass().new InnerClass();特点:1.内部类可以方便的访问外部类的私有属性...
本文通过解读国密的相关内容与标准,呈现了当下国内技术环境中对于国密功能支持的现状。并从 API 网关 Apache APISIX 的角度,带来有关国密的探索与功能呈现。作者:罗泽轩,Apache APISIX PMC什么是国密顾名思义,国密就是国产化的密码算法。在我们日常开发过程中会接触到各种各样的密码算法,如 RSA、SHA256 等等。为了达到更高的安全等级,许多大公司和国家会制定自己的密码算法。国密就是这样一组由中国国家密码管理局制定的密码算法。在国际形势越发复杂多变的今天,密码算法的国产化
CENTOS环境Apache最新版本httpd-2.4.54编译安装
Apache HTTPD是一款HTTP服务器,它可以通过mod_php来运行PHP网页。影响版本:Apache 2.4.0~2.4.29 存在一个解析漏洞;在解析PHP时,将被按照PHP后缀进行解析,导致绕过一些服务器的安全策略。我们查看一下配置:读取配置文件,前三行的意思是把以 结尾的文件当成 文件执行。问题就在它使用的是 符号匹配的,我们都知道这个符号在正则表达式中的意思是匹配字符串的末尾,是会匹配换行符的,那么漏洞就这样产生了。 进入容器里,打开index.php,发现如果文件后缀名为 php、
apache Hop现在好像用的人很少, 我就自己写一个问题收集的帖子吧, 后面在遇到什么问题都会在该文章上同步更新
2.启动容器ps:注意端口占用,当前部署在 8080 端口上了,确保宿主机端口未被占用,不行就换其他端口ps:用户名和密码都是 admin,一会用于登录,其他随便填5.下载一个官方提供的样例数据库【可跳过】ps:此步国内无法访问,一般下载不了,能下的就下,不能下的跳过就行了,一会配置自己的数据库7.访问登录页面ps:注意端口是上面自己配置的端口,账号密码是 admin依次点击 Settings → Database Connections点击 DATABASE 就可以配置自己的数据库了
String类的常用方法1. String类的两种实例化方式1 . 直接赋值,在堆上分配空间。String str = "hello";2 . 传统方法。通过构造方法实例化String类对象String str1 = new String("Hello");2.采用String类提供的equals方法。public boolean equals(String anotherString):成员方法 str1.equals(anotherString);eg:publi
下载下载地址http://free.safedog.cn下载的setup:安装点击下面的图标开始安装:可能会提示:尝试先打开小皮面板的Apache服务:再安装安全狗:填入服务名:如果服务名乱写的话,会提示“Apache服务名在此机器上查询不到。”我干脆关闭了这个页面,直接继续安装了。安装完成后,需要进行注册一个账户,最后看到这样的界面:查看配置:...
一、问题描述一组生产者进程和一组消费者进程共享一个初始为空、大小n的缓冲区,只有缓冲区没满时,生产者才能把资源放入缓冲区,否则必须等待;只有缓冲区不为空时,消费者才能从中取出资源,否则必须等待。由于缓冲区是临界资源,它只允许一个生产者放入资源,或一个消费者从中取出资源。二、问题分析(1)、关系分析。生产者和消费者对缓冲区互斥访问是互斥关系,同时生产者和消费者又是一个相互协作的关系,只有生产者生产之后,消费者只能才能消费,它们还是同步关系。(2)、整理思路。只有生产生产者和消费者进程,正好是这两个进程
依赖注入的英文名是Dependency Injection,简称DI。事实上这并不是什么新兴的名词,而是软件工程学当中比较古老的概念了。如果要说对于依赖注入最知名的应用,大概就是Java中的Spring框架了。Spring在刚开始其实就是一个用于处理依赖注入的框架,后来才慢慢变成了一个功能更加广泛的综合型框架。我在学生时代学习Spring时产生了和绝大多数开发者一样的疑惑,就是为什么我们要使用依赖注入呢?现在的我或许可以给出更好的答案了,一言以蔽之:解耦。耦合度过高可能会是你的项目中一个比较
<dependency><groupId>org.apache.velocity</groupId><artifactId>velocity-engine-core</artifactId><version>使用人数最多的版本</version></dependency>importorg.apache.velocity.Template;importorg.apache.velo
Java Swing皮肤包前言:一.皮肤包分享二.皮肤包的使用1.先新建一个项目。2.导入皮肤包1.先导入我们刚刚下载的jar文件,右键项目demo即可2.如果右键没有这个选项,记得调为下图模式3.点击下图蓝色圆圈处4.找到刚刚下载的jar文件,点击打开即可5.我们看一下效果,是不是比原生的好看前言:因为Java Swing自身皮肤包不是很好看,甚至有点丑,怎么让你的界面更加好看,这里就需要用到皮肤包,我发现了一个还不错的皮肤包,让你的界面美观了几个等级。废话不多说。一.皮肤包分享百度网盘分享链接:
一、前言在做Java项目开发过程中,涉及到一些数据库服务连接配置、缓存服务器连接配置等,通常情况下我们会将这些不太变动的配置信息存储在以 .properties 结尾的配置文件中。当对应的服务器地址或者账号密码信息有所变动时,我们只需要修改一下配置文件中的信息即可。同时为了让Java程序可以读取 .properties配置文件中的值,Java的JDK中提供了java.util.Properties类可以实现读取配置文件。二、Properties类Properties 类位于 java.util.Pro
Mybatis环境JDK1.8Mysql5.7maven 3.6.1IDEA回顾JDBCMysqlJava基础MavenJunitSSM框架:配置文件的最好的方式:看官网文档Mybatis1、Mybatis简介1.1 什么是Mybatis如何获得Mybatismaven仓库:中文文档:https://mybatis.org/mybatis-3/zh/index.htmlGithub:1.2 持久化数据持久化持久化就是将程序的数据在持久状态和瞬时状态转