【转】Spark Streaming和Kafka整合开发指南

基于Receivers的方法

这个方法使用了Receivers来接收数据。Receivers的实现使用到Kafka高层次的消费者API。对于所有的Receivers,接收到的数据将会保存在Spark executors中,然后由Spark Streaming启动的Job来处理这些数据。

  然而,在默认的配置下,这种方法在失败的情况下会丢失数据,为了保证零数据丢失,你可以在Spark Streaming中使用WAL日志,这是在Spark 1.2.0才引入的功能,这使得我们可以将接收到的数据保存到WAL中(WAL日志可以存储在HDFS上),所以在失败的时候,我们可以从WAL中恢复,而不至于丢失数据。

  下面,我将介绍如何使用这种方法来接收数据。

  1、引入依赖。

  对于Scala和Java项目,你可以在你的pom.xml文件引入以下依赖:

<dependency>

  <groupId>org.apache.spark</groupId>

  <artifactId>spark-streaming-kafka_2.10</artifactId>

  <version>1.3.0</version>

</dependency>

  如果你是使用SBT,可以这么引入:

libraryDependencies += "org.apache.spark" % "spark-streaming-kafka_2.10" % "1.3.0"

  2、编程

  在Streaming程序中,引入KafkaUtils,并创建一个输入DStream:

import org.apache.spark.streaming.kafka._

val kafkaStream = KafkaUtils.createStream(streamingContext,

    [ZK quorum], [consumer group id], [per-topic number of Kafka partitions to consume])

  在创建DStream的时候,你也可以指定数据的Key和Value类型,并指定相应的解码类。

  需要注意的是:
  1、Kafka中Topic的分区和Spark Streaming生成的RDD中分区不是一个概念。所以,在KafkaUtils.createStream()增加特定主题分区数仅仅是增加一个receiver中消费Topic的线程数。并不增加Spark并行处理数据的数量;

  2、对于不同的Group和tpoic我们可以使用多个receivers创建不同的DStreams来并行接收数据;

  3、如果你启用了WAL,这些接收到的数据将会被持久化到日志中,因此,我们需要将storage level 设置为StorageLevel.MEMORY_AND_DISK_SER ,也就是:

KafkaUtils.createStream(..., StorageLevel.MEMORY_AND_DISK_SER)

  3、部署

  对应任何的Spark 应用,我们都是用spark-submit来启动你的应用程序,对于Scala和Java用户,如果你使用的是SBT或者是Maven,你可以将spark-streaming-kafka_2.10及其依赖打包进应用程序的Jar文件中,并确保spark-core_2.10和 spark-streaming_2.10标记为provided,因为它们在Spark 安装包中已经存在:

<dependency>

          <groupId>org.apache.spark</groupId>

          <artifactId>spark-streaming_2.10</artifactId>

          <version>1.3.0</version>

          <scope>provided</scope>

</dependency>

<dependency>

          <groupId>org.apache.spark</groupId>

          <artifactId>spark-core_2.10</artifactId>

          <version>1.3.0</version>

          <scope>provided</scope>

</dependency>

然后使用spark-submit来启动你的应用程序。

  当然,你也可以不在应用程序Jar文件中打包spark-streaming-kafka_2.10及其依赖,我们可以在spark-submit后面加上--jars参数也可以运行你的程序:

[[email protected] spark]$ spark-1.3.0-bin-2.6.0/bin/spark-submit  --master yarn-cluster

    --class iteblog.KafkaTest 

    --jars lib/spark-streaming-kafka_2.10-1.3.0.jar,

    lib/spark-streaming_2.10-1.3.0.jar,

    lib/kafka_2.10-0.8.1.1.jar,lib/zkclient-0.3.jar,

    lib/metrics-core-2.2.0.jar ./iteblog-1.0-SNAPSHOT.jar

下面是一个完整的例子:

object KafkaWordCount {

  def main(args: Array[String]) {

    if (args.length < 4) {

      System.err.println("Usage: KafkaWordCount <zkQuorum> <group> <topics> <numThreads>")

      System.exit(1)

    }

    StreamingExamples.setStreamingLogLevels()

    val Array(zkQuorum, group, topics, numThreads) = args

    val sparkConf = new SparkConf().setAppName("KafkaWordCount")

    val ssc =  new StreamingContext(sparkConf, Seconds(2))

    ssc.checkpoint("checkpoint")

    val topicMap = topics.split(",").map((_,numThreads.toInt)).toMap

    val lines = KafkaUtils.createStream(ssc, zkQuorum, group, topicMap).map(_._2)

    val words = lines.flatMap(_.split(" "))

    val wordCounts = words.map(x => (x, 1L))

      .reduceByKeyAndWindow(_ __ _, Minutes(10), Seconds(2), 2)

    wordCounts.print()

    ssc.start()

    ssc.awaitTermination()

  }

}

Direct的方法

