硬核干货——《中小企业 AI 实战指南》免费下载! 了解详情
写点什么

京东 Flink 优化与技术实践

  • 2020-12-09
  • 本文字数:4460 字

    阅读完需:约 15 分钟

京东Flink优化与技术实践

导读:Flink 是目前流式处理领域的热门引擎,具备高吞吐、低延迟的特点,在实时数仓、实时风控、实时推荐等多个场景有着广泛的应用。京东于 2018 年开始基于 Flink+K8s 深入打造高性能、稳定、可靠、易用的实时计算平台,支撑了京东内部多条业务线平稳度过 618、双 11 多次大促。本次讲演将分享京东 Flink 计算平台在容器化实践过程中遇到的问题和方案,在性能、稳定性、易用性等方面对社区版 Flink 所做的深入的定制和优化,以及未来的展望和规划。


实时计算引进


1.发展历程



最初大数据的模式基本都是 T+1,但是随着业务发展,对数据实时性的要求越来越高,比如对于一个数据,希望能够在分钟级甚至秒级得到计算结果。京东是在 2014 年开始基于 Storm 打造第一代流式计算平台,并在 Storm 的基础上,做了很多优化改进,比如基于 cgroup 实现对 worker 使用资源的隔离、网络传输压缩优化、引入任务粒度 toplogy master 分担 zk 压力等。到 2016 年,Storm 已经成为京东内部流式处理的最主要的计算引擎,服务于各个业务线,可以达到比较高的实时性。


随着业务规模的不断扩大,Storm 也暴露出许多问题,特别是对于吞吐量巨大、但是对于延迟不是那么敏感的业务场景显得力不从心。于是,京东在 2017 年引入了 Spark Streaming 流式计算引擎,用于满足此类场景业务需要。


随着业务的发展,不光是对于数据的延迟有很高要求,同时对于数据的吞吐处理能力也有很高的要求,所以迫切需要一个兼具低延迟和高吞吐能力的计算框架,于是在 2018 年我们引入了 Flink。在 Flink 社区版的基础上,我们从性能、稳定性、易用性还有功能等方面,都做了一些深入的定制和优化。同时我们基于 k8s 实现了实时计算全面的容器化,因为容器化有很多的优点,它可以做到很好的资源隔离,同时它有一个很强的自愈能力,另外它很容易实现资源的弹性调度。同时我们基于 Flink 打造了全新的 SQL 平台,降低用户开发实时计算应用的门槛。


到 2020 年,基于 Flink 和 k8s 实时计算平台已经做的比较完善了。过去流式处理是我们关注的重点,今年我们也开始逐渐的支持批处理,朝着批流一体的方向演进。另外 AI 是目前比较火的一个方向,对于 AI 来说,它的实时化也是一个重要的研究方向。所以我们的实时计算平台将会朝着批流一体和 AI 的方向进行发展。


2.平台架构



上面是京东实时计算平台 JRC 的整体架构,整个架构以定制化改造后的 Flink 为核心,Flink 运行在 K8S 上,状态存储在 HDFS 集群上,通过 Zookeeper 保证集群的高可用。支持流式源 JDQ(京东基于 Kafka 深入定制实现的实时数据总线)和 Hive,数据主要写入 JimDB(京东内存数据库)、ES、Hbase 和京东 OLAP。计算平台支持 SQL 和普通 JAR 包两种方式的作业,具有配置、部署、调试、监控、和日志处理等功能。


3. 业务场景



京东 Flink 服务于京东内部非常多的业务线,有 70 多个一级部门在使用,主要应用场景包括实时数仓,实时大屏,实时推荐,实时报表,实时风控和实时监控,当然还有其他一些应用场景。对数据计算实时性有一定要求的场景,一般都会使用 Flink 进行开发。


4. 业务规模



京东 Flink 集群目前由 5000 多台物理机组成,它服务了京东内部 70 多个一级业务部门,目前线上的流计算任务大概有 3000 多个,数据的处理能力可以达到每分钟数十亿甚至更高。


Flink 容器化实践


1.容器化历程



京东从 2018 年开始进行计算引擎的容器化改造,2019 年初已经实现计算单元全部容器化,2020 年进行了容器化方案升级,使用 native k8s 实现计算资源的弹性扩容。容器化改造的好处是提升了资源使用率,提高了研发效率,增强了业务稳定性,减少了运维部署成本。


