【极客说第一期】面向未来的数据处理--实时流处理平台的实践分享

随着移动设备、物联网设备的持续增长,流式数据呈现了爆发式增长,同时,越来越多的业务场景对数据处理的实时性有了更高的要求,基于离线批量计算的数据处理平台已经无法满足海量数据的实时处理需求,在这个背景下,各种实时流处理平台应运而生。

本次直播邀请到了负责腾讯云大数据产品的技术专家邹建平,来为我们介绍实时计算领域的最前沿的现状,通过一些应用案例,来介绍实时计算所面临的一些技术挑战,以及腾讯大数据产品是如何解决这些问题的。

如果对大数据感兴趣的话可以加Mike的微信交流

邹建平(以下称“Mike”)于09年加入腾讯,累积了近十年的互联网行业经验。最初负责QQ后台资料与存储服务。2013年负责SNG 后台框架研发和制定。2015年将孵化的通用存储系统推出腾讯云,做出先进的分布式Redis存储系统。近几年关注大数据相关的技术目前负责腾讯云大数据基础产品线的研发工作。负责产品包括:EMR弹性MapReduce、流计算服务、ElasticSearch服务和云端数据仓库Snova。

不知道大家有没有看过一部精彩的反恐电视剧叫《24小时》,大家应该对里面的主角杰克·鲍尔的表现叹为观止。

但最令人印象深刻的是在反恐总部大楼里在摄像头里对人脸进行识别和匹配,快速找到恐怖分子的踪迹。这次跟大家分享的就是在大数据领域里类似的高大上技术——流计算。

本次的分享主要分三个部分:

WHY WHAT HOW

希望大家能够通过这次分享能够了解流计算是什么,它能做什么,也会在中间跟大家介绍一些实际的操作案例。Mike还为大家带来了流计算内部的实现和技术特点做一些剖析。最后他还会为大家讲解腾讯云在做大数据产品的时候的一些优化思路。

首先我们们来回顾一些下大数据的历史。

什么是大数据?

“大数据(big data),指无法在一定时间范围内用常规软件工具进行捕捉、管理和处理的数据集合,是需要新处理模式才能具有更强的决策力、洞察发现力和流程优化能力的海量、高增长率和多样化的信息资产。”

——百度百科“大数据”

其实这个定义有点取巧。因为常规的软件工具其实一直都在发展,只能说大数据是让你处理起来比较难受的数据集合。通常我们会用四个'V’来描述大数据:

Volume-大容量

Variety- 数据类型多

Velocity-数据产生的速度快

Value-价值密度低

近年来随着收集以及产生数据的设备越来越多, 数据量也会产生爆炸式的增长。其实在很多业务场景里面,随着时间的流逝,数据的价值会非常快地降低。所以我们处理数据的速度变得尤为重要。

介绍流计算之前我们先来看看大数据领域里常见的批量计算的工作原理。这里涉及了几个步骤:首先要将数据从数据源装载到大数据的存储里面,比如说HDFS这样的分布式文件系统。然后我们就可以用不同特点的分析引擎,如Hive、Spark等引擎对这个数据集进行全量的分析,从而得到一个结果。

批量计算有几个特点:

1、分析的数据是有边界的,静态的,通常是存储在文件系统上的一系列的文件

2、分析工具更多关注的是吞吐量,而对分析结果的延迟并不太关注。通常在分钟级,或是小时得出结果就好

3、 需要分析员主动发起分析任务

那么流计算的场景是怎么样的呢?

案例1:

我们看一下下图,这是QQ实时在线的一个真实展示:

输入右下角url也可查看

通过这样可视化的数据,可以很直观地看到业务的一个整体状况。QQ的上下线频率是非常高的,那么我们怎样对海量的QQ上下线的登录日志进行分析呢?还要快速输出按地域或其他维度汇总结果呢?

如果按前面所提到先存再算的方法是无法快速实现这个任务的。

案例2:

公司随着业务的上涨,都会和恶意的用户做对抗。比如做刷量投票的、做数据窃取的,甚至还有进行网络攻击的。比如我们大家所熟知的12306网站,会有黄牛刷票。

