DirectStream、Stream的区别-SparkStreaming源码分析02

在Spark1.3之前,默认的Spark接收Kafka数据的方式是基于Receiver的,在这之后的版本里,推出了Direct Approach,现在整理一下两种方式的异同。

1. Receiver-based Approach

示例代码:

<code class="hljs css" style="font-family:Menlo,Monaco,Consolas,"Courier New",monospace;font-size:undefined; padding:0.5em; display:block; width:auto; word-wrap:normal; overflow-x:auto"><span class="hljs-tag" style="color:#0080;">import</span> <span class="hljs-tag" style="color:#0080;">org</span><span class="hljs-class" style="">.apache</span><span class="hljs-class" style="">.spark</span><span class="hljs-class" style="">.streaming</span><span class="hljs-class" style="">.kafka</span><span class="hljs-class" style="">._</span>
</code>
val kafkaStream = KafkaUtils.createStream(streamingContext,
<code class="hljs css" style="font-family:Menlo,Monaco,Consolas,"Courier New",monospace;font-size:undefined; padding:0.5em; display:block; width:auto; word-wrap:normal; overflow-x:auto"> <span class="hljs-attr_selector" style="">[ZK quorum]</span>, <span class="hljs-attr_selector" style="">[consumer group id]</span>, <span class="hljs-attr_selector" style="">[per-topic number of Kafka partitions to consume]</span>)
</code>

2. Direct Approach (No Receivers)

示例代码:

<code class="hljs cpp" style="font-family:Menlo,Monaco,Consolas,"Courier New",monospace;font-size:undefined; padding:0.5em; display:block; width:auto; word-wrap:normal; overflow-x:auto"> import org.apache.spark.streaming.kafka._

 val directKafkaStream = KafkaUtils.createDirectStream[
 [key <span class="hljs-keyword" style="font-weight:bold">class</span>], [value <span class="hljs-keyword" style="font-weight:bold">class</span>], [key decoder <span class="hljs-keyword" style="font-weight:bold">class</span>], [value decoder <span class="hljs-keyword" style="font-weight:bold">class</span>] ](
 streamingContext, [<span class="hljs-built_in" style="color:#086b3;">map</span> of Kafka parameters], [<span class="hljs-built_in" style="color:#086b3;">set</span> of topics to consume])
</code>

源码实现

1、 KafkaUtils.createStream

首先从源码层面来看,其主要调用栈顺序:

<code class="hljs php" style="font-family:Menlo,Monaco,Consolas,"Courier New",monospace;font-size:undefined; padding:0.5em; display:block; width:auto; word-wrap:normal; overflow-x:auto">KafkaUtils.createStream--->createStream--->new KafkaInputDStream--->new KafkaReceiver
</code>

KafkaReceiver类继承了Receiver,当Reciver被调用起来时,执行onStart()方法,MessageHandler负责将收到的数据进行存储。执行流程如下:

  1. 创建createStreamReceiver被调起执行
  2. 连接ZooKeeper,读取相应的ConsumerTopic配置信息等
  3. 通过consumerConnector连接到Kafka集群,收取指定topic的数据
  4. 创建KafkaMessageHandler线程池来对数据进行处理,通过ReceiverInputDStream中的方法,将数据转换成BlockRDD,供后续计算

2、 KafkaUtils.createDirectStream

主要调用栈顺序:

KafkaUtils.createDirectStream—> new DirectKafkaInputDStream

执行流程如下:

  1. 实例化KafkaCluster,根据用户配置的Kafka参数,连接Kafka集群
  2. 通过Kafka API读取Topic中每个Partition最后一次读的Offset
  3. 接收成功的数据,直接转换成KafkaRDD,供后续计算

架构

通过两张图,来看下他们架构

1、 Receiver-based Approach

2、 Direct Approach (No Receivers)

优缺点

相关的优缺点,在官网上已经说得很清楚了。追求效率、数据准确可以使用Direct方式,但需要自己对Offset进行处理。

参考资料:

Spark Streaming + Kafka Integration Guide

https://github.com/koeninger/kafka-exactly-once

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值