2.容器化方案



旧的容器化方案是基于 k8s Deployment 部署的 Standalone Session 集群,它需要事先预估出集群所需资源,比如需要的 JobManager 和 TaskManager 的资源规格和个数。然后 JRC 平台通过 K8S 客户端向 K8S Master 提出请求,创建 JobManager 的 Deployment 和 TaskManager 的 Deployment。其中使用 ZK 保证高可用,使用 Hdfs 实现状态存储,使用 Prometheus 实现监控指标的上传,结合 Grafana 实现指标的直观展示。集群使用 ES 存储日志,方便日志的查询。


3.容器化遇到的问题 &对策



容器化过程中可能遇到很多问题:


JM/TM 故障自动恢复


应用部署在容器中,当应用出现异常时,如何发现应用或者异常的情况呢?比如可以使用存活探针,编写检测脚本定期读取应用的心跳信息。当检测到 Pod 处于不健康状态时,可以采用 k8s 的重启机制来重启不健康的容器。


减少 Pod 异常对业务影响


在 k8s 中由于硬件异常、资源过载、Pod 不健康等问题会导致 Pod 被驱逐或自动重启,Pod 重启时势必会影响到该 Pod 上分布计算任务的正常运行。这个时候可以考虑采用适当的重启策略、改造内核等方案来减少对任务影响。比如京东实现了 JM Failover 优化,当 Pod 异常引起 JM Failover 时采用的是任务不恢复、重建任务状态恢复的方式,可以一定程度上减少 Pod 重启对业务带来的影响。


性能问题


在容器环境下,JVM 对 cpu 和内存的感知会有一定的问题,在 Java8 版本中,一些参数就要进行显式的设置。对于机器性能差异或热点等问题导致部分 Pod 计算慢的问题,可以考虑进行针对性优化(比如实现基于负载的数据分发)或处理(比如检测到计算慢的 Pod 将其驱逐到负载较低的机器)。此外,对于使用容器网络的情况下,可能会带来一定的网络性能损耗,此时可以根据情况选择使用主机网络避免网络虚拟化带来的开销,或者选择更高性能的网络插件。


重要业务稳定性


如何保证业务的稳定性是一个需要重点考虑的问题。除了保证系统各个环节的高可用外,还可以根据业务情况考虑使用其它合理的方案,例如业务分级管理,独立资源池,多机房互备等。


4.容器化方案升级(Native k8s)



原有容器化方案存在一定的问题:


  • 资源需要提前分配

  • 无法实现资源弹性伸缩

  • 极端场景下 Pod 不能正常拉起,影响任务恢复

  • 重要业务稳定性


容器化升级的解决方案是采用 Native K8s 的方式。由 JRC 平台先向 K8S Master 发出请求,创建 JobManager 的 Deployment;然后在用户通过 Rest 服务提交任务后,由 JobMaster 通过 JDResourceManager 向 JRC 平台发出请求,然后 JRC 平台向 K8s Master 动态申请资源去创建运行 TaskManager 的 Pod。


此处,通过引入 JRC 平台与 K8s 交互,屏蔽了不同容器平台的差异,解耦了镜像与平台集群配置 &逻辑变化。另外,为了兼容原有 Slot 分配策略,在提交任务时会预估出任务所需资源并一次性申请,之后采用等待一定时间后进行 slot 分配的方式达到兼容目的。


Flink 优化改进



主要做了以下四个方面的优化:


  • 性能

  • 稳定性

  • 易用性

  • 功能扩展


下边分几个重要的点进行讲解:


1.预览拓扑



预览拓扑主要是为了解决业务的一些痛点:比如任务调优繁琐、SQL 任务无法指定并行度、任务需要的额 Slot 数不清楚、并行度调整后网络 buffer 不足等。在 Flink 任务调试阶段,对任务并行度、Slot 分组、Chaining 策略的调整是个反复的过程,如果把参数写到命令行就太繁琐了。而基于预览拓扑就可以很方便地对这些参数进行配置。



