标签归档:Apache Flink

轻松掌握阿里Blink SQL关键技术及实现原理

内容来源:2018 年 6 月 15 日,阿里巴巴高级技术专家孙金城(金竹)在“阿里云流计算杭州峰会”进行《Blink SQL关键技术及实现原理》演讲分享。IT 大咖说(微信id:itdakashuo)作为独家视频合作方,经主办方和讲者审阅授权发布。

获取嘉宾演讲视频及PPT:suo.im/4ZZ9PO

摘要

本次演讲主要介绍Blink SQL的几个关键技术,以及实现原理,并通过两个实例来阐述具体的功能效果。

六个特点和背景介绍

(Blink架构)

Blink作为一个纯流式的计算平台,具备秒级甚至毫秒级的延时,能够快速容错,比如在某个计算节点挂掉的时候可以快速恢复。它还支持动态扩容,针对流计算场景做了大量优化,具备高吞吐和高资源利用率的极致性能,同时解决了非常明显的数据乱序的问题,并且支持大数据量的流计算请求。

什么是BlinkSQL

BlinkSQL是在FlinkSQL基础上新增了大量的丰富功能和性能优化。SQL作为声明式的可优化的语言具备很大的优势,Blink的SQL查询优化器会对用户SQL进行优化,制定最优的执行计划以获取高性能。同时SQL易于理解,用它编写的业务逻辑清晰明了。

虽然SQL被更多的用于批处理,但是在流计算场景下同样也适用。从处理的数据集合来看,流处理的数据是无穷的,而批处理面对的是有限集合。从内部处理逻辑来看,批处理是单次作业,流处理的运作持续不断,并且会对历史数据进行修正。

上图展示的是一个携带时间戳和用户名的点击事件流,我们先对这些事件流进行流式统计,同时在最后的流事件上触发批计算。流计算中每接收一个数据都会触发一个结果,可以看到最后的事件无论是在流还是批上计算结果都是6。这说明只要SQL语句和数据源相同,流和批的计算结果就不会存在差异。相同的SQL在流和批这两种模式下,语义相同,最终结果就会一致。

五个概念和一个实现

流表对偶性

流表对偶性是指流表转换信息无损,具有对偶性。

传统数据库表有两个最明显的特征schema和data,流同样也有schema和data,另外还有一个重要属性time,随着时间的推移数据会不断涌入流中。

上图中在对一个用户名关系表进行DML操作,每insert一条语句后会触发一个统计查询,按user维度分组做count统计。图中插入第一条数据后,输入的是(mary , 1),接着再插入数据就会输出(Bob , 2)、(mary , 1),在进行操作的时候虽然没有显示的涉及到时间,但是其实都隐含了一个操作时间,从本质上讲,传统数据库表中也有time属性。

这样的话单就属性来看数据库表和流式就是一样的,我们可以把一个具体的表可以看做是流上某一时间切片的数据。

动态表

随着时间变化不断变化的表可以称之为动态表,这个概念不适用于传统数据库表。因为传统数据库有着事务控制,在执行查询的那一刻表的内容不会有变化,所以是静态表。而流上的数据即使在查询的时候也还是在变化,数据进行回放的时候,可以Replay成一张动态表,而动态表的changelog又形成了流。

持续查询 & 增量计算

持续查询是流计算特有的,不断更新结果,执行运行的查询。它是保证低延迟和数据更新的基础。

增量计算是一种可以提高流计算性能的计算实现,流上的每一条数据都会利用上一条计算结果进行聚合和统计计算。

Early Emit & Retraction

Early Emit是为了保证流计算的低延时需求,将计算结果尽早的流到下游。由于流计算的结果会随着时间改变,因此即使上游的计算结果在发出的那一刻是正确的,但是随后又会产生新的结果,这样下游当初接收的数据就是陈旧的。Retraction解决的就是这一问题,为了保障流计算语义正确性,将Early Emit的计算结果撤回并发出正确的计算结果。

双流JOIN实现

对于双流join,由于流上的流速不一定相同,有可能会出现查询的时候数据不存在,后续才出现数据的情况。上图是Blink的join方案,将左边的数据存储在一个state中,并且对右边的state做join查询。同理右边的数据处理也是一样,先存储在一个state中,然后join查询另一个state。

这样的流程存在一个问题,即在join另一边的state时可能没有数据,传统数据库的做法是将它留空,而流上的数据会实时变化,此刻没有join数据不代表下一刻还没有。这就需要利用Retraction机制,在正确数据到来的时候撤回之前的空数据并重新填入新数据,如上图所示。

总结

