- 1、两种方式特点以及优缺点讲解
- 2、Spark Streaming 整合kafka的两种方式代码展示
7.1、Receiver Approach
Receiver是使用Kafka的high level的consumer API来实现的。Receiver从Kafka中获取数据都是存储在Spark Executor内存中的,然后Spark Streaming启动的job会去处理那些数据
然而这种方式很可能会丢失数据,如果要启用高可靠机制,让数据零丢失,就必须启动Spark Streaming预写日志机制(WAL,Write Ahead Log)。该机制会同步地接收到Kafka数据写入分布式文件系统,比如HDFS上的预写日志中。所有底层节点出现了失败,也可以使用预写日志的数据进行恢复。
saprk streaming + kafka整合(Receiver -based Approach)博文链接:
代码实现:
https://blog.csdn.net/murphyZ/article/details/88238878
7.2、Direct Approach (No Receiver)
它会周期性的查询kafka,来获取每个topic + partition的最新offset,从而定义每一个batch的offset的范围。当处理数据的job启动时,就会使用kafka简单的消费者API来获取kafka指定offset的范围的数据。
1)、它简化了并行读取:如果要读取多个partition,不需要创建多个输入DStream然后对他们进行union操作。Spark会创建跟kafka partition一样多的RDD partition,并且会并行从kafka中读取数据。所以在kafka partition和RDD partition之间有一个一一对应的映射关系。
2)、高性能:如果要保证数据零丢失,基于Receiver的机制需要开启WAL机制,这种方式其实很低效,因为数据实际上被copy了2份,kafka自己本身就有可靠的机制,会对数据复制一份,而这里又复制一份到WAL中。基于Direct的方式,不依赖于Receiver,不需要开启WAL机制,只要kafka中做了数据的复制,那么就可以通过kafka的副本进行恢复。
3)、一次仅且一次的事务机制
基于Receiver的方式,是使用Kafka High Level的API在zookeeper中保存消费过的offset的。这是消费kafka数据的传统方式,这种方式配合着WAL机制可以保证数据零丢失,但是无法保证数据只被处理一次且仅且一次,可能会两次或者更多,因为spark和zookeeper可能是不同步的。
4)、降低资源
Direct不需要Receivers,其申请的Executors全部参与到计算任务中;而Receiver-based则需要专门的Receivers来读取Kafka数据且不参与计算。因此相同的资源申请,Direct 能够支持更大的业务。
5)、降低内存
Receiver-based的Receiver与其他Exectuor是异步的,并持续不断接收数据,对于小业务量的场景还好,如果遇到大业务量时,需要提高Receiver的内存,但是参与计算的Executor并无需那么多的内存。而Direct 因为没有Receiver,而是在计算时读取数据,然后直接计算,所以对内存的要求很低。实际应用中我们可以把原先的10G降至现在的2-4G左右。
6)、不会出现数据堆积
Receiver-based方法需要Receivers来异步持续不断的读取数据,因此遇到网络、存储负载等因素,导致实时任务出现堆积,但Receivers却还在持续读取数据,此种情况很容易导致计算崩溃。Direct 则没有这种顾虑,其Driver在触发batch 计算任务时,才会读取数据并计算。队列出现堆积并不会引起程序的失败。
基于direct的方式,使用kafka的简单api,Spark Streaming自己就负责追踪消费的offset,并保存在checkpoint中。Spark自己一定是同步的,因此可以保证数据是消费一次且仅消费一次。
spark streaming + kafka整合(Direct Approach (No Receiver))代码实战链接
https://blog.csdn.net/murphyZ/article/details/88253396