假设我们已经拿到了这个应用的的实时访问日志,我们怎样才能快速分析这些日志,并判断是否发生攻击,已经找到攻击的根源呢?

攻击的时间是非常快速的,如果我们还是用以往的批处理的方式来分析所得日志的话,即使我们事后得到一个报告,也是没有任何意义的,攻击所带来的伤害已经发生了。这也是体现流计算实施的一个典型场景。

前面给大家介绍的两个例子,对实时性要求非常高的数据处理中,原来先存后算的架构是无法满足要求的。所以在流式计算里,我们是希望能够随着数据的流动,实时地进行加工处理,并实时地吐出计算结果。

流计算的特点是:

1、数据不是静态的,而是随着时间的推移逐步流入系统中的一个动态数据流,通常会有非常多的数据源,不同数据源的数据都是根据自己的特点,实时产生的,并且不同的数据源之间的数据流的顺序是无法控制的。如果要存放这些数据流,是无法得到完全一样的数据流的。同时,这些数据都是由数据流实时产生的,数据的流速也是无法预测的。

2、数据流进入系统之后,它本身的数据价值和生命周期较短,所以相比之下处理时延就显得格外重要。

3、流式数据分析的任务通常是长期运行的,采用一种事件驱动,或消息驱动的方式来输出分析结果。

对比总结:

这里跟大家分享一下大家对于流计算的一些误区:

误区一:有些同学可能会以为流计算是用资源代价换来的实时性,可能会觉得资源不够,就不采用流计算这种实时的方式处理数据。

这种想法已经过时啦,设计精良的流计算系统它并不会比批量计算耗费更多资源,例如我们前面提到的T+1的报表实现,我们在凌晨需要对前一天落地的数据进行分析计算。一方面,整个数据的存储量非常大,另一方面我们需要准备非常多的计算和存储资源来完成这次批量计算。还会经常因为资源或是其他的一些原因导致计算失败,需要重算。

而流计算不同,它可以把计算平摊在前一天的时间段里,来一点数据就进行数据增量的计算。也就是说,我们把一个大计算量的工作,平均分布到了每分每秒去进行。这样做不仅不需要运用到太多的资源,对于流计算来说,数据也无需落地,只需少量的资源就可以完成计算了。最终输出结果的速度也会快很多。

误区二:有同学认为流数据它只是输出数据比较快,但无法保证结果的准确性。这其实也是因为过去的一些流式计算的引擎在计算准确度方面做得不够好。比如对于机器故障,数据乱序等情况下,它的处理能力较弱,但目前已经不再是这样的状况了。

接下来我们来看看流计算更多的应用场景已经技术挑战。大家也可以看看自己的业务场景能不能引用流计算来进一步挖掘业务价值。

金融行业

金融行业领域中会产生出大量的数据,这些数据的时效性也较短,例如风控(信用卡诈骗、证券交易诈骗、保险诈骗等)都需要实时跟踪发现问题。在这种情况下,时间就是金钱,只有在毫秒级完成数据处理,才能避免风险为业务上带来的损失。

在量化投资,股票交易的情况中,熟悉的同学都知道,这种情况一般拼的就是低时延来吃差价,所以我们一方面需要大量的数据参与算法的模型计算,这样才能更好地得到交易决策,另一方面,需要快速得到决策结果,完成交易,才能实现盈利。

互联网广告行业

我们在浏览网页的时候会看到网页上会有点击付费的广告,对于广告商来说,最重要的业务目标,就是在什么时候插入广告,插入什么样的广告来获得最佳的点击效果。过去我们是需要用户的社交属性,兴趣爱好,个人属性或者浏览历史这种时效性较长的信息来进行分析决策。而现在越来越重要的是需要浏览者最近的一些行为特点,比如说他最近浏览过什么样的商品,或者最近的网页浏览记录以及他的地理位置,这些都是时效性很低的一些信息参与计算,才能更好地得到推荐效果。这种场景是需要用到实时流的计算的。

网络安全及设备监控领域

这种领域一般是需要对数据快速分析,进行自动化告警,来提升监控时效。

互联网领域