这里我们对这5个概念做下总结。首先有了流表对偶性,流表转换才有理论支撑,流表才能互转;有了动态表的概念,SQL才能作用于流上,才能进行持续查询;有了持续查询的概念,才能真正解释流式SQL计算永不结束,结果永远在更新;增量计算配合查询和引擎优化,才有了Blink的高性能;Early Emit和Retraction,一个使用Blink有了无限逼近秒级毫秒级的低延时,一个保证了流式语义的正确性。

两个案例和总结

案例1 – 无key热点

对于有多区块的数据源,每个区块都会由对应的节点来处理。理想情况下每个节点的处理量相同,负载是均衡的,但是实际场景下可能会出现不均衡处理的情况,比如某个节点无法处理所负载的量,对此我们要将该节点无法处理的部分分配给其他节点。

Blink为此提供了Dynamic Rebalance,它会感知下游节点的压力情况,进而将繁忙的节点处理不过来的数据分发给空闲节点。需要注意的是目前的这种情况是无key节点,这意味着数据在哪个节点处理都可以。

案例2 – keyed热点

Keyed就是对数据按key分组,相同的key必须到同一个节点上。这时候虽然框架也能感知到反压,但是不可以使用反压机制再分配节点上的数据。

这时候要用到Local-Global Aggregation,数据热点优化的另一个方案,也是由系统内部的查询优化器来完成,让用户无感知。它会先将每个节点的数据在本地进行Local Agg聚合,图中不同的颜色表示不同的key,他们在本地会做局部的聚合,这样原先上游的4条记录就变成的1条,很大程度上减轻了下游节点的压力。

总结

Blink SQL拥有标准的语义,完全支持标准的ANSI SQL,同时有丰富的功能,比如UDF、JOIN、双流JOIN等。有更优的性能,在ANSI SQL的各个语法功能基础上做了大量的性能优化。提供了一站式平台,集开发、测试、部署、监控、升级于一体,让用户专注于自己的业务。

原文链接:https://juejin.im/post/5b8609a6e51d4538d12ca085

那些年我们用过的流计算框架

数据时代,从数据中获取业务需要的信息才能创造价值,这类工作就需要计算框架来完成。传统的数据处理流程中,总是先收集数据,然后将数据放到DB中。当人们需要的时候通过DB对数据做query,得到答案或进行相关的处理。这样看起来虽然非常合理,但是结果却非常紧凑,尤其是在一些实时搜索应用环境中的某些具体问题,类似于MapReduce方式的离线处理并不能很好地解决。

基于此,一种新的数据计算结构—流计算方式出现了,它可以很好地对大规模流动数据在不断变化的运动过程中实时地进行分析,捕捉到可能有用的信息,并把结果发送到下一计算节点。 什么是流计算? 时下,对信息高时效性、可操作性的需求不断增长,这要求软件系统在更少的时间内能处理更多的数据。传统的大数据处理模型将在线事务处理和离线分析从时序上将两者完全分割开来,但显然该架构目前已经越来越落后于人们对于大数据实时处理的需求。 流计算的产生即来源于对于上述数据加工时效性的严苛需求:数据的业务价值随着时间的流失而迅速降低,因此在数据发生后必须尽快对其进行计算和处理。而传统的大数据处理模式对于数据加工均遵循传统日清日毕模式,即以小时甚至以天为计算周期对当前数据进行累计并处理,显然这类处理方式无法满足数据实时计算的需求。在诸如实时大数据分析、风控预警、实时预测、金融交易等诸多业务场景领域,批量(或者说离线)处理对于上述对于数据处理时延要求苛刻的应用领域而言是完全无法胜任其业务需求的。而流计算作为一类针对流数据的实时计算模型,可有效地缩短全链路数据流时延、实时化计算逻辑、平摊计算成本,最终有效满足实时处理大数据的业务需求。 通常而言,流计算具备三大类特点:

  • 实时(realtime)且无界(unbounded)的数据流。流计算面对计算的 是实时且流式的,流数据是按照时间发生顺序地被流计算订阅和消费。且由于数据发生的持续性,数据流将长久且持续地集成进入流计算系统。例如,对于网站的访问点击日志流,只要网站不关闭其点击日志流将一直不停产生并进入流计算系统。因此,对于流系统而言,数据是实时且不终止(无界)的。
  • 持续(continuos)且高效的计算。流计算是一种”事件触发”的计算模式,触发源就是上述的无界流式数据。一旦有新的流数据进入流计算,流计算立刻发起并进行一次计算任务,因此整个流计算是持续进行的计算。
  • 流式(streaming)且实时的数据集成。流数据触发一次流计算的计算结果,可以被直接写入目的数据存储,例如将计算后的报表数据直接写入RDS进行报表展示。因此流数据的计算结果可以类似流式数据一样持续写入目的数据存储。

