一、Kafka-08 接口
### --- Receiver based Approach
~~~ 基于 Receiver 的方式使用 Kafka 旧版消费者高阶API实现。
~~~ 对于所有的 Receiver,通过 Kafka 接收的数据被存储于 Spark 的 Executors上,
~~~ 底层是写入BlockManager中,默认200ms生成一个block(spark.streaming.blockInterval)。
~~~ 然后由 Spark Streaming 提交的 job 构建BlockRDD,最终以 Spark Core任务的形式运行。
### --- 对应 Receiver方式,有以下几点需要注意:
~~~ Receiver 作为一个常驻线程调度到 Executor上运行,占用一个cpu
~~~ Receiver 个数由KafkaUtils.createStream调用次数决定,一次一个 Receiver
~~~ kafka中的topic分区并不能关联产生在spark streaming中的rdd分区。
~~~ 增加在KafkaUtils.createStream()中的指定的topic分区数,
~~~ 仅仅增加了单个receiver消费的topic的线程数,它不会增加处理数据中的并行的spark的数量。
~~~ 【 即:topicMap[topic,num_threads]中,value对应的数值是每个topic对应的消费线程数】
~~~ receiver默认200ms生成一个block,可根据数据量大小调整block生成周期。
### --- 一个block对应RDD一个分区。
~~~ receiver接收的数据会放入到BlockManager,每个 Executor 都会有一个BlockManager实例,
~~~ 由于数据本地性,那些存在 Receiver 的 Executor 会被调度执行更多的 Task,
~~~ 就会导致某些executor比较空闲默认情况下,Receiver是可能丢失数据的。
~~~ 可以通过设置spark.streaming.receiver.writeAheadLog.enable为true开启预写日志机制,
~~~ 将数据先写入一个可靠地分布式文件系统(如HDFS),确保数据不丢失,但会损失一定性能
二、spark Streaming架构
![](https://i-blog.csdnimg.cn/blog_migrate/806de9da23d27d996e03c9b7eb403351.png)
### --- Kafka-08 接口(Receiver方式):
~~~ Offset保存在ZK中,系统管理
~~~ 对应Kafka的版本 0.8.2.1+
~~~ 接口底层实现使用 Kafka 旧版消费者高阶API
~~~ DStream底层实现为BlockRDD
四、spark Streaming+HDFS
![](https://i-blog.csdnimg.cn/blog_migrate/47bf85e0ea42cc6e8ffc46f22b27751a.png)
### --- Kafka-08 接口(Receiver with WAL):
~~~ 增强了故障恢复的能力
~~~ 接收的数据与Dirver的元数据保存到HDFS
~~~ 增加了流式应用处理的延迟
五、Direct Approach
### --- Direct Approach
~~~ Direct Approach是 Spark Streaming不使用Receiver集成kafka的方式,
~~~ 在企业生产环境中使用较多。
### --- 相较于Receiver,有以下特点:
~~~ 不使用 Receiver。减少不必要的CPU占用;
~~~ 减少了 Receiver接收数据写入BlockManager,
~~~ 然后运行时再通过blockId、网络传输、磁盘读取等来获取数据的整个过程,提升了效率;
~~~ 无需WAL,进一步减少磁盘IO;
~~~ Direct方式生的RDD是KafkaRDD,它的分区数与 Kafka 分区数保持一致,便于把控并行度
~~~ 注意:在 Shuffle 或 Repartition 操作后生成的RDD,这种对应关系会失效
~~~ 可以手动维护offset,实现 Exactly Once 语义
![](https://i-blog.csdnimg.cn/blog_migrate/2bc2bf9ad3472bbb7b3578760e691b1e.png)