和基于Receiver接收数据不一样,这种方式定期地从Kafka的topic+partition中查询最新的偏移量,再根据定义的偏移量范围在每个batch里面处理数据。当作业需要处理的数据来临时,spark通过调用Kafka的简单消费者API读取一定范围的数据。这个特性目前还处于试验阶段,而且仅仅在Scala和Java语言中提供相应的API。

  和基于Receiver方式相比,这种方式主要有一些几个优点:
  (1)、简化并行。我们不需要创建多个Kafka 输入流,然后union他们。而使用directStream,Spark Streaming将会创建和Kafka分区一样的RDD分区个数,而且会从Kafka并行地读取数据,也就是说Spark分区将会和Kafka分区有一一对应的关系,这对我们来说很容易理解和使用;

  (2)、高效。第一种实现零数据丢失是通过将数据预先保存在WAL中,这将会复制一遍数据,这种方式实际上很不高效,因为这导致了数据被拷贝两次:一次是被Kafka复制;另一次是写到WAL中。但是本文介绍的方法因为没有Receiver,从而消除了这个问题,所以不需要WAL日志;

  (3)、恰好一次语义(Exactly-once semantics)。《Spark Streaming和Kafka整合开发指南(一)》文章中通过使用Kafka高层次的API把偏移量写入Zookeeper中,这是读取Kafka中数据的传统方法。虽然这种方法可以保证零数据丢失,但是还是存在一些情况导致数据会丢失,因为在失败情况下通过Spark Streaming读取偏移量和Zookeeper中存储的偏移量可能不一致。而本文提到的方法是通过Kafka低层次的API,并没有使用到Zookeeper,偏移量仅仅被Spark Streaming保存在Checkpoint中。这就消除了Spark Streaming和Zookeeper中偏移量的不一致,而且可以保证每个记录仅仅被Spark Streaming读取一次,即使是出现故障。

  但是本方法唯一的坏处就是没有更新Zookeeper中的偏移量,所以基于Zookeeper的Kafka监控工具将会无法显示消费的状况。然而你可以通过Spark提供的API手动地将偏移量写入到Zookeeper中。如何使用呢?其实和方法一差不多

1、引入依赖。

  对于Scala和Java项目,你可以在你的pom.xml文件引入以下依赖:

<dependency>

  <groupId>org.apache.spark</groupId>

  <artifactId>spark-streaming-kafka_2.10</artifactId>

  <version>1.3.0</version>

</dependency>

  如果你是使用SBT,可以这么引入:

libraryDependencies += "org.apache.spark" % "spark-streaming-kafka_2.10" % "1.3.0"

  2、编程

  在Streaming应用程序代码中,引入KafkaUtils ,并创建DStream输入流:

import org.apache.spark.streaming.kafka._

val directKafkaStream = KafkaUtils.createDirectStream[

    [key class], [value class], [key decoder class], [value decoder class] ](

    streamingContext, [map of Kafka parameters], [set of topics to consume])

  在 Kafka parameters参数中,你必须指定 metadata.broker.list或者bootstrap.servers参数。在默认情况下,Spark Streaming将会使用最大的偏移量来读取Kafka每个分区的数据。如果你配置了auto.offset.reset为smallest,那么它将会从最小的偏移量开始消费。

  当然,你也可以使用KafkaUtils.createDirectStream的另一个版本从任意的位置消费数据。如果你想回去每个batch中Kafka的偏移量,你可以如下操作:

directKafkaStream.foreachRDD { rdd =>

    val offsetRanges = rdd.asInstanceOf[HasOffsetRanges]

    // offsetRanges.length = # of Kafka partitions being consumed

    ...

}

你可以通过这种方式来手动地更新Zookeeper里面的偏移量,使得基于Zookeeper偏移量的Kafka监控工具可以使用。

  还有一点需要注意,因为这里介绍的方法没有使用到Receiver,所以Spark中关于spark.streaming.receiver.*相关的配置参数将不会对创建DStreams 有影响。我们可以使用spark.streaming.kafka.*参数进行配置。

  3、部署

  对应任何的Spark 应用,我们都是用spark-submit来启动你的应用程序,对于Scala和Java用户,如果你使用的是SBT或者是Maven,你可以将spark-streaming-kafka_2.10及其依赖打包进应用程序的Jar文件中,并确保spark-core_2.10和 spark-streaming_2.10标记为provided,因为它们在Spark 安装包中已经存在:

<dependency>

          <groupId>org.apache.spark</groupId>

          <artifactId>spark-streaming_2.10</artifactId>

          <version>1.3.0</version>

          <scope>provided</scope>

</dependency>

<dependency>

          <groupId>org.apache.spark</groupId>

          <artifactId>spark-core_2.10</artifactId>

          <version>1.3.0</version>

          <scope>provided</scope>

</dependency>

然后使用spark-submit来启动你的应用程序。