概念区分 明确了流处理概念的同时,一些其他的概念也需要了解:离线计算、批处理计算、实时计算。 离线计算 正如前文所述,离线计算就是在计算开始前已知所有输入数据,输入数据不会产生变化,且在解决一个问题后就要立即得出结果的前提下进行的计算。在大数据中属于数据的计算部分,在该部分中与离线计算对应的则是实时计算。一般来说,离线计算具有数据量巨大且保存时间长;在大量数据上进行复杂的批量运算;数据在计算之前已经完全到位,不会发生变化;能够方便的查询批量计算的结果等特点。 常用的离线计算框架包括有:

  • Hadoop,适用于离线大批量数据处理,不需要多次迭代。
  • Spark,适用于离线快速的处理,不能用于处理需要长期保存的数据;适用于多次迭代的计算模型。
  • MapReduce,Hadoop框架最核心的设计就是HDFS和MapReduce。HDFS为海量的数据提供了存储,MapReduce则为海量的数据提供了计算,它适用于大规模数据集的并行运算。
  • HDFS,这个Hadoop分布式文件系统能提供高吞吐量的数据访问,非常适合大规模数据集上的应用。

批量计算 批量计算是一种批量、高时延、主动发起的计算。目前绝大部分传统数据计算和数据分析服务均是基于批量数据处理模型: 使用ETL系统或者OLTP系统进行构造数据存储,在线的数据服务(包括Ad-Hoc查询、DashBoard等服务)通过构造SQL语言访问上述数据存储并取得分析结果。这套数据处理的方法论伴随着关系型数据库在工业界的演进而被广泛采用。传统的批量数据处理模型传统的批量数据处理通常基于如下处理模型:

  • 使用ETL系统或者OLTP系统构造原始的数据存储,以提供给后续的数据服务进行数据分析和数据计算。
  • 用户/系统主动发起一个计算作业(例如=Hive的SQL作业)并向上述数据系统进行请求。
  • 计算结果返回,计算作业完成后将数据以结果集形式返回用户。

实时计算 实时计算一般都是针对海量数据进行的,一般要求为秒级。实时计算主要分为两块:数据的实时入库、数据的实时计算。主要应用的场景有:

  • 数据源是实时的不间断的,要求用户的响应时间也是实时的(比如对于大型网站的流式数据:网站的访问PV/UV、用户访问了什么内容、搜索了什么内容等,实时的数据计算和分析可以动态实时地刷新用户访问数据,展示网站实时流量的变化情况,分析每天各小时的流量和用户分布情况)。
  • 数据量大且无法或没必要预算,但要求对用户的响应时间是实时的。比如说:昨天来自每个省份不同性别的访问量分布,昨天来自每个省份不同性别不同年龄不同职业不同名族的访问量分布。

对于实时计算来说。首先需要解决数据的就是实时接收的问题,在网络带宽、接收性能、安全防控等情况下,如何实现海量并发数据平稳接收具有很大挑战。 离线=批量?实时=流式? 习惯上我们认为离线和批量等价;实时和流式等价,但其实这种观点并不完全正确。假设一种情况:当我们拥有一个非常强大的硬件系统,可以毫秒级的处理Gb级别的数据,那么批量计算也可以毫秒级得到统计结果(当然这种情况非常极端,目前不可能),那我们还能说它是离线计算吗? 所以说离线和实时应该指的是:数据处理的延迟;批量和流式指的是:数据处理的方式。两者并没有必然的关系。事实上Spark streaming就是采用小批量(batch)的方式来实现实时计算。

可以参考链接:https://www.oreilly.com/ideas/the-world-beyond-batch-streaming-101。作者是Google实时计算的负责人,里面阐述了他对批量和实时的理解,并且作者认为批量计算只是流式计算的子集,一个设计良好的流式系统完全可以替代批量系统。

