ApacheKafka与SparkStreaming的两种整合方法及其优缺点

Apache Kafka与Spark Streaming的两种整合方法及其优缺点

译文
作者:陈峻编译 2018-10-24 09:00:26

大数据

Kafka

Spark 我们在将Apache Kafka与Spark Streaming整合的实战过程中,一般可以选用两种方面来配置Spark Streaming,并接收来自Kafka的数据。第一种是利用接收器和Kafka的高级API;而第二种新的方法则并不使用接收器。这两种方法在性能特征和语义保持上,有着不同的编程模式。

10余年的四方台网站建设经验,针对设计、前端、开发、售后、文案、推广等六对一服务,响应快,48小时及时工作处理。成都全网营销的优势是能够根据用户设备显示端的尺寸不同,自动调整四方台建站的显示方式,使网站能够适用不同显示终端,在浏览器中调整网站的宽度,无论在任何一种浏览器上浏览网站,都能展现优雅布局与设计,从而大程度地提升浏览体验。成都创新互联公司从事“四方台网站设计”,“四方台网站推广”以来,每个客户项目都认真落实执行。

【51CTO.com快译】Kafka与Spark Streaming的整合

我们在将Apache Kafka与Spark Streaming整合的实战过程中,一般可以选用两种方面来配置Spark Streaming,并接收来自Kafka的数据。***种是利用接收器和Kafka的高级API;而第二种新的方法则并不使用接收器。这两种方法在性能特征和语义保持上,有着不同的编程模式。

下面让我们来详细探究一下这两种方法。

一、基于接收器的方法

此法运用接收器(Receiver)来接收数据。而接收器是利用Kafka的高级消费者(consumer)API来实现的。此外,接收到的数据会被存储在Spark的各个执行器(executor)中。然后由Spark Streaming所启动的作业来处理数据。

但是在出现失败时,这种方法的默认配置可能会丢失数据。因此,我们必须在Spark Streaming中额外地启用预写日志(write-ahead log),以确保数据的零丢失。它将所有接收到的Kafka数据,同步地保存到某个分布式文件系统的预写日志中,以便在出现失败时恢复所有的数据。

下面,我们将讨论如何在Kafka-Spark Streaming应用中,使用该基于接收器的方法。

1.链接

现在,先将您的Kafka Streaming应用与如下的artifact相链接,对于Scala和Java类型的应用,我们会用到SBT(Simple Build Tool)和Maven(一种构建工具)的各种项目定义。

 

  
 
 
 
  1. groupId = org.apache.spark 
  2. artifactId = spark-streaming-kafka-0-8_2.11 
  3. version = 2.2.0 

而对于Python类型的应用,我们必须在部署自己的应用时,额外添加上述库、及其各种依赖项。

2.编程

随后,我们在streaming应用的代码中,通过导入KafkaUtils,来创建一项DStream输入:

 

  
 
 
 
  1. import org.apache.spark.streaming.kafka._ 
  2. val kafkaStream = KafkaUtils.createStream(streamingContext, 
  3.     [ZK quorum], [consumer group id], [per-topic number of Kafka partitions to consume]) 

同样,通过使用createStream的各种变形方式,我们可以制定出不同的键/值类,及其对应的解码类。

3.部署

通常情况下,对于任何Spark应用而言,您都可以使用spark-submit来发布自己的应用。当然,就具体的Scala、Java和Python应用来说,它们在细节上会略有不同。

其中,由于Python应用缺少SBT和Maven的项目管理,我们可以使用–packages spark-streaming-kafka-0-8_2.11、及其各个依赖项,直接添加到spark-submit处。

  
 
 
 
  1. ./bin/spark-submit --packages org.apache.spark:spark-streaming-kafka-0-8_2.11:2.2.0 ... 

此外,我们还可以从Maven的存储库中下载Maven artifact的spark-streaming-Kafka-0-8-assembly所对应的JAR包,然后使用-jars,将其添加到spark-submit处。

二、直接方法(无接收器)

在基于接收器的方法之后,新的一种无接收器式“直接”方法诞生了。此法提供了更强大的端到端保证。它定期查询Kafka在每个topic+分区(partition)中的***偏移量,而不再使用接收器去接收数据。同时,它也定义了要在每个批次中处理的不同偏移范围。特别是在那些处理数据的作业被启动时,其简单消费者(consumer)API就会被用于读取Kafka中预定义的偏移范围。可见,此过程类似于从某个文件系统中读取各种文件。

注:针对Scala和Java API,Spark在其1.3版本中引入了此功能;而针对Python API,它在其1.4版本中同样引入了该功能。

下面,我们将讨论如何在Streaming应用中使用该方法,并深入了解更多有关消费者API的链接:

1.链接

