共计 6579 个字符,预计需要花费 17 分钟才能阅读完成。
摘要:本文整顿自快手实时计算团队技术专家刘建刚在 Flink Forward Asia 2021 生产实践专场的演讲。次要内容包含:
- 快手 Flink 的历史及现状
- Flink 容错能力晋升
- Flink 引擎管制与实际
- 快手批处理实际
- 将来布局
点击查看直播回放 & 演讲 PDF
一、快手 Flink 的历史与现状
快手从 2018 年开始对 Flink 进行深度整合,通过 4 年倒退,实时计算平台逐步欠缺并赋能周边各种组件。
- 2018 年咱们针对 Flink 1.4 进行了平台化建设并大幅晋升运维治理能力,达到了生产可用。
- 2019 年咱们开始基于 1.6 版本进行迭代开发,很多业务都开始实时化,比方优化 interval join 为商业化等平台带来显著收益、开发实时多维分析减速超大多维报表的实时化,这一年咱们的 Flink SQL 平台也投入使用。
- 到了 2020 年,咱们降级到 1.10,对 sql 的性能进行了十分多的欠缺,同时进一步优化 Flink 的外围引擎,保障了 Flink 的易用性、稳定性、可维护性。
- 2021 年咱们开始发力离线计算,反对湖仓一体的建设,进一步欠缺 Flink 生态。
上图是快手基于 Flink 的技术栈。
- 最外围、最底层是 Flink 的计算引擎,包含流计算和批处理,咱们针对稳定性和性能做了大量工作。
- 里面一层是跟 Flink 打交道的周边组件,既有 Kafka、rocketMQ 等中间件,也有 ClickHouse、Hive 等数据分析工具,还有 Hudi 等数据湖的应用。用户能够基于 Flink 和这些组件构建各种利用,涵盖了实时、近实时、批处理的各种场景。
- 最外层是具体的应用场景,常见的有电商、商业化等视频相干的业务方,利用场景蕴含机器学习、多维分析等。另外还有很多技术部门基于 Flink 来实现数据的导入、转换,比方 CDC、湖仓一体等。
利用规模上,咱们有 50 万 CPU 核,次要通过 Yarn 和 K8s 的形式进行资源托管,下面运行着 2000+ 作业,峰值解决达到了 6 亿 / 秒,日解决条数达到了 31.7 万亿,节假日或流动的时候流量甚至会翻倍。
二、容错能力晋升
容错能力次要蕴含以下局部:
- 首先是单点复原,反对任意多个 task 失败时的原地重启,long-running 作业根本能够做到永不断流;
- 其次,是集群故障的应答,蕴含冷备、热备以及 Kafka 双集群的集成;最初是黑名单的应用。
Flink 为了做到 exactly-once,任何节点呈现故障都须要重启整个作业,全局重启会带来长时间的进展,最高可达十几分钟。有些场景不谋求 exactly-once,比方举荐等实时场景,但它们对服务可用性的要求很高,无奈容忍作业的断流,还有模型训练等初始化很慢的场景,重启工夫特地长,一旦重启将会造成很大的影响。基于以上思考,咱们开发了单点复原性能。
上图是单点复原的基本原理。如图有三个 task,其中两头的 task 失败了,那么首先 Flink 的主节点会从新调度两头的 task,此时上下游的 task 不会失败,而是期待重连。等两头的 task 调度胜利后,master 节点会告诉上游的 task 去重连上游的 task,与此同时两头的 task 也会去连它上游的 task,通过从新构建读视图来复原数据的读取。等上下游都连贯胜利后这个作业就能够失常工作了。
理解完基本原理,再来看一下线上多 task 复原的案例。理论环境中常常会呈现多个 task 同时失败的状况,这个时候咱们会依照拓扑程序来一一复原失败的 task,比方上图中是依照从左往右的程序复原。
这个性能上线之后,咱们外部有将近 100 个作业应用了这个性能,惯例故障下作业都能够做到一直流,即使呈现小的流量稳定,业务也能够做到无感知,业务方彻底辞别了服务断流的噩梦。
集群故障一旦产生就是致命性的,所有的数据都会散失,服务也会挂掉。咱们的计划次要蕴含冷备、热备,以及 Flink 和 Kafka 的双集群集成。
冷备次要指的是对数据做备份,集群挂掉当前能够疾速在另外一个集群启动计算工作。
如上图,KwaiJobManager 是快手的作业管理服务,其中的 failover coordinator 次要负责故障解决。咱们会把所有 jar 包等文件保留在 HDFS,所有的信息保留在 Mysql,这两者都做到了高可用。作业运行在主集群 ClusterA,线上用的是增量快照,会存在文件依赖的问题,所以咱们定期做 savepoint 并拷贝到备集群。为了防止文件过多,咱们设置了定时删除历史快照。
一旦服务检测到集群 A 故障,就会立即在集群 B 启动作业,并从最近一次的快照复原,确保了状态不失落。对于用户来说,只须要设置一下主备集群,剩下的全都交由平台方来做,用户全程对故障无感知。
热备就是双集群同时运行一样的工作。咱们的热备都是全链路的,Kafka 或者 ClickHouse 等都是双跑。最下面的展现层只会应用其中一份后果数据做展现,一旦呈现故障,展现层会立即切换到另外一份数据,切换过程在一秒以内,用户全程无感知。
相比冷备,热备须要等量的资源来备份运行,但切换的速度更快,比拟实用于春晚等要求极高的场景。
Flink 与 Kafka 的双集群集成,次要是因为快手的 Kafka 都具备双集群的能力,所以须要 Flink 反对读写双集群的 Kafka topic,这样某个 Kafka 集群挂掉时 Flink 能够在线无缝切换。如上图所示,咱们 Flink 对 Kafka 双集群做了形象,一个逻辑上的 topic 底层对应两个物理上的 topic,外面由多个 partition 组合而成,Flink 生产逻辑 topic 就相当于同时读取底层两个物理 topic 的数据。
针对集群的各种变动,咱们全副形象成了 partition 上的扩缩容,比方集群挂掉,能够看成是逻辑 topic 的 partition 缩容;单集群切双集群,能够看成是逻辑 topic 的扩容;topic 的迁徙,能够看成逻辑 topic 先扩容再缩容。这里咱们都是依照双集群来举例,实际上无论是双集群还是更多的集群,原理都是一样的,咱们都提供了反对。
呈现以下两种状况的时候须要应用黑名单性能。第一种是重复调度有故障的机器,导致作业频繁失败。另一种是机器因为硬件或网络等起因,导致 Flink 个别节点卡主但未失败。
针对第一种状况,咱们开发了阈值拉黑,如果作业在同一个机器上失败或者屡次部署阈值失败,超过配置的阈值就会拉黑;针对第二种状况,咱们建设了异样分类机制,针对网络卡顿和磁盘卡顿状况,间接驱除容器并且拉黑机器。另外咱们还对外裸露了拉黑接口,买通了运维 Yarn 等内部零碎,实现了实时拉黑。咱们还以 Flink 黑名单为契机,建设了一套残缺的硬件异样解决流程,实现了作业主动迁徙,全程自动化运维,用户无感知。
三、Flink 引擎管制与实际
3.1 Flink 实时控制
针对 long-running 的实时作业,用户常常须要作出变更比方调整参数来更改行为,还有一些零碎运维比方作业降级、批改日志级别等,这些变更都须要重启作业来失效,有时会高达几分钟到几十分钟,在一些重要的场合,这是无奈容忍的。比方在流动期间或者排查问题的关键点,作业一旦进行将会功亏一篑,所以咱们须要在不进行作业的状况下实时调整作业的行为,也就是实时控制。
从更宽泛的角度来看,Flink 不仅是计算工作,也是一个 long-running service。咱们的实时控制正是基于这样的思考,来为实时计算提供交互式的管制模式。如上图所示,用户通过经典的 kv 数据类型与 Flink dispatcher 交互,Flink 收到音讯后,会先将它们长久化到 zk 用于 failover,而后依据具体的音讯做相应的管制,比方管制 resource manager、管制 job master 或者其余组件。
咱们既反对用户自定义动静参数,也为用户提供了很多现成的系统控制。用户自定义次要是应用 RichFunction 来获取动静参数,并且实现相应的逻辑,这样在作业运行的时候就能够实时传入参数,达到实时控制的成果。
零碎提供的实时控制能力,次要蕴含数据源限速、采样、重置 Kafka offset、调整快照参数以及运维相干的更改日志级别、拉黑节点等性能。除此之外,咱们还反对动静批改局部 Flink 原生配置。
快手外部对实时控制性能实现了产品化,用户应用起来十分不便。
3.2 源端控制能力
Flink 解决历史工作或者作业性能跟不上的的时候,会引发以下的问题:
首先 source 的各个并发处理速度不统一,会进一步减轻数据的乱序、失落、对齐慢等问题。其次,快照会继续变大,重大影响作业性能。另外还有流量资源的不可控,在高负载的状况下会引发 CPU 打满、oom 等稳定性问题。
因为 Flink 是一种 pipeline 实时计算,因而从数据源动手能够从根本上解决问题。
首先来看下历史数据精准回放性能。上图是以二倍速率去生产 Kafka 的历史数据,Flink 作业追上 lag 之后就能够转成实时生产。通过这种形式能够无效解决简单工作的稳定性问题。
上图的公式是一个基本原理,生产倍率 = Kafka 的时间差 / Flink 的零碎时间差,用户应用的时候只须要配置倍率即可。
另外一个能力是 QPS 限速。数据流量很大的时候,会导致 Flink 的负载很高以及作业不稳固。咱们基于令牌桶算法,实现了一套分布式的限速策略,能够无效减缓 Flink 的压力。应用 QPS 限速后,作业变得十分衰弱,上图绿色局部可见。19 年的春晚大屏,咱们就是通过这个技术实现了柔性可用的保障。
另外咱们还反对主动适配 partition 的变更和实时控制,用户能够随时随地调整作业的 QPS。
最初一个性能是数据源对齐,次要指 watermark 的对齐。首先每个 subtask 都会定期向主节点汇报本人的 watermark 进度,次要包含 watermark 的大小和速度。主节点会计算下一个周期的 target,即预期的最大 watermark,再加一个 diff 返回给各个节点。各个 source task 会保障下一个周期的 watermark 不超过设置的 target。上图最上面是 target 的计算公式,预测每个 task 下个周期完结时候的 waterMark 值,再加上咱们容许的 maxdiff 而后取最大值,通过这种形式能够保障各个 source 的进度统一,防止 diff 过大导致的稳定性问题。
3.3 作业平衡调度
生产环境中常常会呈现资源不平衡的景象,比方第一点 Flink 的 task 散布不平均,导致 task manager 资源应用不平衡,而作业的性能又往往受限于最忙碌的节点。针对这个问题,咱们开发了作业平衡调度的策略;第二点是 CPU 应用不平衡,有些机器被打满而有些机器很闲。针对这个问题,咱们开发了 CPU 平衡调度的性能。
上图中有三个 jobVertex,通过 hash shuffle 的形式来连贯。上图两头局部显示了 Flink 的调度,每个 jobVertex 都是自上而下往 slot 里调度 task,后果就是前两个 slot 很满而其余 slot 很闲暇,第一个 task manager 很满而第二个 task manager 很闲暇。这是一个很典型的资源歪斜的场景,咱们对此进行了优化。调度的时候首先计算须要的总资源,也就是须要多少个 task manager,而后计算每个 TM 调配的 slot 个数,确保 TM 中的 slot 资源平衡。最初平衡调配 task 到各个 slot 中,确保 slot 中 task 平衡。
理论运行过程中还存在另外一种歪斜状况 —— CPU 歪斜,咱们来看下怎么解决这个问题。上图左侧,用户申请了一个核但理论只应用了 0.5 个核,也有申请了一个核理论应用了一个核。依照默认调度策略,大量此类 case 可能会导致有的机器 CPU 使用率很高,有的却很闲,负载高的机器不论是性能还是稳定性都会比拟差。那么如何让申请和应用的 diff 尽可能小?
咱们的计划是对作业资源精准画像,具体做法分为以下步骤:作业运行过程中统计每个 task 所在容器的 CPU 使用率,而后建设 task 到 executionSlotSharingGroup,再到 container 的映射,这样就晓得了每个 task 所在 slot 的 CPU 应用状况,而后依据映射关系重启作业,依据 task 所在 slot 的历史 CPU 使用率来申请相应的资源,一般来说会预留一些 buffer。如上图右图所示,如果预测足够准,重启后 task manager 应用的资源不变,然而申请值变小了,二者的 diff 就变小了。
其实业界一些先进的零碎,比方 borg 是反对动静批改申请值的,但咱们的底层调度资源不持这种策略,所以只能在 Flink 这一层应用资源画像来解决这个问题。当然资源画像不能保障百分百精确,咱们还有其余策略,比方限度高 CPU 负载的机器持续分配资源,尽可能减少不平衡。另外咱们还建设了分级保障制度,不同优先级的作业有不同的 cgroup 限度,比方低优先级作业不再超配,高优先级作业容许大量超配,从而防止 CPU 应用过多导致的不平衡。
四、快手批处理实际
上图是咱们的批处理架构图。最底层为离线集群,两头是 Flink 引擎以及 Flink 的 data stream API、SQL API,再下面是一些平台方比方 sql 入口、定时调度平台等,此外还有一些流批一体的摸索,最下面是各种用户比方视频、商业化等。
流批一体中,流的个性是低延时,批的个性是高吞吐。针对流批一体,咱们期待零碎既能解决 unfield batch 数据,也能够调整数据块的 shuffle 大小等来平衡作业的吞吐和时延。
快手外部对流批一体进行了很多摸索,咱们为存储数据建设了对立的 Schema 规范,包含流表和批表,用户能够应用雷同的代码来解决流表和批表,只是配置不同。产生的后果也须要合乎对立的 Schema 规范,这样就能够买通上下游,实现尽可能多的逻辑复用。Schema 对立是咱们快手数据治理的一部分,湖仓一体等场景也都有这个需要。
利用场景次要包含以下几个方面:
- 指标计算,比方实时指标和报表计算。
- 数据回溯,利用已有的离线数据从新生成其余指标。
- 数仓减速,次要是数据仓库和数据湖的实时减速。
流批一体带来的收益是多方面的,首先是升高了开发和运维老本,实现了尽可能多的代码逻辑复用,运维不再须要保护多个零碎。其次是实时处理和批处理的口径保持一致,保障了最终后果的统一。最初是资源方面的收益,有些场景只须要一套实时零碎。
咱们在调度方面进行了优化。如上图所示的三个 task,起初 a 和 c 曾经实现,b 还在运行。这时 a 失败了,依照默认的策略 ABC 都须要从新运行,即使 c 曾经实现。在理论场景中会有大量的 c 进行重算,带来微小的资源损耗。针对这种状况如果,咱们默认开启了以下策略:如果 a 的后果是决定性的(实际上大部分批处理的输入都是决定性的),能够不再重算 c,只需计算 a 和 b。
上图是咱们快手外部针对批处理的优化和改良。
第一个是 shuffle service,当初既有外部的集成,也在试用社区的版本,次要是为了实现存储和计算的解耦,同时进步 shuffle 的性能。第二个是动静资源的调度,次要是依据数据量来主动决定算子的并发,防止人工重复调整。第三个是慢节点躲避,也叫揣测执行,次要是为了缩小长尾效应,缩小总执行工夫。第四个是 hive 的优化,比方 UDF 适配、语法兼容。另外针对 partition 生成 split,咱们减少了缓存、多线程生成等形式,极大缩小了分片的工夫。最初是一些压缩形式的反对,比方反对 gzip、zstd 等。
五、将来布局
咱们的将来布局次要分为以下几个方面:
- 首先是实时计算,进一步加强 Flink 的性能、稳定性和应用性,并通过实时计算来减速各种业务场景。
- 第二个是在线和离线的对立,蕴含实时、近实时和批处理。咱们期待能用 Flink 对立快手的数据同步、转换和在离线计算,让 ETL、数仓、数据湖解决等各类场景,都应用一套 Flink 计算零碎。
- 最初一个是弹性可伸缩,次要是云原生相干,蕴含在离线混部和作业的弹性伸缩等。
点击查看直播回放 & 演讲 PDF
更多 Flink 相干技术问题,可扫码退出社区钉钉交换群
第一工夫获取最新技术文章和社区动静,请关注公众号~
流动举荐
阿里云基于 Apache Flink 构建的企业级产品 - 实时计算 Flink 版现开启流动:
99 元试用 实时计算 Flink 版(包年包月、10CU)即有机会取得 Flink 独家定制卫衣;另包 3 个月及以上还有 85 折优惠!
理解流动详情:https://www.aliyun.com/produc…