流计算产品盘点 目前流式计算是业界研究的一个热点。早期的代表系统有IBM的System S,它是一个完整的计算架构,通过“stream computing”技术,可以对stream形式的数据进行real-time的分析。“最初的系统拥有大约800个微处理器,但IBM称,根据需求,这个数字也有可能上万。研究者讲到,其中最关键的部分是System S软件,它可以将任务分开,比如分为图像识别和文本识别,然后将处理后的结果碎片组成完整的答案。IBM实验室高性能流运算项目的负责人Nagui Halim谈到:System S是一个全新的运算模式,它的灵活性和速度颇具优势。而与传统系统相比,它的方式更加智能化,可以适当转变,以适用其需要解决的问题。 近年来Twitter、LinkedIn等公司相继开源了流式计算系统Storm、Kafka等,加上Yahoo!之前开源的S4,流式计算研究在互联网领域持续升温。下面来盘点一些业界常见的流计算产品。 Storm Storm是一个分布式的、容错的实时计算系统,做作为最早的一个实时计算框架,早期应用于各大互联网公司。在Storm出现之前,进行实时处理是非常痛苦的事情,我们主要的时间都花在关注往哪里发消息,从哪里接收消息,消息如何序列化,真正的业务逻辑只占了源代码的一小部分。一个应用程序的逻辑运行在很多worker上,但这些worker需要各自单独部署,还需要部署消息队列。最大问题是系统很脆弱,而且不是容错的:需要自己保证消息队列和worker进程工作正常。Storm具有编程简单、高性能,低延迟、分布式、可扩展、容错、消息不丢失等特点。

但是,Storm没有提供exactly once的功能,并且开启ack功能后又会严重影响吞吐,所以会给大家一种印象:流式系统只适合吞吐相对较小的、低延迟不精确的计算;而精确的计算则需要由批处理系统来完成,所以出现了Lambda架构,同时运行两个系统:一个流式,一个批量,用批量计算的精确性来弥补流式计算的不足,但是这个架构存在一个问题就是需要同时维护两套系统,代价比较大。 Spark streaming

Spark streaming采用小批量的方式,提高了吞吐性能。Spark streaming批量读取数据源中的数据,然后把每个batch转化成内部的RDD。Spark streaming以batch为单位进行计算),而不是以record为单位,大大减少了ack所需的开销,显著满足了高吞吐、低延迟的要求,同时也提供exactly once功能。但也因为处理数据的粒度变大,导致Spark streaming的数据延时不如Storm,Spark streaming是秒级返回结果(与设置的batch间隔有关),Storm则是毫秒级。 Flink Flink是一个针对流数据和批数据的分布式处理引擎,主要由Java代码实现。对 Flink 而言,其所要处理的主要场景就是流数据,批数据只是流数据的一个极限特例而已。Flink 可以支持本地的快速迭代,以及一些环形的迭代任务,并且可以定制化内存管理。在这点,如果要对比 Flink 和 Spark 的话,Flink 并没有将内存完全交给应用层。这也是为什么 Spark 相对于 Flink,更容易出现 OOM 的原因(out of memory)。就框架本身与应用场景来说,Flink 更相似与 Storm。

Apache Flink的特点有:低延迟的流处理器;丰富的API能够帮助程序员快速开发流数据应用;灵活的操作状态和流窗口;高效的流与数据的容错。 Apache Kafka Kafka是一个分布式的、分区的、多复本的日志提交服务,它通过一种独一无二的设计提供了一个消息系统的功能。实现流处理最基本的方法是使用Kafka API读取输入数据流进行处理,并产生输出数据流。这个过程可以用任何编程语言实现。这种方法比较简单,易于操作,适应于任何有Kafka客户端的语言。

Apache Samza Samza处理数据流时,会分别按次处理每条收到的消息。Samza的流单位既不是元组,也不是Dstream,而是一条条消息。在Samza中,数据流被切分开来,每个部分都由一组只读消息的有序数列构成,而这些消息每条都有一个特定的ID。该系统还支持批处理,即逐次处理同一个数据流分区的多条消息。Samza的执行与数据流模块都是可插拔式的,尽管Samza的特色是依赖Hadoop的Yarn(另一种资源调度器)和Apache Kafka。

Heron Twitter由于本身的业务特性,对实时性有着强烈的需求。因此在流计算上投入了大量的资源进行开发。第一代流处理系统Storm发布以后得到了广泛的关注和应用。根据Storm在实践中遇到的性能、规模、可用性等方面的问题,Twitter又开发了第二代流处理系统——Heron,并在2016年将它开源。

目前的Heron支持Aurora、YARN、Mesos以及EC2,而Kubernetes和Docker等目前正在开发中。通过可扩展插件Heron Scheduler,用户可以根据不同的需求及实际情况选择相应的运行平台,从而达到多平台资源管理器的支持。 编译自互联网,参考资料:

  • http://www.csdn.net/article/2014-06-12/2820196-Storm
  • http://www.jianshu.com/p/16323566f3c6
  • http://www.jianshu.com/u/a9196e920278
  • https://help.aliyun.com/document_detail/49924.html
  • https://help.aliyun.com/document_detail/49926.html
  • https://baike.baidu.com/

原文发布于微信公众号 – CSDN技术头条(CSDN_Tech)

原文发表时间:2017-10-23