互联网领域是目前相当火热的一个领域,也是有着流计算数据的特点。例如智能交通,是通过传感器实时反应道路,车辆的状态,并且实时反应一定时间一定范围内的道路交通情况,以便有效地进行分流调度。

互联网产生的数据量非常大,这个行业的要求也需要实时进行计算反馈,否则在现实生活中会酿成严重的后果。

从批转向流所面临的挑战:

批计算模型经过多年的发展,目前已经有相对成熟的平台和技术了,能保证计算的可靠性和后瞻性。

而流计算就是为了解决批计算实时性的问题所出现的,相对来说是一个比较新的技术,面临着比较多的技术挑战。

低延迟 高吞吐

通常我们认为一个批处理会处理较多的数据,所以整体的吞吐性会更大,但我们缓冲一个批次,就会增大输出结果的时延。高吞吐和低延迟其实是一个矛盾的特点,我们要怎样做才能兼得两者呢?

准确性

作为一个分布式系统,计算节点发生宕机是个常态,批处理计算比较容易实现容错,因为文件是可以重复访问的,当某一个任务失败之后,重启任务就可以了。但在流处理系统中,由于数据源是无限的数据流,一个流处理任务执行几个月都是非常常见的,将所有的数据缓存是不现实的,对于流数据来说,怎么样在发生故障的情况下,保证计算的准确性呢?

易用性

流计算是提供给数据和算法工程师的一计算工具,怎么样让最终客户无需关注底层实现,提供一套易于开发易于复用面向数据的编程接口?

其实面对这些挑战流计算是有做出相应对策的,我们会在后面提到。

接下来我们进一步为大家介绍,什么是流计算?

流计算架构的演进过程:

Storm

Storm是twitter开源的一个分布式,是个可靠,容错的数据流系统。下图为Storm的处理程序,一般称之为拓扑。拓扑里面有Spout和Bolt两种模块。输入流由Spout负责接收,然后传输给Bolt。Bolt处理数据之后会传递给其他的Bolt继续处理,最终的Bolt会把数据落地到外部的存储,也就是计算结果落地到外部存储。

Storm第一个解决的问题就是将过去分布式服务里面需要处理的,发送接收消息序列号部署或收容的事情,都通过这些新的抽象的框架来实现。编程者可以只按照Storm的协议接口,编写数据处理的程序拓扑。也就是说,从过去通常的分布式服务里面的面向过程的编程,变成了面向数据的编程。

它第二个解决的问题是提供了一个Ack机制来解决容错问题,可以保证消息得到完整的处理。

Storm的优点:

框架简单灵活——它采用一种原生流模型,每个数据包在收到之后会立刻处理,并且立刻发送给下一条

时延低——通过Ack机制部分地解决了容错的问题。

成熟应用——Storm推出的比较早,它本身的应用相对来说也是比较成熟的

Storm的缺点:

编程接口简陋——它没有状态管理,需要用户来使用外部存储,如Redis来自行管理状态

容错无法支持exactly once——Storm的容错机制无法支持exactly once

吞吐量低——Ack机制虽然是异步的,但消息传递中,每一跳都会生成Ack包,会导致系统内部的通讯包量负载加重,而且中间的Ack blot相当于是额外的一个组件,随着包量增大需要部署非常多的Bolt,从整体看,是无法实现高吞吐量的。

Spark Streaming:微批处理框架的代表

它是把实时输入的数据流以时间片,比如说一秒为单位,切成块,每一块就是一个RDD。它会生成一个Spark Job来处理RDD,并且分批次提交到集群中去运行。运行每个Job的过程和真正的Spark任务没有什么区别。也就是说,Spark Streaming是以单位为计算,而不是以消息来计算。这样大大减少了Ack所需的开销,显著提高了吞吐量。

Spark Streaming的优点:

吞吐量高

容错支持exactly once——能够通过RDD的check point实现exactly once

生态活跃,外围工具多——Spark本身的生态非常活跃,编程接口也良好,拥有非常多算子的函数库,支持的外围工具也很多

Spark Streaming的缺点:

微批处理,延迟较高——由于采用微批处理模式,它的延迟只能到秒级,如果将微批改的更小,会消耗更多的管理开销

对流语言支持不够——采用的微批处理模式对于原生的源语言支持不够

