参考:http://spark.apache.org/docs/1.4.1/streaming-kafka-integration.html
Receiver与Direct方法相比,后者具有以下优点。
简化并行性
无需创建多个输入Kafka流和联合它们。使用directStream,Spark Streaming将创建与要消费的Kafka分区一样多的RDD分区,这将从Kafka并行读取数据。因此,Kafka和RDD分区之间存在一对一映射,这更容易理解和调整。
效率
在第一种方法中实现零数据丢失需要将数据存储在预写日志中,该日志进一步复制数据。这实际上是低效的,因为数据有效地被复制两次 - 一次是Kafka,另一次是写入提前日志。第二种方法消除了问题,因为没有接收器,因此不需要预写日志。只要您有足够的Kafka保留,消息可以从Kafka恢复。
Exactly-once语义
第一种方法使用Kafka的高级API在Zookeeper中存储消耗的偏移量。这是传统上消费Kafka数据的方式。虽然这种方法(与预写日志结合)可以确保零数据丢失(即至少一次语义),但是一些记录在一些故障下可能被消耗两次的机会很小。这是因为Spark Streaming可靠接收的数据与Zookeeper跟踪的偏移之间存在不一致。因此,在第二种方法中,我们使用Zookeeper的简单的Kafka API。偏移由Spark Streaming在其检查点内跟踪。这消除了Spark Streaming和Zookeeper / Kafka之间的不一致,所以每个记录被Spark Streaming有效地接收一次。为了实现输出结果的一次性语义,将数据保存到外部数据存储的输出操作必须是幂等的。