预览拓扑基本的实现方案如上图:用户提交 JAR 包后可根据 JAR 包生成对应的拓扑图,之后用户根据拓扑图可以进行在线调整,最后自动将修改后的配置和原来的 JAR 包一起进行任务提交。



预览拓扑机制使得不修改程序多次提交任务调优成为可能,但是如何保证前后两次提交生成算子稳定的对应关系呢?解决方案的关键是保证算子有稳定的唯一身份标识,具体算法是:如果算子指定了 uidHash 就用 uidHash,如果算子指定了 uid 就使用 uid,否则就从 source 开始广度优先遍历,利用算子在 graph 中的位置生成一个稳定 hash 值。


2.背压量化



第二个重要的优化是背压量化。


在 Flink 开发的时候,主要有两种方式:


通过 Flink UI 背压面板观察是否背压。使用这种方式在某些场景比较方便,但是它存在几个问题:


  • 在有些场景下采集不到背压

  • 对于历史背压情况无法跟踪

  • 背压影响不直观

  • 大并行度时背压采集压力


通过任务背压相关指标进行观察和分析,通过将指标定期采集并存储起来,可以进行实时或历史的背压分析。但是它也有一些不足的地方:


  • 不同 Flink 版本中指标含义有一定差异

  • 分析背压有一定门槛,需要对于指标含义有深入理解,联合进行分析

  • 背压未量化,对业务影响程度不够直观



京东的解决方案是采集背压发生的位置、时间和次数指标,并对这些指标进行上报存储。同时对量化的背压指标结合运行时拓扑,可以精确反映发生背压现场的情况。


3.HDFS 优化



随着业务数量的增多,HDFS 集群的压力就会变得很大。这会直接导致 RPC 响应时间变慢,造成请求堆积,同时大量小文件也会对 NN 内存造成很大压力。对此京东尝试的解决方案有 4 方面:限制 checkpoint 最小间隔,时间最小设置在 1min 左右可以满足大部分业务需求;进行小文件合并;降低 cp 创建和删除时的 hdfs rpc 请求;HDFS 集群多 ns 分散均衡压力。


4.网络分发优化



在实践过程中我们发现,即使业务使用了 rebalance 并且对任务进行了打散分布,但是由于机器处理能力和负载的差异,会导致任务各个并行度不同程序的背压表现,严重影响了任务的性能。为此,我们开发了基于负载的动态 rebalance,在数据进行分发时优先选择下游负载最小的 channel 进行分发。


经测试,在特定场景下性能能够提升近一倍。


5.ZK 防抖



目前一般都是使用 ZK 集群实现 Flink 集群的高可用,但是当网络抖动、机器繁忙、ZK 集群暂时无响应或运维机器的时候,都可能会导致任务重启。



任务重启的原因是由于在这些场景发生时,Curator 会将状态设置为 suspended,并且 Curator 认为 suspended 为 Error 状态,从而会释放 leader,Flink 发现 notleader 后会 revokeLeadership,从而造成任务重启。


一个可行的解决办法是升级 Curator 的版本,同时将 connectionStateErrorPolicy 设置为 SessionConnetionStateErrorPolicy。


6.日志分离



目前我们一个集群是支持跑多个任务的,这时日志会出现的问题是:任务的日志和集群 Framework 日志混在一起,同时集群的多个任务日志也是混在一起的,不太方便用户查看日志,快速定位问题。


为了解决这个问题,首先要弄清楚目前 Flink 加载日志框架的基本机制:为了避免跟业务 Job 中可能包含的日志框架的依赖、配置文件产生冲突,Flink 日志相关类的加载都代理给 TaskManager 框架的类加载器,也就是 Parent Classloader,而框架加载的这些类都是从 Flink 安装包的 lib 目录下加载的。对于日志配置文件,Flink 通过 JVM 启动参数来指定配置日志配置文件路径。



日志分离的解决方案是:将日志相关 jar 包加入到各个 task 自己 classloader(user classloader)的类路径中;同时确保使用 user classloader 加载日志类和加载自己的日志配置;


另外对于使用了 Flink 框架的类(比如 PrintSinkFunction),日志不能做到很好的分离,可以考虑使用 logback MDC 机制。


未来规划



未来规划主要包括四个方面:


统一计算引擎


