返回 登录
0

争分夺秒:阿里实时大数据技术全力助战双11

摘要: 12月13-14日,由云栖社区与阿里巴巴技术协会共同主办的《2017阿里巴巴双11技术十二讲》顺利结束,集中为大家分享了2017双11背后的黑科技。本文是《争分夺秒:阿里实时大数据技术助战双 11》演讲整理,主要讲解了阿里巴巴实时大数据和机器学习技术,以及这些技术如何运用于阿里巴巴事业部,实现大数据升级,最终取得卓越的双11战果。

12月13-14日,由云栖社区与阿里巴巴技术协会共同主办的《2017阿里巴巴双11技术十二讲》顺利结束,集中为大家分享了2017双11背后的黑科技。本文是《争分夺秒:阿里实时大数据技术助战双11》演讲整理,主要讲解了阿里巴巴实时大数据和相关的机器学习技术,以及这些技术如何运用于阿里巴巴几十个事业部,实现大数据升级,最终取得卓越的双11战果,内容如下。

分享嘉宾:
图片描述
大沙,阿里巴巴高级技术专家,负责实时计算Flink SQL,之前在美国脸书任职,Apache Flink committer。
实时计算in阿里巴巴
1999年起,阿里从电商平台开始不断拓展业务,在金融、支付、物流、文娱各个领域衍生出众多产品,例如依托于淘宝、天猫为主的电商平台、阿里妈妈广告平台、蚂蚁金服支付宝、阿里云、大文娱等。今天的阿里它已经不仅仅是一个电商平台,而是一个庞大的应用生态。阿里巴巴目前是全球最大的电商平台,拥有25个子公司,去年财年收入达到5500亿美金。在阿里平台上有近5亿的用户,相当于中国人口的1/3,每天有近1000万用户通过阿里平台交易。

阿里俨然成为巨大的商业航母,在这艘航母上,在大量的用户和应用之外,必然产生大量的数据。目前,阿里巴巴的数据量级已经达到EB级别,每天的增长量达到PB级别,每天实时计算数据也达到PB级,日常峰值处理的数据量可达到100GB/S,今年双11更是达到了惊人的470GB/S。

实时计算在阿里巴巴内部应用广泛。随着新经济体的发展,技术的革新和用户需求的提升,人们越来越需要实时计算的能力,它的最大特征是数据是在变化的。接下来,举两个例子说明实时计算在阿里内部应用的场景:
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 Tesing的框架开发平台。它用来同步算法工程师感兴趣的Metrics进行聚合,收集起来并发送到Druid引擎。这样,算法工程师根据不同Job筛选出结果的优劣,最后根据Druid对不同的Metrics进行统计分析,建立Model。

综上,实时计算在阿里巴巴内部存在如下挑战:
1) 业务庞大,场景多,导致逻辑复杂
2) 数据量大,拥有很多Job和机器
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时,存储、调度和底层优化等方面会有不同,这一层不好与社区统一,我们称之为BlinkRuntime。

  1. Flink SQL
    原生的Flink只有比较底层的DataStream API,用户在使用时需要设计大量的代码,而且DataStream本身也有需要设计上的问题,每次修改都需要修改所有的用户代码。阿里巴巴团队重新设计了流计算的Flink SQL并推回了社区。取名Flink SQL的原因,是因为我们希望和社区在API层保持统一,拥抱开源生态。
    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
图片描述
Flink有不同的State存储方式:内存和外部存储。在面对多种State如机器学习时内存无法满足存储要求,这时往往需要外存。早期的Flink设计存在缺陷:checkpoint会把所有的data压缩后,按照每一次checkpoint写入磁盘。随着State的不断增大,checkpoint读取和写入的数据量十分巨大。这会导致Job的checkpoint无法在1分钟内完成,这样在failover时就会造成大量的回退,造成较长延迟。

