一. 业务现状分析
1.需求
统计某视频学习平台主站上每个(指定)课程访问的客户端(PC/APP)、地域信息分布。
用户每一次在站点上发生点击或搜索是都会产生日志,如何从这个日志里面提取出来这些地域和终端信息呢?
地域信息:由IP进行转换;
客户端:通过useragent获取
以上两个操作都是可以采用离线的方式(Spark/MapReduce)进行统计的。
2.实现步骤
提取出课程编号(URL)、useragent、IP信息,进行相应的统计分析操作:Spark/MapReduce。
3.项目架构(基于Hadoop的实现方案)
日志收集:flume收集实时点击日志,存入HDFS(可以采用分区:天/小时)。
离线分析:MapReduce/Spark。
统计结果图形化展示:ECharts、HUE、Zeppelin等类似的开源框架。
4.存在的问题
如果业务要求按小时级别进行统计,采用离线的方式必然是没有问题的,能够处理的过来;
如果按10min进行统计,可能启一个MapReduce来处理也处理的过来;
如果再小(如5min),估计就够呛了,因为每次提交作业到yarn上执行时,一般情况下都会经历一个accept状态(资源申请、等待的过程),这个地方很可能就会花掉30~40s左右的时间,跑5min力度的话可能就有点吃力了;
如果再严格一点,按1min进行统计,基本上采用mapreduce是不现实的;
如果再低,改成秒级别,这样的统计如果想采用mapreduce/spark这种离线批处理来处理,肯定不现实。
主要因为mapreduce时效性不是太好,延时性比较高,mapreduce是适合做离线批处理的,它不关注数据量大小,只要能存储得下,计算能力足够,都没有问题,但是如果想让它快速的将一个作业处理完并显示结果,mapreduce是无法做到的。mapreduce的map task和reduce task都是进程级别,每次都需要启动进程,运行完后销毁进程,启动和销毁都会占用一定的时间,虽然可以采用jvm的复用,让它多个task跑在一个jvm上,但不管怎样,它的执行模型(计算模型)导致了它并不适合做实时的计算(中间的结果还需要落地磁盘等等)。
当前如果采用mapreduce/spark sql已经没办法满足需求,对于存在的问题,如何解决?---->实时流处理框架。
二. 实时流处理的产生背景
1.时效性高
业务营销特别是对于推荐,如电信行业各种流量包/套餐推荐、营销的时机通常情况下是转瞬即逝的,如何在第一时间分析出用户的需求,从而针对性的开展营销活动,对时效性的高要求决定了数据不可能像传统业务分析即离线分析那样以批量的方式按照数据模型进行一个一个的计算,这必然是不现实的,等你把结果计算出来,很可能营销时机就已经过了,从而无法为公司带来业务、创造价值。
2.数据量大
对于时效性的要求就决定了必须以实时的方式来处理原始数据,但原始数据的价值密度往往是很低的,但数据量却很大(大数据4V特性,现在好像是5V了)。
如何以实时的方式来处理大量数据,并同时保证数据的准确性?以上两点即实时流处理产生背景的重要两条,当然也有其它的点,如数据量变化是非常迅速的,越来越多的业务数据它当中存在着数据量暴增/暴减的场景,比如说在电信行业,它的计费详单(包括上网日志的信令数据)暴增/暴减的场景是非常多的,那么如何设计一个扩展性比较好的实时处理系统,其实难度也是比较大的。
还有一个,业务的生命周期比较短,越来越多的案例表明,一种营销业务,它的生命周期是越来越短的,由原来的可能1个月,到现在的2周、1天或几个小时都是非常有可能的。
而且业务发展变化是越来越快的,需要有一种很好的计算引擎去支撑业务的快速发展以及业务的快速实现。
这几点即描述了实时流式处理框架的一个诞生背景,只有诞生了一个比较稳定的扩展性好的实时流处理才能针对于大量的原始数据(价值密度较低),从中提取出我们所需要的东西,进而创造更大的价值。
三.实时流处理概述
1.实时计算
实时即意味着响应时间较短,实时计算即响应时间受到实时约束一种计算。离线批处理它是没有时间限制的,只要把结果跑出来,但是实时计算肯定是不允许的,它的实时约束往往比较短,一般都是秒级别,甚至到毫秒级别,而且其对延迟性的要求要比较低。
2.流式计算
流式计算即在不断产生的数据流上面进行计算,数据是源源不断的进来的。对于流式计算来说,它的数据流是由基本的数据(一行一行记录)所构成的,这个数据流是不断产生、没有尽头的,计算结果也一样,它是不断的进行计算,不断的进行更新,7*24h不停止的。
3.实时流式计算
以上两点加起来即实时流式计算,即在不断产生的数据流上面进行实时计算。它输入的数据是不断产生的,它的计算结果所产生的数据相对于数据的流入是实时的,统计分析的结果产生的时间相对于数据流入的时间两者的对比是实时的。而离线计算不是这样的,离线计算是对前面一段时间产生的数据,统一来进行处理,它对于处理时间的长短是没有约束的。
四.离线计算与实时计算对比
1.数据来源
离线:一般情况下是HDFS上的一些历史数据,他的数据量级比较大。
实时:一般情况下不会是HDFS上的数据,大部分场景是从消息队列(kafka)里面过来的。它其实是从实时新增/实时修改记录过来的某一笔数据。
2.处理过程
离线:如Hadoop的MapReduce,通常情况下分两步(map+reduce来进行两个阶段的构成)。
实时:Spark(DStream/SS(结构化流))。
3.处理速度
离线:速度比较慢,因为它的数据量级比较大。
实时:必然是要快速拿到结果。
4.进程角度
离线:启动时进程开始(map task/reduce task),计算完以后进程销毁。
实时:7*24h不停的进行计算,只要有新数据进来,它都要进行相应的统计分析操作。
五.实时流处理框架对比
因为通常情况下一种业务场景可能由多个框架都能够满足需求,典型的如离线计算(MapReduce/Spark)。同理,流处理也是有一些框架能够完成类似的功能的。
1.Apache Storm
Apache Storm是一个免费开源的分布式实时计算系统。storm是真正实时的流处理框架,只要是来一条数据,它立刻就执行了。
2.Apache Spark Streaming
Spark Streaming是Spark中的一个字模块,是专门用来处理流式计算的。spark streaming和storm有一个本质的区别,众所周知,spark core是可以用来进行离线处理的,其实spark streaming它就是基于spark的API做了一个扩展,它并不会像storm那样,每一次处理一个数据,它的原理是把数据按照设置好的时间间隔(2s/5s/1min)拆分成一个一个小的批处理,所以说spark streaming严格意义上来说并不是一个实时处理框架,而是一个微批处理框架。
3.IBM Stream
4.Yahoo! S4
5.LinkedIn Kafka
众所周知,kafka是一个消息队列,其实kafka已经不仅仅是一个消息队列那么简单了,它是一个非常系统的框架,kafka里面也是包括实时流处理的。kafka是一个分布式的流处理平台,它能够比较高效的进行流数据处理,而且可以适用于实时计算。所以说kafka也自带了流处理的功能,但这个功能在国内用的不多。
6.Flink
Flink是一个可扩展的流式和批处理的数据处理框架。它的用法跟spark是比较类似的。
在生产上,1和2是用的最多的,如果要做到真正的实时计算的话,就用storm,能够忍受微批处理的话,那么spark streaming也是非常不错的一个技术选型。
六.实时流处理架构与技术选型
假设以用户行为日志来说,用户通过手机(APP)/浏览器查看了某一个新闻或在电商网站上点击了某一个商品,不管是点击还是搜索等等类似的用户行为,它都会有一个请求,会有一条日志信息记录到webserver(Ngix/Tomcat到Ngix集群做负载均衡)上面去。
假设日志信息是记录到/var/log/access.log这个日志里面去的,用户的每一个请求都会在webserver(webserver集群)上有日志产生。
虽然日志已经到了webserver上面了,但是要进行相应的数据处理的话,很遗憾,是处理不了的。因为通常情况下webserver是在Hadoop集群之外的,所以还需要做一件事情,把实时产生的这些日志通过一个框架给它收集过来才行,上图的第二步即一个数据采集的过程,可以通过一个叫做flume的分布式日志收集框架将实时的日志收集过来。
那么能不能把flume收集过来的日志直接丢到实时流处理系统(spark streaming/storm)上面来呢?其实是可以的,但是一般情况下不会这么做,因为一般情况下访问行为晚上是高峰期,凌晨是低峰期,如果高峰期的时候将收集过来的日志直接怼到流处理系统上,那么流处理系统很可能是会崩掉的,扛不住这个压力。所以,中间一般情况下会加一层消息队列,flume收集过来的日志,先放到kafka里面去,然后实时流处理框架再从kafka这个消息队列里面把要的消息取出来消费掉,目的就是为了起到一个很好的缓冲作用,这一层对于实时流处理来说是一个很好的保护机制。所以一般在生产上实时流处理都是flume和kafka对接流处理进行使用。
既然现在数据(访问日志)已经到了实时流处理框架里面来了,那么它的业务逻辑应该就在这一个部分完成。完成之后把结果写入到关系型数据库或NoSQL数据库(HBase/ES)都是可以的。写入到数据库还不够,得有一个前端的展示,最终通过一个可视化的展示将统计结果展示出来(典型的如双十一的订单营业额/销量的展示)。
上面即一个整个的实时流处理架构和技术选型。