SparkStreaming连接kafka的两种方式

     Spark对于Kafka的连接主要有两种方式,一种是DirectKafkaInputDStream,另外一种是KafkaInputDStream。

  【Receiver-based
    这种方法使用一个 Receiver 来接收数据。在该 Receiver 的实现中使用了 Kafka high-level consumer API。Receiver 从 kafka 接收的数据将被存储到 Spark executor 中,随后启动的 job 将处理这些数据。
    在默认配置下,该方法失败后会丢失数据(保存在 executor 内存里的数据在 application 失败后就没了),若要保证数据不丢失,需要启用 WAL(即预写日志至 HDFS、S3等),这样再失败后可以从日志文件中恢复数据。
  在该函数中,会新建一个 KafkaInputDStream对象,KafkaInputDStream继承于 ReceiverInputDStream。KafkaInputDStream实现了getReceiver方法,返回接收器的实例:

  def getReceiver(): Receiver[(K, V)] = {
    if (!useReliableReceiver) {
      //< 不启用 WAL
      new KafkaReceiver[K, V, U, T](kafkaParams, topics, storageLevel)
    } else {
      //< 启用 WAL
      new ReliableKafkaReceiver[K, V, U, T](kafkaParams, topics, storageLevel)
    }
  }

    Kafka Topic 的 partitions 与RDD 的 partitions 没有直接关系,不能一一对应。如果增加 topic 的 partition 个数的话仅仅会增加单个 Receiver 接收数据的线程数。事实上,使用这种方法只会在一个 executor 上启用一个 Receiver,该 Receiver 包含一个线程池,线程池的线程个数与所有 topics 的 partitions 个数总和一致,每条线程接收一个 topic 的一个 partition 的数据。而并不会增加处理数据时的并行度。
    启用了WAL的话,为能将接收到的数据将以 log 的方式在指定的存储系统备份一份,需要指定输入数据的存储等级为
`StorageLevel.MEMORY_AND_DISK_SER

StorageLevel.MEMORY_AND_DISK_SER_2`

  【Direct-based】
自 Spark-1.3.0 起,提供了不需要 Receiver 的方法。替代了使用 receivers 来接收数据,该方法定期查询每个 topic+partition 的 lastest offset,并据此决定每个 batch 要接收的 offsets 范围。
    该方式相比使用 Receiver 的方式有以下好处:

    1.简化并行:不再需要创建多个 kafka input DStream 然后再 union 这些 input DStream。使用 directStream,Spark Streaming会创建与 Kafka partitions 相同数量的 paritions 的 RDD,RDD 的 partition与 Kafka 的 partition 一一对应,这样更易于理解及调优

    2.高效:在方式一中要保证数据零丢失需要启用 WAL(预写日志),这会占用更多空间。而在方式二中,可以直接从 Kafka 指定的 topic 的指定 offsets 处恢复数据,不需要使用 WAL

    3.恰好一次语义保证:基于Receiver方式使用了 Kafka 的 high level API 来在 Zookeeper 中存储已消费的 offsets。这在某些情况下会导致一些数据被消费两次,比如 streaming app 在处理某个 batch 内已接受到的数据的过程中挂掉,但是数据已经处理了一部分,但这种情况下无法将已处理数据的 offsets 更新到 Zookeeper 中,下次重启时,这批数据将再次被消费且处理。基于direct的方式,使用kafka的简单api,Spark Streaming自己就负责追踪消费的offset,并保存在checkpoint中。Spark自己一定是同步的,因此可以保证数据是消费一次且仅消费一次。这种方式中,只要将 output 操作和保存 offsets 操作封装成一个原子操作就能避免失败后的重复消费和处理,从而达到恰好一次的语义(Exactly-once)

你可能感兴趣的:(大数据)