因此,我们提出了Incremental Checkpoint。概括的说就是增量地进行checkpoint。由于历史的checkpoint都已经完成,后面的checkpoint只需要将不同的数据放入存储,这样使checkpoint变得轻量,是的checkpoint可以在秒级完成,减小了failover的延迟。
3. 异步IO
图片描述
很多时候我们将数据放在外部存储,需要IO读取数据。传统的方式使用 Sync-IO,等待结果返回造成了较大延迟和CPU资源的浪费。为此,我们设计了Async-IO,允许异步地多线程地读取数据。当数据到达时系统时,调用callback处理数据,需要保序时我们提供buffer暂时保存先到的数据,等前部数据全部到达后批量发送。系统的整体性能根据buffer大小实现几十倍几百倍的提升,这极大地提升了单机的CPU利用率和数据吞吐。

以上所述大部分优化已经推回社区。
Flink SQL核心功能解密
1. 阿里完成Apache Flink SQL 80%研发工作
目前,Apache Flink SQL 80%的功能是阿里巴巴贡献的,包括两百个提交和上十万行代码。使用Flink SQL的原因是因为我们发现了底层API给用户的迁移、上线带来的极大不便。那么,我们又为什么选择SQL?原因如下:
1) SQL是描述性语言,SQL适合用来描述Job的需求。
2) SQL拥有比较好的优化框架,使用户专注于业务逻辑而不用关心State等,使用门槛低。
3) SQL易懂,适合不同领域的人使用。
4) SQL的API十分稳定,更新Engine时不用更换用户的Job。
5) 有些应用场景需要流式更新,批式验证,一个SQL同时进行批计算和流计算能带来巨大好处。批计算使用SQL,我们可以在此基础上达到批和流的统一。
2. 流处理 VS 批处理
两者的核心区别在于流处理的数据是无穷的而批处理的数据是有限的,这导致了其他三个区别:
1) 流处理不会结束并产生结果,批处理返回一个结果后结束。比方说,在双11结束后,批处理计算当天所有买家花费的总金额,而流处理需要追踪实时的交易金额,不停地计算。
2) 流计算需要做checkpoint并保留状态,机器宕机时大量Job需要回滚。批计算则不需要,它的输入数据往往是被持久化存储过的。
3) 流数据会不断更新,例如某一买家的花费总金额在不断变化,而批处理的数据是一天花费的总金额,是固定的。流数据会被更改而批数据不会。
3. QueryConfiguration
为了定义什么时候产生流计算结果和怎么保留状态,我们设计了Query Configuration,主要包括两个部分:
1. Latency SLA
定义了从数据产生到展现的延迟,如双11大屏是秒级别。

  1. State Retention/TTL
    流数据中的State不能一直存在,用户设置TTL(过期时间)来解决这个问题。
    这样,我们就消除了流和批的区别,实现统一。接下来我们需要考虑如何设计流式的SQL?
    4. Dynamic-Table实现流式SQL
    问题关键在于SQL在批处理中对表操作而流数据中并没有表。因此,我们创建了数据会随着时间变化的动态表。动态表是流的另一种表现形式,它们之间具有对偶性,即它们可以互相转换而不破坏数据的一致性。以下是一个例子:
    图片描述

如图,左边是输入流,我们为每一条数据产生Dynamic-Table,再将Table的变化用Changelog发送出去。随着数据的输入,两边的数据始终保持一致,这就证明了Dynamic-Table并没有丢失语义和数据。

这样,我们就可以根据表做SQL。我们将Stream理解为一个个Dynamic-Table,动态查询产生新的Table。值得一提的是,Dynamic-Table是虚拟的一层,并不需要存储落地。我们再来看一个例子:
图片描述
如图,当有输入流的时候我们进行连续查询。因为加入了连续查询的convert,左右两边的流已经发生了变换。总之动态表大大支撑了我们在流上执行连续查询SQL的能力。
5. 地球上不应该存在Stream SQL
通过例子我们发现有了Dynamic-Table不需要创造新的流式SQL,我们或许可以得出这样的结论:地球上不应该有流式SQL。保持ANSI SQL是我们构建Flink SQL的原则,ANSI SQL完全可以描述Stream SQL。
6. ANSI SQL功能实现
此外,我们需要实现ANSI SQL的所有功能。阿里巴巴内部实现了所有batch框架所需要的功能:DML、DDL、QueryConf、UDF/UDTF/UDAF、连接join、撤回、Window聚合、查询优化等等。现在详细介绍其中几项:
1) JOIN
流和动态表具有对偶性,一条SQL看似是Table的join,事实上是流的join。底层实现如下:
图片描述
两边都来数据时立刻产出一个结果,例如order 5和6在接近的时间内到达。一边数据先来会被存在State中并查询对面的State,不存在则不输出,直到对面数据来了之后产生结果。总之,两个流具有两个state,一边的数据到达后存下来等待另外一边数据,全部到达后inner join产生结果。另外,此图还引入了流和外部表的join。机器学习时大量的数据存储在HBase,连接HBase的操作实际上是在连接一个外部表,存在两个模式:
a) Look up方式。流数据到达时查询外部表得到结果。
b) 发送版本号给外部存储service,然后存储根据版本号给出结果。

