Spark Streaming VS Flink

2020-07-09 00:00:00 数据 时间 分区 提交 事件
本文从编程模型、任务调度、时间机制、Kafka 动态分区的感知、容错及处理语义、背压等几个方面对比 Spark Streaming 与 Flink,希望对有实时处理需求业务的企业端用户在框架选型有所启发。本文篇幅较长,建议先收藏~微信link:Spark Streaming VS Flink

#编程模型对比


运行角色

Spark Streaming 运行时的角色(standalone 模式)主要有:

  • Master:主要负责整体集群资源的管理和应用程序调度;
  • Worker:负责单个节点的资源管理,driver 和 executor 的启动等;
  • Driver:用户入口程序执行的地方,即 SparkContext 执行的地方,主要是 DAG 生成、stage 划分、task 生成及调度;
  • Executor:负责执行 task,反馈执行状态和执行结果。

Flink 运行时的角色(standalone 模式)主要有:

  • Jobmanager: 协调分布式执行,他们调度任务、协调 checkpoints、协调故障恢复等。至少有一个 JobManager。高可用情况下可以启动多个 JobManager,其中一个选举为 leader,其余为 standby;
  • Taskmanager: 负责执行具体的 tasks、缓存、交换数据流,至少有一个 TaskManager;
  • Slot: 每个 task slot 代表 TaskManager 的一个固定部分资源,Slot 的个数代表着 taskmanager 可并行执行的 task 数。


生态

图 1:Spark Streaming 生态,via Spark 官网
图 2:Flink 生态,via Flink官网

运行模型

Spark Streaming 是微批处理,运行的时候需要指定批处理的时间,每次运行 job 时处理一个批次的数据,流程如图 3 所示:

图 3,via Spark 官网

Flink 是基于事件驱动的,事件可以理解为消息。事件驱动的应用程序是一种状态应用程序,它会从一个或者多个流中注入事件,通过触发计算更新状态,或外部动作对注入的事件作出反应。

图 4,via Fink 官网

#编程模型对比

编程模型对比,主要是对比 flink 和 Spark Streaming 两者在代码编写上的区别。


Spark Streaming

Spark Streaming 与 kafka 的结合主要是两种模型:

  • 基于 receiver dstream;
  • 基于 direct dstream。

以上两种模型编程机构近似,只是在 api 和内部数据获取有些区别,新版本的已经取消了基于 receiver 这种模式,企业中通常采用基于 direct Dstream 的模式。

val Array(brokers, topics) = args//    创建一个批处理时间是2s的context    
   val sparkConf = new SparkConf().setAppName("DirectKafkaWordCount")    
   val ssc = new StreamingContext(sparkConf, Seconds(2))    
   //    使用broker和topic创建DirectStream    
   val topicsSet = topics.split(",").toSet    
   val kafkaParams = Map[String, String]("metadata.broker.list" -> brokers)    
   val messages = KafkaUtils.createDirectStream[String, String]( ssc, LocationStrategies.PreferConsistent,    ConsumerStrategies.Subscribe[String, String](topicsSet, kafkaParams))  
     // Get the lines, split them into words, count the words and print    
   val lines = messages.map(_.value)    
   val words = lines.flatMap(_.split(" "))    
   val wordCounts = words.map(x => (x, 1L)).reduceByKey(_ + _)   
    wordCounts.print()     //    启动流    
   ssc.start()    
   ssc.awaitTermination()

相关文章