Flink:分布式快照机制

Flink在近几年在流处理方面做了比较多创新的机制,也是目前非常火热的流计算框架。首先,Flink采用的内设Storm的原生流(即Nativie Flow)的处理模式,它在逻辑上是一条条消息处理的。一方面,Flink的延迟比较低,另一方面,它还可以优雅的实现一些窗口等流的语义。当然在底层传输上,Flink还是采用了固定的缓存块为单位来进行网络传输,所以说它在处理延迟和吞吐量上,Flink都能根据业务要求来进行灵活的调节。其次,Flink在容错方面,采用了分布式快照的机制。通过异步模式来保存状态到一个持久存储,并且这个过程不会阻塞消息的处理。同时他也实现了exactly once的容错级别。

三个产品对比如下:

整体来看,Flink在三者之间通过先进的流处理架构,以及友好的编程接口。在功能和性能方面都能达到比较好的平衡,目前的上升趋势也非常快。

从开发者角度来看,流计算又是如何使用的呢?

如何提供易用的编程接口是流计算面临的挑战之一。Flink是如何解决这个问题的呢?

上图是Flink的一个编程接口栈,最底层的API是Flink操作的源语,一般我们不会去用。第二层是Flink的核心API,其中DataStream API可以处理流式计算,DataSet API用来处理批次计算。第三第四层的Table API和SQL是两种基于核心API的扩展。它统一地对应流处理和批处理的任务。其中Table API是对应Scala和Java来使用。SQL则是通过一个标准的SQL语言来查询。

我们为什么要在流计算里面用SQL呢?

我们要理解一个流计算的处理过程,先来了解一下流处理中间的语义。

其中一个重要概念就是消息时间。首先在实时流处理里,时间是一个必要的因素,同时,如果没有明确的时间概念,最终流计算的结果也很难做到准确。

从上图的示例可以看到,从消息的采集端,也就是采集设备上,事件产生的时候会生成一个时间戳,我们把这个定义为Event Time,也就是事件时间。这个时间是精确的,另外有两个时间,一个是在流计算引擎的入口处的一个时间,另外一个是在具体执行的算子上的一个系统时间。这两个时间都不是精确的时间。因为消息传输的过程中间逻辑,可能会导致消息堆积,可能会导致数据晚到或是消息乱序,所以这两个时间,并不能准确反应消息的顺序。在业务场景需要得到一个精确时间的情况下,大家务必要记得使用Event Time。

第二个需要了解的语义是窗口,流计算处理过程中通常不会对历史上的所有数据来进行分析。一般都是定义一个数据集合,来进行统计汇总,输出计算结果。

在Flink里面支持丰富的窗口机制,有基于时间的,也有基于个数的,还可以按照会话来定义窗口。

下面我们通过一个对事件的求和的例子来看窗口的定义。

上图是一个翻转窗口。可以看出来他是有一个个固定的时间间隔,不重叠的一些窗口来代表一个数据集合,来做统计。假设图中每个输入流的消息,是某网页的PV数,那么我们这个翻转窗口就是按4秒为一个单位(以秒计算)来统计这个网页的总PV。

上图就是滑动窗口。这个例子就是每隔两秒钟对上一个四秒钟的一个窗口来做求和。在实际操作者,滑动窗口是非常常见的一种。比如可以用来实现热门商品的排行榜,或是需要一个较短间隔的时间来更新数据,再统计最近一段时间,比如一个小时或是更长时间的一个热门商品的统计信息。

还有一个就是会话窗口。这种窗口需要定义每个会话最长的idle时间,比如定义一个1分钟的idle时间。如1分钟以上没有对应消息过来,就会完成上一个窗口过来的统计,并输出一个结果。一般我们可以用这种窗口来进行一个用户的行为分析。比如说社交网站可以基于会话窗口来分析用户登录使用产品的一些情况。

有了这些丰富的窗口源语,我们只需要描述窗口类型,不需要实现具体窗口和触发的管理,就可以更方便地让我们进行流式处理的开发。

当然除了这些基本的概念,流计算里面还有很多计算的规则,这里就不做一一的说明了。