当然,这种方法仅被Scala和Java应用所支持,并且通过如下artifact来链接STB和Maven项目。

 

  
 
 
 
  1. groupId = org.apache.spark 
  2. artifactId = spark-streaming-kafka-0-8_2.11 
  3. version = 2.2.0 

2.编程

随后,我们在Streaming应用的代码中,通过导入KafkaUtils,来创建一项DStream输入:

 

  
 
 
 
  1. import org.apache.spark.streaming.kafka._ 
  2. val directKafkaStream = KafkaUtils.createDirectStream[ 
  3.     [key class], [value class], [key decoder class], [value decoder class] ]( 
  4.     streamingContext, [map of Kafka parameters], [set of topics to consume]) 

我们必须在Kafka的参数中,指定metadata.broker.list或bootstrap.servers,以便它能够在默认情况下,从各个Kafka分区的***偏移量开始消费。当然,如果您在Kafka的参数中将auto.offset.reset配置为最小,那么它就会从最小的偏移开始消费。

此外,通过使用KafkaUtils.createDirectStream的各种变形方式,我们能够从任意偏移量开始消费。当然,我们也可以在每一个批次中,按照如下的方式去消费Kafka的偏移量。

 

  
 
 
 
  1. // Hold a reference to the current offset ranges, so downstream can use it 
  2. var offsetRanges = Array.empty[OffsetRange] 
  3. directKafkaStream.transform { rdd => 
  4.   offsetRanges = rdd.asInstanceOf[HasOffsetRanges].offsetRanges 
  5.   rdd 
  6. }.map { 
  7.           ... 
  8. }.foreachRDD { rdd => 
  9.   for (o <- offsetRanges) { 
  10.     println(s"${o.topic} ${o.partition} ${o.fromOffset} ${o.untilOffset}") 
  11.   } 
  12.   ... 

如果您想使用基于Zookeeper的Kafka监控工具(https://data-flair.training/blogs/zookeeper-in-kafka/),来显示Streaming应用的进度,那么您也可以自行将其更新到Zookeeper中。

3.部署

该方面的部署过程与基于接收器的方法类似,此处就不赘述了。

三、直接方法的优点

就Spark Streaming与Kafka整合的角度而言,第二种方法较***种方法有着如下的优点:

1.简化并行

无需创建与合并多个输入的Kafka Streams(https://data-flair.training/blogs/kafka-streams/)。但是,Sparking Streaming会创建同样多的RDD(Resilient Distributed Datasets,弹性分布式数据集)分区,以供多个Kafka分区使用直接的方法进行消费。这些分区也会并行地从Kafka中读取数据。因此我们可以说:在Kafka和RDD分区之间存在更容易被理解和调整的、一对一的映射关系。

2.效率

为了实现数据的零丢失,***种方法需要将数据存储在预写日志中,以供进一步复制数据。此方法的效率实际上是比较低的,因为数据被Kafka和预写日志实际复制了两次。而在直接的方法中,由于没有了接收器,因此不需要预先写入日志,此问题也就迎刃而解了。只要您拥有足够多的Kafka数据保留,各种消息就能够从Kafka中被恢复回来。

3.准确到位的语义

在***种方法中,我们使用Kafka的高级API,在Zookeeper中存储被消费的偏移量。然而,这种传统的、从Kafka中消费数据的方式,虽然能够确保数据的零丢失,但是在某些失败情况下,数据可能会被小概率地消费两次。实际上,这种情况源自那些被Spark Streaming可靠地接收到的数据,与Zookeeper跟踪到的偏移量之间所产生的不一致。因此在第二种方法中,我们不再使用Zookeeper,而只是使用一个简单的Kafka API。Spark Streaming通过其各个检查点(checkpoints),来跟踪不同的偏移量,籍此消除了Spark Streaming和Zookeeper之间的不一致性。

可见,就算出现了失败的情况,那些记录也都会被Spark Streaming有效地、准确地一次性接收。它能够确保我们的输出操作,即:将数据保存到外部数据存储库时,各种保存结果和偏移量的幂等性、和原子事务性,这同时也有助于实现准确到位的语义。

不过,这种方法也有一个缺点:由于它不会在Zookeeper中更新各种偏移量,因此那些基于Zookeeper的Kafka监控工具将无法显示进度。当然,您也可以自行访问每个批次中由此方法处理的偏移量,并更新到Zookeeper之中。

结论

通过上述讨论,我们学到了Kafka与Spark Streaming整合的全体概念。同时,我们也讨论了Kafka-Spark Streaming的两种不同配置方法:接收器方法和直接方法,以及直接方法的几项优点。

原文标题:Apache Kafka + Spark Streaming Integration,作者:Rinu Gour

【51CTO译稿,合作站点转载请注明原文译者和出处为51CTO.com】

网站标题:ApacheKafka与SparkStreaming的两种整合方法及其优缺点
本文地址:http://www.shufengxianlan.com/qtweb/news18/29718.html

网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联