值得一提的是,这个功能没有新的设计和Query语法的引入(完全按照SQL-2011的标准实现的)。同样,它在批计算上也适用。

2) Retraction
撤回是流计算的重要概念,举一个例子作解释:计算词频
图片描述
英语文本到达后计算出每个单词的频次。Hello World Bark每个单词出现一次,产生1——3的数据。当数据不断更新增加一个Hello时,我们在词频表插入2——1的数据,但这样就使频次为1的单词数出现了问题。出现问题的原因是因为流数据在不断更新,这时就需要我们能检测到这种错误并且拥有撤回机制。事实上,什么时候需要撤回可以使用SQL的Query Optimizer判断,它是用户无感知的。这就体现了SQL拥有天然优化框架的优势。
图片描述
如上图,第一个场景不需要撤回而第二个需要,这完全是由优化框架决定而非用户 。

3) Window聚合
图片描述
Window聚合是Flink SQL的一个重要能力。这个例子中我们对每一个小时的数据聚合进行统计。我们还支持了滑动窗和Session Window。Window的聚合事实上是按照Window的标准做一个个小batch处理。

4) 查询优化Query Optimization
除了添加新的功能,我们还做了大量的查询优化。例如在Async-join服务表时,我们会自动优化成Async状态的Table,改写最终的Runtime实现。我们还对Multiple joins进行merge,做了micro-batching。如果没有micro-batching,一条数据的到来就会伴随着读写IO。有了micro-batching之后我们可以用两次IO处理几千条数据。另外还有join/aggregate pushdown和TopN的优化,现在举例解释TopN优化:
图片描述
如上图,我们想取销售量前三的city,对用户的Query有两种解法:
a) 每有一条数据对保存的city进行排序,再截取前三个city,消耗大量存储计算资源
b) Query Optimizer会自动识别查询语句,只保存前面三个city,大大优化了计算和存储复杂度
阿里巴巴实时计算应用
1. 阿里云流计算开发平台
图片描述
该平台允许用户编写SQL,输入数据产生输出判断逻辑正确与否。正确后用户可以通过平台在集群上部署,完成后检测Job的运行情况。整个平台完成了所有实时计算的需求,集开发、Debug、上线、部署、运维于一体,大大加速了用户开发和上线的效率。值得一提的是,今年双11期间大部分Job均通过这个平台发布。阿里云,包括公共云、专有云也是通过这个平台输出给中小企业,让他们分享阿里巴巴实时计算的能力。
2. 阿里实时机器学习平台Porsche
图片描述
本平台是面向算法同学的UI拖拽平台,提供标准组件供他们开发复杂组件。使用者将组件按照规则连接后可生成图,图在经过优化翻译成SQL后可以上线和部署。本平台免去了算法同学学习SQL的成本,主要对内开放。
双11实时计算总结
图片描述
上图是阿里巴巴实时计算架构,底层是成千上百台的机器,之上是统一部署的Resource Management和Storage,还有Blink Runtime和Flink SQL,用户通过StreamCompute和Porsche平台提交Job,阿里内部几百个工程师已经提交了上千个Flink SQL Job。上述就是阿里巴巴实时计算的现状。
在实时计算的助力下,双11拿到1682亿的战果,实时计算的贡献主要体现在以下几点:

  1. 本次双11是互联网历史最大规模的并发,几十万的交易和支付的实时聚合操作全部是是由Blink计算带来的
  2. 3分01秒100亿数据的展现不仅需要高Data Base的高吞吐能力,还考验着实时计算的速度
  3. 算法平台得到了很好的搜索和推荐结果,取得了整体GMV的增长
评论