大沙,阿里巴巴高级技术专家,负责实时计算 Flink SQL,之前在美国脸书任职,Apache Flink committer.
实时计算 in 阿里巴巴
1999 年起,阿里从电商平台开始不断拓展业务,在金融,支付,物流,文娱各个领域衍生出众多产品,例如依托于淘宝,天猫为主的电商平台,阿里妈妈广告平台,蚂蚁金服支付宝,阿里云,大文娱等.今天的阿里它已经不仅仅是一个电商平台,而是一个庞大的应用生态.阿里巴巴目前是全球最大的电商平台,2016 财年收入达到 5500 亿美金.在阿里平台上有 5 亿的用户,相当于中国人口的 1/3,每天有近 1000 万用户通过阿里平台交易.
阿里俨然成为巨大的商业航母,在这艘航母之上,海量的用户和应用必然会产生大量的数据.目前,阿里巴巴的数据量级已经达到 EB 级别,每天的增长量达到 PB 级别,实时计算日常峰值处理的数据量可达到 1 亿每秒,今年双 11 更是达到了惊人的 4.7 亿每秒.
实时计算在阿里巴巴内部应用广泛.随着新经济体的出现与发展,技术的革新和用户需求的提升,人们越来越需要实时计算的能力,它的最大好处就是能够基于实时变化数据更新大数据处理的状态和结果.接下来,举两个例子来阐释实时计算在阿里内部应用的场景:
1. 双 11 大屏
每年双 11 阿里都会聚合有价值的数据展现给媒体,GMV 大屏是其中之一.整个 GMV 大屏是非常典型的实时计算,每条交易数据经过聚合展现在大屏之上.从 DataBase 写入一条数据开始,到数据实时处理写入 HBase,最后展现在大屏之上,整个过程的链路十分长.整个应用存在着许多挑战:
1) 大屏展现需要秒级延迟,这需要实时计算延迟在亚秒级别
2) 双 11 大量数据需要在一个 Job 中聚合完成
3)Exactly-Once 保持数据计算的精确性
4) 系统高可用,不存在卡顿和不可用的情况
这个应用场景的 SLA 非常高,要求秒级延迟和数据的精确性,但它的计算并不复杂,接下来介绍更为复杂的应用.
2. 实时机器学习
机器学习一般有两个重要的组件:Feature 和 Model.传统的机器学习使用批计算对 Feature 的采集和 Model 的训练,这样更新频率太低,无法适应数据在不断变化的应用的需求.例如在双 11 时,商品的价格,活动的规则与平时完全不同,依据之前的数据进行训练得不到最优的效果.因此,只有实时收集 Feature 并训练 Model,才能拟合出较为满意的结果.为此,我们开发了实时机器学习平台.
此实时机器学习平台主要包括两个部分:实时 Feature 计算和实时 Model 计算.这套系统同样拥有很多挑战,具体如下:
1) 机器学习需要采集各种各样 Metrics,存在许多 DataSource
2) 维度多,如用户维度,商品维度.维度的叠加甚至是笛卡儿积导致最后的 Metrics 是海量的,State 非常巨大
3) 机器学习计算复杂,耗用大量 CPU
4) 某些数据不能存在 State 中,需要外部存储,存在大量外部 IO
3. 实时 A/B Testing
用户的 Query 也有可能不停变化,典型的例子有实时的 A/B Testing.
算法工程师在调优 Model 时会涉及多种 Model,不同的 Model 有不同的计算模式和方法,产生不同的计算结果.因此,往往会有不同的 Query 订阅实时数据,产生结果后根据用户回馈迭代 Model,最终得到最优模型.A/B Tesing 的挑战在于算法工程师往往计算很多 Metrics,所有的 Metrics 都通过实时计算进行统计会浪费大量资源.
针对这个挑战,我们设计了 A/B Testing 的框架开发平台.它用来同步算法工程师感兴趣的 Metrics 进行聚合,收集起来并发送到 Druid 引擎.这样,算法工程师根据不同 Job 的要求清洗数据到 Druid,最后在 Druid 之上对不同的 Metrics 进行统计分析,从而找到最优的算法 Model.
综上,实时计算在阿里巴巴内部存在如下挑战:
1) 业务庞大,场景多,大量的机器学习需求,这些因素一起导致了计算逻辑十分复杂
2) 数据量大,作业多,因此整个实时计算的机器规模十分巨大
3) 要保障低延迟和数据精确性,同时要满足高吞吐量的需求
Flink 的选定及优化
为了应对上述挑战,我们调研了许多计算框架,最终选定 Flink,原因如下:
1.Flink 很好地引入和设计了 State,基于 State 复杂的逻辑计算如 join 能得到很好的描述
2.Flink 引入了 Chandy-Lamport 算法,在此算法的支撑下可以完美实现 Exactly-Once,并能在低延迟下实现高吞吐量.
然而,Flink 在 State,Chandy-Lamport 算法等方面还有很多缺陷,为此阿里开辟了名为 Blink 的项目.
Blink 是开源 Flink 与阿里巴巴 Improvement 的结合,主要分两大块:
1.BlinkRuntime
包括存储,调度和计算,不同公司在使用 Flink 时,存储,调度以及底层优化等方面会有诸多不同,阿里巴巴的 blink 内部也对 Runtime 做了诸多个性化的优化,这一层不好与 Apache Flink 社区统一,我们称之为 Blink Runtime.
2.Flink SQL
原生的 Flink 只有比较底层的 DataStream API,用户在使用时需要设计实现大量的代码,此外 DataStream 本身也有设计上的缺陷.为了方便用户使用,阿里巴巴团队设计了流计算的 Flink SQL 并推回了社区.取名 Flink SQL 而不是 Blink SQL,主要原因 Blink 和 Flink 在 SQL 这个用户 API 上面是完全和社区统一的,另外 Apache Flink 的大部分功能都是阿里巴巴贡献的,所以说 Flink SQL 就是 Blink SQL,没有特别大的区别.
BlinkRuntime 核心优化解密
1. 部署和模型的优化
优化包含以下几点:
1) 解决大规模部署问题.Flink 中一个 Cluster 只有一个 JobMaster 来管理所有的 Job.随着 Job 的不断增加,单一的 Master 无法承接更多的 Job,产生了瓶颈.因此,我们重构了架构,使每一个 Job 拥有自己的 Master.
2) 早期的 Flink 中 TaskManager 管理很多 Task,某一个 Task 的问题会导致 TaskManager 崩溃,进而影响其他 Job.我们使每一个 Job 拥有自己的 TaskManager,增强了 Job 的隔离.
3) 引入 ResourceManager.ResourceManager 可以和 JobMaster 通讯,实时动态地调整资源,达到最优的集群部署.
4) 我们不仅将这些优化应用在 YarnCluster 上,还应用到 Mesos 和 Standalone 的部署上.
有了这些工作,Flink 就可以应用到大规模的集群部署.
2.Incremental Checkpoint
实时计算需要不停的在 checkpoint 的时候来保留计算状态.早期的 Flink 的 checkpoint 的设计存在缺陷,在每个 checkpoint 发生的时候,它会读取所有旧的状态数据,和新的数据合并后按照全量的方式写入磁盘.随着 State 的不断增大,在每次做 checkpoint 的时候所需要的数据读取和写入的量级是十分巨大. 这就导致 Job 的 checkpoint 的间隔需要设置的很大,不能小于 1 分钟.越大的 checkpoint 的间隔, failover 的时候回退的计算就越大,造成的数据延迟也就越严重.
为了减少 checkpoint 间隔,我们提出了 Incremental Checkpoint 的设计.概括的说就是在 checkpoint 的时候只存储增量的 state 变化的数据.由于历史上每个 checkpoint 的数据都已经保存,后面的 checkpoint 只需要将不同的数据放入存储,这样每次做 checkpoint 需要更新的数据量就非常小,使得 checkpoint 可以在若干秒级内完成,这就大大减小了 failover 时可能引起的延迟.
3. 异步 IO
很多时候我们不得不将数据放在外部存储中,这样在计算过程中就需要通过网络 IO 读取数据.传统的方式使用 Sync-IO 的读取方式,在发出数据请求之后,只有等待到结果返回之后才能开始下一个数据请求,这种做法造成了 CPU 资源的浪费,因为 CPU 在大多数情况下都在等待网络 IO 的请求返回.Sync-IO 使得 CPU 的资源利用率无法提高到极致,也就大大影响了单位 CPU 下的计算吞吐.为此提升计算吞吐,我们设计了 Async-IO 的数据读取框架,它允许异步地多线程地读取数据.
每次数据请求发出后不需要等待数据返回就继续发送下一个数据请求.当数据请求从外部存储返回后,计算系统会调用 callback 方法处理数据.如果数据计算不需要保序,数据返回之后就会快速经过计算发出.如果用户需要数据的计算保序时,我们使用 buffer 暂时保存先到的数据,等前部数据全部到达后再批量地发送.在使用了 Async-IO 之后,根据设置的 buffer 大小不同计算吞吐可以提升几十倍甚至几百倍,这就极大地提升了单位 CPU 利用率和整体的计算性能.
来源: https://yq.aliyun.com/articles/399401