这里跟大家讲一个点击流统计的例子。给大家介绍一下载Flink里面SQL是如何进行开发的。这个点击流包括几个字段,第一个是事件产生的时间戳(即Event Time),第二个是用户名,第三个是访问网页的ID,以及用户的IP。

先看一个最简单的例子。通过一个实时的ETL,可以对输入的数据进行一个过滤的操作,比如上图中的例子就是把所有pageID为8212的点击给过滤出来

这里还有一个稍微复杂一点的例子。这个例子是按用户维度的一个PV操作。这里可以看到它是一个持续查询,所以当有新数据来的时候,可能会对已输出的数据更新,例如我们先收到Bob的数据,它通过SQL后,算出的结果是为1,但后面又新来了Bob的数据,需要它对原来的数据进行一个Update。最终需要我们做一个Upsert(update or insert)

的操作。

再举一个网站流量统计的例子。它对一个一分钟单滚的窗口里面的网页浏览进行汇总统计。

我们再来看看一个高阶一点的ETL,我们可以把一个输入流,和一个静态的维度表,做一个Joint。它就是通过流表和维表对IP地址转换到具体的城市。

同时我们也可以对多个输入流做Join,比如对广告投放的分析,上图输入流1描述的就是广告的投放时间,输入流2描述的是广告被点击的时间。通过双流对这两个输入流的分析,我们可以得出这个广告的投放效果。

虽然后面两个例子我们没有把SQL的代码发出来,其实它也跟普通的SQL一样,用它来描述流处理是非常简单的。只不过更厉害的是,Flink可以根据SQL来做优化,生成对应的程序,然后再部署到数百甚至上千的数据去进行处理。来实现高性能的分布式流计算,

刚刚我们介绍了Flink里面的编程接口,如果各位之前是用Storm来手写代码,一定会觉得SQL对于流式数据是相当的便利。下面我们再来深入了解一下Flink的内部实现。

流计算的实施准确性一直都是软肋,为了能够不败于批量计算,流计算首先就需要解决准确性的问题。

这个准确性代表什么呢?一方面是流计算在正常工作下,对同等的数据流,比如数据中可能存在乱序(在分布式系统中很常见)流计算能否得到跟批计算同样的结果。

另一方面就是无论在宕机或者其他失败的情况下,得到结果需要等于跟正常情况下得出的结果,一个输入对应一个输出,不会对消息进行多次处理或少处理,即exactly once。

那么Flink是如何解决这个问题的呢?

我们首先来看看Flink里面的状态。状态是指在一个计算的过程中,系统为了维持计算过程去需要保存的一个中间状态。比如我们对一个窗口数据进行统计计算,在触发计算前,需要hold一个数据集合。另外为了能从故障中恢复过来,重新接收外部数据流继续计算,我们需要保存当前数据流的一个位置,这个也是状态。另外还会用户自己定义的一些状态,需要长期保存的对象,这些状态都保存在哪儿呢?

在Flink里,状态是保存在算子的State Backend里。State Backend可以根据配置而有区别。可以是在JVM的堆内存中。也可以是超大状态,还可以保存在以文件系统为基础的RocksDB,KV数据库中。

一个分布式系统里有很多并行的算子,那么怎么样保证整个系统从一个一次的状态中恢复呢?Flink采用的是轻量级的快照机制,它会定时在所有数据源中插入一个叫Checkpoint Barrier,即快照栅栏的消息。每个栅栏消息都会分配一个ID。这些快照栅栏消息和其他用户的消息一样,在整个流处理的过程中流动,但是它不会被用户定义的业务逻辑来处理。每个快照栅栏会将它所在的数据流分成两部分。一个是本次的快照数据流,和下次的快照数据流。算子收到栅栏消息时,就会把自己当前的状态做一个快照,存储起来,并且将这个栅栏消息传递给下游的算子。当所有的算子都完成某个栅栏消息后,就表示这该分布式完成了一个整体的快照。这个有点像微批处理的方法,其中,两个栅栏之间所有的计算,我们都可以把它看做是整体的一个成功或是失败。这个算法优点在于,我们无需等待一批数据结束后才处理确认,而是让数据自然的流入,实时的计算结果,然后异步的快照也不会阻碍计算的主流程。

