kafka版本说明
0.8版本有Receiver和Direct模式
0.10以后只保留了direct模式
receiver接收方式
Receiver是使用Kafka的高层次Consumer API来实现的。
Receiver方式从Kafka中获取的数据都是存储在Spark Executor的内存中的,然后Spark Streaming启动的job会去处理这些数据。
然而,在默认的配置下,这种方式可能会因为底层的失败而丢失内存中的数据。
如果要启用高可靠机制,让数据零丢失,就必须启用Spark Streaming的预写日志机制(Write Ahead Log,WAL)。
该机制会同步地将接收到的Kafka数据写入分布式文件系统(比如HDFS)上的预写日志中。
即使底层节点出现了失败,也可以使用预写日志中的数据进行恢复,但是效率会下降。
Direct直连方式
Direct这种方式会周期性地查询Kafka,来获得每个topic(话题)+partition(分区)的最新的offset(偏移量),从而定义每个batch(批次)的offset的范围。
数据处理的job启动时,使用Kafka的简单consumer api,从Kafka中,获取指定offset范围的数据。
Direct直连方式的优点
1、相比receiver简化了并行读取:
Spark会创建跟Kafka partition一样多的RDD partition,并且会并行从Kafka中读取数据。所以在Kafka partition和RDD partition之间,是一对一的映射关系
Direct的方式:
如果要读取多个partition,不需要创建多个输入DStream然后对它们进行union操作。
2、高性能:
receiver方式:
要想保证零数据丢失,需要开启WAL机制,而这种方式其效率低下,这里会将数据复制一份在WAL中(Hdfs上).
direct的方式:
不依赖Receiver,不需要开启WAL机制,只要Kafka中作了数据的复制,那么就可以通过Kafka的副本进行恢复。
3、一次且仅一次的事务机制:
receiver方式:
使用Kafka的高阶API来在ZooKeeper中保存消费过的offset的.
这种方式配合着WAL机制可以保证数据零丢失的高可靠性,但是却无法保证数据被处理一次且仅一次,可能会处理存在两次。
因为Spark和ZooKeeper之间可能是不同步的问题。
direct的方式:
使用kafka的简单api,SparkStreaming自己就负责追踪消费的offset,并保存在checkpoint中。
Spark自己一定是同步的,因此可以保证数据是消费一次且仅消费一次。