时间: 2024-10-07 22:26:05

【转】Spark Streaming和Kafka整合开发指南的相关文章

Spark Streaming和Kafka整合开发指南(一)

Apache Kafka是一个分布式的消息发布-订阅系统.可以说,任何实时大数据处理工具缺少与Kafka整合都是不完整的.本文将介绍如何使用Spark Streaming从Kafka中接收数据,这里将会介绍两种方法:(1).使用Receivers和Kafka高层次的API:(2).使用Direct API,这是使用低层次的KafkaAPI,并没有使用到Receivers,是Spark 1.3.0中开始引入的.这两种方法有不同的编程模型,性能特点和语义担保.下文将会一一介绍. 基于Receiver

Spark Streaming和Kafka整合保证数据零丢失

当我们正确地部署好Spark Streaming,我们就可以使用Spark Streaming提供的零数据丢失机制.为了体验这个关键的特性,你需要满足以下几个先决条件: 1.输入的数据来自可靠的数据源和可靠的接收器: 2.应用程序的metadata被application的driver持久化了(checkpointed ); 3.启用了WAL特性(Write ahead log). 下面我将简单地介绍这些先决条件. 可靠的数据源和可靠的接收器 对于一些输入数据源(比如Kafka),Spark S

第89课:Spark Streaming on Kafka解析和安装实战

本课分2部分讲解: 第一部分,讲解Kafka的概念.架构和用例场景: 第二部分,讲解Kafka的安装和实战. 由于时间关系,今天的课程只讲到如何用官网的例子验证Kafka的安装是否成功.后续课程会接着讲解如何集成Spark Streaming和Kafka. 一.Kafka的概念.架构和用例场景 http://kafka.apache.org/documentation.html#introdution 1.Kafka的概念 Apache Kafka是分布式发布-订阅消息系统.它最初由Linked

第89讲:Spark Streaming on Kafka解析和安装实战

本课分2部分讲解: 第一部分,讲解Kafka的概念.架构和用例场景: 第二部分,讲解Kafka的安装和实战. 由于时间关系,今天的课程只讲到如何用官网的例子验证Kafka的安装是否成功.后续课程会接着讲解如何集成Spark Streaming和Kafka. 一.Kafka的概念.架构和用例场景 http://kafka.apache.org/documentation.html#introdution 1.Kafka的概念 Apache Kafka是分布式发布-订阅消息系统.它最初由Linked

spark streaming集成kafka

Kakfa起初是由LinkedIn公司开发的一个分布式的消息系统,后成为Apache的一部分,它使用Scala编写,以可水平扩展和高吞吐率而被广泛使用.目前越来越多的开源分布式处理系统如Cloudera.Apache Storm.Spark等都支持与Kafka集成. Spark streaming集成kafka是企业应用中最为常见的一种场景. 一.安装kafka 参考文档: http://kafka.apache.org/quickstart#quickstart_createtopic 1.安

SBT 构建 spark streaming集成kafka (scala版本)

前言: 最近在研究spark 还有 kafka , 想通过kafka端获取的数据,利用spark streaming进行一些计算,但搭建整个环境着实不易,故特此写下该过程,分享给大家,希望大家可以少走点弯路,能帮到大家! 环境准备:    操作系统 : ubuntu14.04 LTS hadoop 2.7.1   伪分布式搭建 sbt-0.13.9 kafka_2.11-0.8.2.2 spark-1.3.1-bin-hadoop2.6 scala 版本 : 2.10.4 注: 请重视版本问题,

Spark Streaming使用Kafka保证数据零丢失

来自: https://community.qingcloud.com/topic/344/spark-streaming使用kafka保证数据零丢失 spark streaming从1.2开始提供了数据的零丢失,想享受这个特性,需要满足如下条件: 数据输入需要可靠的sources和可靠的receivers 应用metadata必须通过应用driver checkpoint WAL(write ahead log) 可靠的sources和receivers spark streaming可以通过

spark streaming 对接kafka记录

spark streaming 对接kafka 有两种方式: 参考: http://group.jobbole.com/15559/ http://blog.csdn.net/kwu_ganymede/article/details/50314901 Approach 1: Receiver-based Approach 基于receiver的方案: 这种方式使用Receiver来获取数据.Receiver是使用Kafka的高层次Consumer API来实现的.receiver从Kafka中获

Spark Streaming、Kafka结合Spark JDBC External DataSouces处理案例

场景:使用Spark Streaming接收Kafka发送过来的数据与关系型数据库中的表进行相关的查询操作: Kafka发送过来的数据格式为:id.name.cityId,分隔符为tab 1 zhangsan 1 2 lisi 1 3 wangwu 2 4 zhaoliu 3 MySQL的表city结构为:id int, name varchar 1 bj 2 sz 3 sh 本案例的结果为:select s.id, s.name, s.cityId, c.name from student s