我们又要怎样实现端到端的精确一致呢?在Flink里面是通过一个二阶段提交的方式来实现的。它先做预提交,在中间如果有任何失败的情况,我们可以回滚到预提交的状态。最终成功时,再commit,将修改落地。

上图示例中的Flink机制里,有三个算子,分别是Source(从Kafka里读取的数据),Windows和Sink(将计算结果写入Kafka)。

当数据流在各个算子之间传递的时候,JobManager会在适当的时间往Source算子里插入快照栅栏,此时一个Checkpoint的预提交就开始了。这个快照栅栏会沿着处理路径往下流动。

每个算子收到栅栏之后会触发算子的State Backend作为一个当前状态的快照。比如Source这个算子,它提交当前流的offset作为一个状态数据。并将快照栅栏传递给下一跳Window算子。

当算子没有外部状态的时候,情况就比较简单了。其实Source是有外部状态,即Kafka,因为Kafka可以通过一个offset来读取它的历史数据。我们可以理解为我们只要保存好这个offset,后续对Kafka的一个读取就是一致的。

而对于这个例子中的Source和Window而言,它们都没有外部状态,Flink会自动在快照后完成提交,或者失败后放弃提交。

当算子存在一个外部状态的时候,比如这里面的Sink,它会把数据写到Kafka里面去,Sink除了要保存自己的状态之外,它还要对外部的Kafka进行一个预提交的动作。当快照栅栏流过所有的算子,也就表明预提交结束。这时候在State Backend里面,我们包含了所有算子的状态信息,也包括了外部状态的一个预提交信息。这样当后续出现任何问题的时候,就可以重新将整个分布式系统回滚到当前位置重做。

随后我们进入一个二阶段提交的commit阶段。JobManager会通知所有的快照说“快照已经完成啦”。这个阶段Source和Window没有外部状态,所以不需要做任何事情,而Sink它有个外部状态,所以它要对外部的Kafka系统做一个正式事务提交。通过这样的一个二阶段提交的方式,整个流计算分布式系统能保证事务的整体提交。或者当我们遇到故障的时候,可以撤销这个提交任务,实现从端到端的exactly once。

前面对比三个主流产品的时候,我们可以看到虽然Storm和Flink都是采用原生的流处理方式,实现消息处理的低时延,但Storm的吞吐量比较低,而Flink能够实现高吞吐,这个它又是如何做到的?

我们先对比看看流计算和批计算在消息传输上的不同。最左边是流计算的处理模式,每次处理一个消息(Storm就是采用这种模式),序列化到缓存中,然后通过网络传输到下个节点。

中间的批量计算则是在处理一个数据之后,数据化到缓存,缓存写满后,再保存到本地磁盘。当所有的数据都被处理之后,才开始将所有的数据传输到下一个节点。这样在网络传输上能够节约很多开销,吞吐量自然也比较高。

而最右侧的Flink采用了一个更灵活的传输方式。它同时支持这两种传输模型。它以一个固定的缓存块为单位来进行网络数据传输,用户可以通过设置这个缓存块的超时值来指定传输的时机。比如我们把超时值设为0,那么这时候它就能获得跟流计算一样的低延迟。如果将超时值设为无穷大或是某一个最大值,那么它就会以类似批处理的方式去进行传输。

总之,用户可以在Flink里面根据需求来灵活地权衡系统的延迟和吞吐量。Flink更妙的地方在于它把上层处理消息的逻辑和底层传输机制结合起来,所以我们改变缓存块的超时值的参数,只会影响整体的吞吐量和延迟,并不会影响上层对数据的处理逻辑。这个设计就要比Spark强很多。

虽然Flink生态目前还不如Spark,但是也在蓬勃发展,最近的版本也推的比较积极。上图是最近版本的一些优化特性。

说了这么多,Flink确实是一个不错的流计算框架。但作为开源产品的特点就是要真实落地,还是需要踩相当多的坑,需要相当的运维开发量和人力。在业务方面要如何快速地落地流计算服务呢?

