SparkStreaming读取kafka数据的两种方式

Receive

Receive是使用的高级API,需要消费者连接Zookeeper来读取数据。是由Zookeeper来维护偏移量,不用我们来手动维护,这样的话就比较简单一些,减少了代码量。但是天下没有免费的午餐,它也有很多缺点:
1.导致丢失数据。它是由Executor内的Receive来拉取数据并存放在内存中,再由Driver端提交的job来处理数据。这样的话,如果底层节点出现错误,就会发生数据丢失。
2.浪费资源。可以采取WALs方式将数据同步到高可用数据存储平台上(HDFS,S3),那么如果再发生错误,就可以从中再次读取数据。但是这样会导致同样的数据存储了两份,浪费了资源。
3.可能会导致重复读取数据。对于公司来说,一些数据宁可丢失了一小小部分也不能重复读取,但是这种由Zookeeper来记录偏移量的方式,可能会因为Spark和Zookeeper不同步,导致一份数据读取了两次。
4.效率低。因为是分批次执行的,它是接收数据,直到达到了设定的时间间隔,才可是进行计算。而且我们在KafkaUtils.createStream()中设定的partition数量,只会增加receive的数量,不能提高并行计算的效率,但我们可以设定不同的Group和Topic创建DStream,然后再用Union合并DStream,提高并行效率。

官网Receive的架构图如下:
在这里插入图片描述

Direct

Direct方式则采用的是低层次的API,直接连接kafka服务器上读取数据。需要我们自己去手动维护偏移量,代码量稍微大些。不过这种方式的优点有:
1.当我们读取Topic下的数据时,它会自动对应Topic下的Partition生成相对应数量的RDD Partition,提高了计算时的并行度,提高了效率。
2.它不需要通过WAL来维持数据的完整性。采取Direct直连方式时,当数据发生丢失,只要kafka上的数据进行了复制,就可以根据副本来进行数据重新拉取。
3.它保证了数据只消费一次。因为我们将偏移量保存在一个地方,当我们读取数据时,从这里拿到数据的起始偏移量和读取偏移量确定读取范围,通过这些我们可以读取数据,当读取完成后会更新偏移量,这就保证了数据只消费一次。

官方的Direct架构图如下:
在这里插入图片描述

总结

在spark1.3以后的版本中,direct方式取代了receive方式,当然在公司中,使用的都是direct方式。从上面对比也能看出receive方式的效率低,而且数据完整性也很让人担忧,当我们采取direct方式时,完全不用为这两点所担忧,可以根据自己想读取的范围进行读取,底层失败后也能通过副本来进行数据恢复。
在接下来的博客中,我会向大家分别介绍三种采用Direct存储偏移量的方式。
1.存储于HBase
2.存储于Zookeeper
3.存储于MySQL
如果我说的有哪点错误的地方,希望能帮我指正出来。

									 summed up by JiaMingcan
									 转载请署名:JiaMingcan
©️2020 CSDN 皮肤主题: 精致技术 设计师:CSDN官方博客 返回首页