引擎 Storm 全部升级为 Flink,这样可以减少平台的运维成本,同时可以提高作业性能(目前已经接近完成)。


更多 SQL 作业


持续完善 SQL 平台,降低用户的使用门槛,推动用户更多使用 SQL 开发作业。


智能运维


使用智能诊断,自适应调整运行参数,提升任务的鲁棒性


批流一体


深度打造批流一体实时计算平台,兼具低延迟的流处理和高性能的批处理能力。另外统一架构,实现代码复用,降低用户的使用成本。


本文转载自: [DataFunTalk](ID:datafuntalk)


原文链接:京东Flink优化与技术实践


2020-12-09 15:005304

评论

发布
暂无评论
发现更多内容

30个类手写Spring核心原理之动态数据源切换(8)

Tom弹架构

Java spring 源码

🏆【Alibaba中间件技术系列】「RocketMQ技术专题」RocketMQ消息发送的全部流程和落盘原理分析

码界西柚

RocketMQ 消息队列 Apache RocketMQ 12月日更

Apache APISIX 社区双周报 | 功能亮点更新进行中

API7.ai 技术团队

云原生 后端 开源社区 api 网关 Apache APISIX

化繁为简--百度智能小程序主数据架构实战总结

百度Geek说

小程序 百度 架构 后端 数据

DotNet工具箱之性能监控组件——CLRStats

为自己带盐

dotnet 28天写作 12月日更

「猿桌派」即将开播,聚焦客户端埋点和大数据分析

融云 RongCloud

大数据 程序员 埋点

实用机器学习笔记二十:偏差和方差

打工人!

机器学习 深度学习 算法 学习笔记 12月日更

一站式云安全保障,就用行云管家!完美保障!

行云管家

云计算 云安全 企业上云 云资源 云管理

JAVA 开发常用工具汇总

编程江湖

java编程

Linux之more命令

入门小站

Linux

熟悉又陌生的白帽黑客组织OWASP

喀拉峻

黑客 网络安全 安全 OWASP

在线JSON转Csharp工具

入门小站

工具

(转)大数据开发之Hive中UDTF函数

@零度

大数据 hive

【MongoDB学习笔记】-使用 MongoDB 进行 CRUD 操作(上)

恒生LIGHT云社区

数据库 mongodb

Ajax+SSM实现客户端开发 实现简单的前后端分离

Bug终结者

Java ajax 前后端分离

从Hadoop框架讨论大数据生态

编程江湖

大数据 hadoop

超市发:多措并举 提振销售 服务顾客

科技热闻

视频通信中的码率控制算法

拍乐云Pano

音视频 RTC 视频编码 码率控制

【等保小知识】等保一级需要测评吗?

行云管家

网络安全 等保 等级保护 等保一级

给弟弟的信第19封|年轻人要注意养生

大菠萝

28天写作

6000 字干货详解:直播聊天室的无限用户优化

融云 RongCloud

高并发 直播 直播聊天室 海量用户

Linux云计算好学吗?Linux云计算运维学习资料,手把手教你学 条件测试语句和流程控制语句的使用

学神来啦

Linux centos Shell if linux云计算

web技术分享| 白板SDK的几种图形检测算法

anyRTC开发者

前端 音视频 白板 web技术分享 图形检测算法

酷炫3D效果在瘦设备上也能实现?|HDC2021技术分论坛

HarmonyOS开发者

HarmonyOS

从 Discord 看未来社交的「超级群」模式

融云 RongCloud

腾讯云原生数据库TDSQL-C斩获2021 PostgreSQL中国最佳数据库产品奖

科技热闻

升级过log4j,却还没搞懂log4j漏洞的本质?

华为云开发者联盟

Java log4j 漏洞 JNDI rmi

10 个打造 React.js App 的最佳 UI 框架

编程江湖

前端开发

2021数据技术嘉年华 | OceanBase 技术盛宴ON LINE ,我们不见不散!

OceanBase 数据库

数据库 OceanBase 社区版 技术嘉年华 DTC

30个类手写Spring核心原理之自定义ORM(下)(7)

Tom弹架构

Java spring 源码

「Oracle」数据库字符集编码修改

恒生LIGHT云社区

数据库 oracle

京东Flink优化与技术实践_架构_DataFunTalk_InfoQ精选文章