Airflow之WebServer性能优化
有着多年开发的工程师,在设计与编码的过程中就会自带 性能优化
的思维。笔者有着多年的Java后端研发经验,所以,在性能优化这块,我们有着非常成熟的套路。
比如,在项目技术详细设计的阶段,我们会合理预估数据量,决定申请MySQL的配置,是否读写分离,是否分库分表;我们接口梳理的时候,哪些核心接口需要高QPS保障,这决定了我们是否需要使用到Redis做缓存,或者异步、多线程方式处理等。包括编码的过程中我们也会带着Java编码最佳实践以及MySQL最佳规范去做实现。
但,本文并非介绍常规的性能优化,而是针对开源大数据调度系统Apache Airflow的性能优化。
遇到问题
Apache Airflow是apache社区开源的一款大数据任务调度系统,我司上万个大数据离线任务均由Airflow调度完成。
Airflow包含了非常核心的调度scheduler模块和webserver模块。
schedluer 主要负责任务的运行
webserver 主要是可视化web系统,可以查看dag运行情况,以及任务运行信息,运行日志等等。
现在的核心问题就是webserver的性能极低,首页加载需要15s左右,一个dag详情页加载也在几秒以上,一个稍微大一些的dag达到了10s左右,这是极度不能忍的。
【优化前首页】
问题分析
Airflow使用Python开发的,所有的代码都在一个工程中,使用的是Flask框架(一个Python的web框架),整体是一个前后端没有分离的项目。
所以,当我们进入首页到渲染页面顺序的需要拿到两部分数据才真正渲染页面:
/admin 首页页面,其中包含了大量的数据,消耗4.91秒
/task_states 渲染Recent Tasks的数据,通过Ajax获取,消耗10.33秒
两个数据拿到之后才看到页面,总耗时15.24秒,这肯定不能忍的。
问题解法
因为是开源项目,我们尽量不修改源码,我们原则是扩展。所以,针对首页需要的数据,我们开发REST API。
原页面对象绑定了大量没有使用到的数据,优化中,我们精简数据结构,查询需要使用到的字段再返回。
原页面两个请求顺序的优化为先渲染页面,其他特殊列数据异步渲染。
前端逻辑重写,需要我们另外单独起纯前端项目来实现;然后在原页面通过iframe引入方式让用户使用新的UI页。(我们计划通过前后端分离方式逐渐全部重写Airflow的WebUI)
高性能库的使用(在python中,不同的json库,性能居然差了好几倍,惊讶!)
优化效果
【优化后首页】
通过上图(新UI)可以看到,我们数据接口只耗时108ms,效率提升了150多倍。也就是进入页面瞬间可以加载数据主要数据,而其中Recent Task和DAG Runs列依然采用异步加载方式,在功能上,这两列其实并不是常用功能,列表出来之后通过点击列表中的DAG名称进入详情是高频操作。
事实上,进入DAG详情页页进行了重构优化,效率提升了7倍。
【优化前DAG详情页】
【优化后DAG详情页】
启示
Airflow是一款优秀的开源调度系统,但是webserver却做的比较糟糕,只能说Airflow的核心是Scheduler而非webserver,套一句常说的话,“又不是不能用!”。
工作中亦是如此,我们大多数开发的项目都是企业B端项目,这些项目有一些特征:
系统用户不多,并且大多数可能还是内部用户
数据量并不大,主表数据可能几年也才几千万
内部逻辑较重,B端系统一般有着比较复杂的权限校验、事务、RPC调用关系。
以致于会导致天然低QPS、慢接口、低要求、重功能,为了节约成本,可能最终没有安排人力去做优化。所以,作为一名研发老司机,我给出的建议是
任何经手的项目,性能要求应该写在设计文档里,后期即使在数据量合理增长的情况下,依然有着良好的性能表现。
作者:FunGa黄佳
链接:https://juejin.cn/post/7020386907079049230