这里跟大家简单介绍一下腾讯云的流计算产品。腾讯云的流计算产品是基于Flink内核进行云化之后构建的流计算服务。它与腾讯云上各种数据通道产品,数据存储产品,可视化产品都能够进行无缝对接。它具有全托管、开箱即用、弹性伸缩、安全可靠等特点。

介绍一下流计算产品在腾讯云生态里的数据流程。从数据生产开始,我们可以从云主机或者物联网通过流数据管道将数据接入。同时静态数据也能通过一些数据集成的工具,传输到云上各式各样的存储与数据产品上去。

这些动态和静态的流数据,可以在我们的流计算产品里面进行快速的分析,来实现业务逻辑。最终再通过流数据管道sink到各类的存储产品,或者直接输出到数据消费端。

基于这样的生态,我们可以一站式快速地进行流计算处理,构建上层各样的应用场景。

我们的流计算产品基于开源的Flink,并进行了强化和改进。目前Flink已经在腾讯服务得到了广泛的应用,包括实时ETL,用于内部数据管道的数据进行实时分拣;在QQ音乐等业务场景里用了实时的PV、UV统计;在微信支付领域做了实时监控的业务场景;除此之外,我们也可以采用CEP复杂的处理模式来对基于复杂规则的监控和处理。目前Flink在腾讯业务里面每天处理的数据量在数PB级别。

Flink在产品化的过程中,也做了大量的优化。

比如对于超多状态时的OOM的问题,当Key过多时,在算子上的内存压力会非常大。Flink会默认把状态保存在JVM堆内存的StateBackend中,通常采用这个方式能获得最佳的一个性能。随着状态数不断地增加,状态表容量越来越大,比如Key越来越多,Value越来越大,这时我们就需要作出一个抉择,比如一种方式就是说采用对状态来设置TTL,这样的确可以降低内存占用,但会牺牲准确度。但设置超时的话,TTL定时器本身也会占内存,如果占用数过多,同样会出现OOM。

如果我们不设置TTL的话,还是会耗尽内存,最终会导致任务失败。

Flink提供了一个RocksDB的State Backend,它可以将状态保存在磁盘上,从而支持超大的状态。但如果我们一开始直接配置使用RocksDB,是可以解决内存OOM的问题,但会严重影响非峰值的性能。比如时延会明显上升,吞吐量也会下降。

针对以上问题,我们设计了一种自适应的Backend,它可以解决这个问题。我们的当负载在对内存安全区域内,优先使用Heap,我们可以通过Heap来获得一个高性能。当负载逐步上升到临界点时,我们会通过一个机制,平滑迁移到RocksDB,避免出现OOM。当负载下降之后,我们又能逐步迁移回Heap,达到一个高性能的情况。整个过程无需人工干预,而且任意时刻发生故障,仍然可以从检查点恢复。

另外,虽然Flink里面本身也有一些监控告警机制,我们在云上的Flink做了更多的一些完善。我们对整个监控能力进行了精细化。还会自动做一些自动扩缩容的动作,来实现业务变化。

在云上服务,必须要保证客户的服务和数据的安全,所以我们在这几个层面实现了安全隔离。

资源隔离——在资源隔离方面我们通过独立集群,运行单一Job的方式,避免任务里面混合Job的干扰。

代码加密——所有用户的作业代码在传输过程中均加密存储,运维人员无法看到实际的代码数据。

安全守护——在事前,我们上传的UD包会经过直接码的一些静态检测。在事中,我们会对运行的作业做整体的一个安全检测,发现异常及时告警。在事后,我们会定期进行安全扫描,对系统日志进行安全审计。

云服务是需要持续优化和升级的,我们对于产品的规划特性,主要集中在更易用、更安全、更智能。

更易用——在目前开发库上持续加入更多通用的UDF函数。在安全的前提下,提供用户自定义的UDF机制,提升整个框架的扩展性。用户不仅可以在界面直接编写SQL来运行业务,也可以基于API编写业务代码,提交Jar到后台执行。这样既兼顾了SQL的易用性,也支持调用Flink的API的灵活性。用户还能通过拖拽链接,就能完成整个业务的编辑,无需写SQL或是写代码。

更安全——对于安全性要求高的用户来说,我们可以支持独占集群部署方式,保证服务是运行在他们的独立母机上,同时,在虚拟机和VPC的基础上,我们采用腾讯云的gaiastack来实现容器化部署,来实现更好的隔离性和配额管理。

