Apache Flink 误用之痛

整理:lyee(Flink 社区志愿者)
git


摘要: 本文根据 Flink Forward 全球在线会议 · 中文精华版整理而成, 围绕着项目的 开始、需求分析、开发, 以及测试、上线、运维整个生命周期展开,介绍了 Apache Flink 实践中的一些典型误用状况,并给出了相应的更优实践方案。

Flink 实践中最首当其冲的误用就是不按迭代开发的过程操做。最佳实践应该遵循迭代开发的步骤进行,包含如下几个阶段:

  1. 项目开始
  2. 涉及分析
  3. 开发
  4. 测试
  5. 上线
  6. 维护

Tips: 点击「 阅读原文 」可查看更多 Flink 社区最新动态~


1. 项目开始github


在开始开发前,咱们须要选择正确的切入方式,如下几种每每是最糟糕的开始:

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

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

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

  • 邮件列表:apache

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

  • Stack Overflow:windows

    www.stackoverflow.com后端


2. 设计分析安全


方案设计中的一些常见错误思惟,每每是因为没有充分思考需求致使的,好比:

    a) 不考虑数据一致性和交付保证    b) 不考虑业务升级和应用改进  c) 不考虑业务规模问题  d) 不深刻思考实际业务需求
   

咱们要认真分析需求,同时认真考虑实际交付状况。提到一致性和交付保障,其实能够经过几个问题来引导你们完成这件事,以下图所示:


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

果不在意,你能够没有 Checkpoint。

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

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

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

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

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

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

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

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


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

另外新做业中还有新建的节点,这个节点就用空状态去初始化便可。除此以外,还须要注意,为了保证做业成功启动而且状态恢复不受影响,咱们应该为算子设置 StreamAPI 中的 uid 。固然,若是状态的结构发生了变化,Avro Types 和 POJO 的类型都是支持的,Kryo 是不支持的。最后建议全部 key 的类型尽可能不要修改,由于这会涉及 shuffle 和 状态的正确性。

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


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


在这个例子中选择哪一种时间窗口、什么时候触发计算,仅凭一句话的需求是没法描述清楚的。只有根据流处理的特性结合实际的业务去认真分析需求,才能将 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中是一种效率较低的处理过程,咱们应该先进行过滤和投影操做,防止不须要的数据进行多余的处理。




3.4 并发性


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

  • 任务之间共享静态变量


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

  • 在用户函数中生成线程


检查点变得复杂易错。

对于想用线程的状况,若是是须要加速做业,能够调整并行度和资源,使用异步IO;若是是须要一些定时任务的触发,可使用 Flink 自带的 Timer 定时调度任务。


3.5 窗口


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


另外,也要避免图7中的这种滑动窗口,在图7中每一个记录被50万个窗口计算,不管是计算资源仍是业务延迟都会很是糟糕。


3.6 可查询状态

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

3.7 DataStream API 的应用

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


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


4. 测试


除了系统测试和 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。


做者简介:

本文由  Konstantin Knauf 分享 孙金城进行中文解说。

孙金城(金竹,Apache Member, 阿里巴巴高级技术专家。 2011 年加入阿里,9 年的阿里工做中,主导过不少内部核心系统,如,阿里集团行为日志,阿里郎,云转码,文档转换等。 在 2016 年初开始了解 Apache Flink 社区,由初期的参与社区开发到后来逐渐主导具体模块的开发,到负责 Apache Flink Python API(PyFlink) 的建设。   目前是 PMC member of Apache Flink and ALC(Beijing), 以及 Committer for Apache Flink, Apache Beam and Apache IoTDB。


# 如何提早了解 Flink 1.11 新版功能特性?#

   机会来了 !

6月14日,阿里巴巴计算平台事业部与阿里云开发者社区共同举办的 大数据+AI Meetup 系列第一季即将重磅开启 ,这次 Meetup 邀请了来自阿里巴巴、Databricks、快手、网易云音乐的7位技术专家,集中解读大数据当前热门话题!

其中,Apache Flink Committer,阿里巴巴技术专家李劲松(之信)将现场分享Flink 1.11 Table&SQL 深度解读,还有快手春晚项目的独家实践、网易云音乐 Flink + Kafka 的生产落地等。点击「 阅读原文 」便可预定报名~

▼ 活动亮点 


> 超豪华嘉宾阵容!多位资深技术专家在线分享对行业趋势的洞察!

> 极丰富干货分享!集结大数据热门议题,次看完:数据处理、数仓、数据湖、AI 等技术实践与生产应用落地。

> 多种奖品拿到手软!直播间已准备超多精美礼品,现场送送送!预定直播并参与互动即有机会领走哦。




点击「 阅读原文 」便可预定报名!

本文分享自微信公众号 - Flink 中文社区(gh_5efd76d10a8d)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。

相关文章
相关标签/搜索