您的位置:首页 > 其它

流计算概述(一)

2016-05-14 10:32 274 查看

何为流计算?

批计算是已经存在一堆数据,需要用一次计算把这堆数据处理完。

而流计算是有一个源源不断的源头,是一个为了无止境的数据集设计的计算框架。

批计算处理的是有界的数据集,而流计算处理的是一个近似无界的数据集。

批计算更关注的是吞吐量,而流计算更关注的是低延时。
流计算还有个特性,就是增量性,数据源源不断的流入,对计算结果进行增量的更新,这给状态的容错带来了很大的复杂性(Exactly-Once)。

Lambda架构

Lambda架构是由Storm的作者Nathan Marz提出的一个实时大数据处理框架。

Lambda架构整合离线计算和实时计算,融合不可变性(Immunability),读写分离和复杂性隔离等一系列架构原则。

Lambda架构分为三层,Speed Layer(对应Storm)、Batch Layer(Hadoop)、查询层(使用KV存储)。

Speed Layer处理的数据是最近的增量数据流,Batch Layer处理的全体数据集。

Speed Layer为了效率,接收到新数据时不断更新Realtime View,而Batch Layer根据全体离线数据集直接得到Batch View。

Lambda架构将数据处理分解为Batch Layer和Speed Layer有如下优点(来自引用1):

容错性。Speed Layer中处理的数据也不断写入Batch Layer,当Batch Layer中重新计算的数据集包含Speed Layer处理的数据集后,当前的Realtime View就可以丢弃,这也就意味着Speed Layer处理中引入的错误,在Batch Layer重新计算时都可以得到修正。这点也可以看成是CAP理论中的最终一致性(Eventual Consistency)的体现。

复杂性隔离。Batch Layer处理的是离线数据,可以很好的掌控。Speed Layer采用增量算法处理实时数据,复杂性比Batch Layer要高很多。通过分开Batch Layer和Speed Layer,把复杂性隔离到Speed Layer,可以很好的提高整个系统的鲁棒性和可靠性。



(图来自DataArtisans Flink PPT)

聚合/增量:直接使用kv store来进行数据的聚合。

准确性:算两次,批计算来保证数据的准确。

批计算:一般24小时算一次。

Lambda架构的问题是:

1.大量冗余计算,浪费资源,流计算与批计算重复,批计算每次都跑全量。

2.由于直接使用KV store来作增量计算,各种瓶颈都在kv store上。

对此,Flink提出了一个新的思路,就是使用一个高吞吐、有状态的、有存储的、Exactly-Once、可增量计算的流计算引擎来解决这一切(all-streaming),甚至查询直接通过此引擎(目前Flink还没实现)。



(图来自DataArtisans Flink PPT)

Time Series Database用于查询已经与当前计算无关的历史值,用户直接查询引擎内部,大大减小了存储开销,也避免了瓶颈。

没有Lambda架构,也不用设计一套Hadoop的批处理系统,大大减小了开发和运维的工作。

性能与精确性

常驻任务

影响延时最大的就是是否为常驻任务的执行方式,之所以称Spark Streaming为准实时计算,就是因为它的每次计算都需要调度的,它使用了批计算的调度方式,是任务跟着数据走,而Storm/Flink等实时计算,是数据跟着任务走的方式。

打包

抛开外部依赖影响,对于吞吐影响最大的还是打包:

Spark Streaming的做法是直接切成离散流,把流计算转换为批计算。

Storm1.0的做法是对于其中的队列进行ThreadLocal的打包方式。

Flink的做法是点到点的打包,结合了内存池的使用,把数据汇聚成固定的segment。

更进一步的打包是使用列存和压缩。

序列化

序列化大概有三种方式:

Java自带:慢,序列化出来的数据量大。

Kryo序列化:比Java自带好,通用,可注册,不用管类型。Storm/Spark

Writable:最快、数据量小,但是反序列化时需要上层的Schema信息,并且需要用户自定义序列化。Flink和SparkSql中,会根据用户的泛型信息生成对应的Writable类,不需要用户手写了。一个良好的Writable实现,可以让序列化反序列化带来的消耗略同于直接的内存拷贝。



(图来自Flink官网博客)

如上图Flink测试所示,Writable序列化方式,不管对于数据传输还是聚合都能有效提高整体性能。

内存池

流计算中会产生大量的数据在内存中,当打包或发生拥塞时,这些数据躲过了YoungGC,进入了老年代,这会给GC带来很大的压力,而且Full GC也会导致时延不稳定。所以使用内存池,绕过JVM的GC系统或操作系统的内存分配,由于流计算是源源不断产生的,也不用担心碎片问题,Flink。

Exactly-Once

Storm中使用了Acker消息追踪的方式保证数据不丢,但是会导致消息量大增,Trident中把数据聚集成批来处理,大大减小了追踪的消息。

Flink中不追踪消息,只会进行时间间隔的checkpoint,当有出错时,直接全部重来。

Trident和Flink都是用Master来进行全局统一的分布式checkpoint。

Trident是checkpoint消息来触发数据的流入计算,而Flink使把checkpoint消息插入正常的数据处理之间。

Trident使用了两阶段来进行一致性的checkpoint,Flink是靠多版本来在正常的处理流程中进行checkpoint。

Trident依靠HBase来作增量操作,Flink目前是全量checkpoint。

Spark Streaming是直接使用了RDD(由于RDD粒度太大,后续也在自建状态的容错)。

其它

减少反射和多态(Codegen来解决)、Record粒度减少算随机值和拿系统时间等。

参考:
http://developer.51cto.com/art/201511/496529.htm https://cwiki.apache.org/confluence/display/FLINK/Stateful+Stream+Processing
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息