更智能——我们会支持CEP,复杂事件处理来应对物联网的各种复杂场景。也会拓展机器在线学习的能力,给到更丰富的应用机器的学习接口。

总结

随着互联网、物联网和AI对实时计算的需求,流计算肯定会有越来越多的业务场景。Flink虽然是近期快速发展的一个流计算框架,但它的核心能力非常强大,是流计算领域里面一个强大的竞争者。腾讯云流计算产品基于Flink核心结合腾讯云内部业务流计算运营的一些经验,打造的流计算业务的云上产品,我们的目标是希望在云上生态,自动化运维,开发便利性方面能够给到开发者最好的体验。

今天的分享就到这里结束,感谢各位!

直播视频回顾:https://cloud.tencent.com/developer/salon/live-1083

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏程序员的SOD蜜

3篇有代表性的文章,有关存储过程的是是非非

这个问题争论很久了,用不用存储过程,有时甚至到了个人信仰的程度,我们还是来看看在知名技术社区前人对此的激烈讨论吧,顺便说说相关的东西。 1, “使用存储过程的好...

2449
来自专栏BestSDK

Java 9正式发布:这次Jigsaw终于来了

在历经多次跳票之后,Java 9 终于在千呼万唤中正式发布。从这个版本开始,Java 将每半年发布一个版本。作为霸占编程语言排行榜鳌头多年的老牌语言,Java ...

3955
来自专栏一名叫大蕉的程序员

浸入式大蕉Lab实训指南 No.106

现在呢,已经有11个小伙伴一起参与到校招Java训练实训的项目啦,大家可以一起参与进来,提你所想要的意见,比如说想练练算法啊,想练练具体的实战啊,想练练一些原理...

1173
来自专栏Golang语言社区

【十问十答】对话Go语言开发团队

o是谷歌推出的一门编程语言。熟悉Go语言的开发者都知道其弥补了C语言的不足并且保持了C的极简主义。使用Go编译的程序可以媲美C或C++代码的速度,而且更加安全、...

3486
来自专栏大数据挖掘DT机器学习

如何科学地蹭热点:用python爬虫获取热门微博评论并进行情感分析

甩锅の声明 1.本数据节选自新浪热门微博评论,不代表本人任何观点 2.本人不接受任何非技术交流类批评指责(夸我可以) 3.本次分析结果因技术问题存在一定误差(...

9885
来自专栏飞雪无情的博客

飞雪无情的博客Go语言、Android相关的十大热门文章

对于很多人来说,可能不明白我为什么写博客,写博客对于我来说,可能就像大家看电影一样,有时间就看看(写写)。对于我自己也是一些东西的总结,有时候通过写,才能加深理...

1061
来自专栏程序员的知识天地

为什么程序员总是发现不了自己的Bug? 程序员: 我不认识他啊

程序员在普通人的印象里是一份严(ku)谨(bi)的职业,也是一个被搞怪吐槽乐此不疲的职业,程序员们面对复杂的代码敲打电脑时连眉头都不会皱一下,但是有一个词却是他...

2051
来自专栏PPV课数据科学社区

【学习】切勿妄谈Hadoop,以及4个数据管道打造实践

时至今日,大数据这个概念已充斥了整个IT界,各种“搭载”了大数据技术的产品,各种用于处理大数据工具更如雨后的春笋触目皆是。同时,如果某个产品还没抱...

3187
来自专栏Java架构师进阶

Java程序员进阶路线-高级Java怎么炼成的

搞Java的弟兄们肯定都想要达到更高的境界,用更少的代码解决更多的问题,用更清晰的结构为可能的传承和维护做准备。想想当初自己摸着石头过河,也看过不少人介绍的学习...

1274
来自专栏java一日一条

Java 消亡了?不!原因在这…

年复一年,关于”Java消亡了?”的疑问频繁涌现,然而,通过所有外部表现来看,Java仍活着,并且在发展。尽管许多新语言各领风骚,开发语言排行榜(TIOBE)上...

722

扫码关注云+社区

领取腾讯云代金券