当前位置:   article > 正文

第1课:通过案例对SparkStreaming 透彻理解三板斧_drbrqf

drbrqf
1 Spark Streaming另类在线实验

2 瞬间理解Spark Streaming本质


Spark中程序最容易出错的是流处理,流处理也是目前spark技术瓶颈之一,所以要做出一个优秀的spark发行版的话,对流处理的优化是必需的。

根据spark历史演进的趋势,spark graphX,机器学习已经发展得非常好。对它进行改进是重要的,单不是最重要的。最最重要的还是流处理,而流处理最为核心的是流处理结合机器学习,图计算的一体化结合使用,真正的实现一个堆栈rum them all .

1 流处理最容易出错

2 流处理结合图计算和机器学习将发挥出巨大的潜力

3 构造出复杂的实时数据处理的应用程序

流处理其实是构建在spark core之上的一个应用程序


代码如下:

  1. import org.apache.spark.SparkConf
  2. import org.apache.spark.storage.StorageLevel
  3. import org.apache.spark.streaming.{Seconds, StreamingContext}
  4. /**
  5. * Created by hadoop on 2016/4/18.
  6. * 背景描述 在广告点击计费系统中 我们在线过滤掉 黑名单的点击 进而包含广告商的利益
  7. * 只有效的广告点击计费
  8. *
  9. * 1、DT大数据梦工厂微信公众号DT_Spark
  10. * 2、IMF晚8点大数据实战YY直播频道号:68917580
  11. * 3、新浪微博:http://www.weibo.com/ilovepains
  12. */
  13. object OnlineBlanckListFilter extends App{
  14. //val basePath = "hdfs://master:9000/streaming"
  15. val conf = new SparkConf().setAppName("SparkStreamingOnHDFS")
  16. if(args.length == 0) conf.setMaster("spark://Master:7077")
  17. val ssc = new StreamingContext(conf, Seconds(30))
  18. val blackList = Array(("hadoop", true) , ("mahout", true), ("spark", false))
  19. val backListRDD = ssc.sparkContext.parallelize(blackList)
  20. val adsClickStream = ssc.socketTextStream("192.168.74.132", 9000, StorageLevel.MEMORY_AND_DISK_SER_2)
  21. val rdd = adsClickStream.map{ads => (ads.split(" ")(1), ads)}
  22. val validClicked = rdd.transform(userClickRDD => {
  23. val joinedBlackRDD = userClickRDD.leftOuterJoin(backListRDD)
  24. joinedBlackRDD.filter(joinedItem => {
  25. if(joinedItem._2._2.getOrElse(false)){
  26. false
  27. }else{
  28. true
  29. }
  30. })
  31. })
  32. validClicked.map(validClicked => {
  33. validClicked._2._1
  34. }).print()
  35. ssc.start()
  36. ssc.awaitTermination()
  37. }

16/05/01 17:00:31 INFO scheduler.DAGScheduler: ResultStage 1 ( start at OnlineBlanckListFilter.scala:40) finished in 4.234 s
16/05/01 17:00:31 INFO scheduler.TaskSchedulerImpl: Removed TaskSet 1.0, whose tasks have all completed, from pool 
16/05/01 17:00:32 INFO scheduler.DAGScheduler: Job 0 finished: start at OnlineBlanckListFilter.scala:40, took 81.504046 s
16/05/01 17:00:32 INFO scheduler.ReceiverTracker: Starting 1 receivers
16/05/01 17:00:32 INFO scheduler.ReceiverTracker: ReceiverTracker started
16/05/01 17:00:32 INFO dstream.ForEachDStream: metadataCleanupDelay = -1
16/05/01 17:00:32 INFO dstream.MappedDStream: metadataCleanupDelay = -1
16/05/01 17:00:32 INFO dstream.TransformedDStream: metadataCleanupDelay = -1
16/05/01 17:00:32 INFO dstream.MappedDStream: metadataCleanupDelay = -1
16/05/01 17:00:32 INFO dstream.SocketInputDStream: metadataCleanupDelay = -1
16/05/01 17:00:32 INFO dstream.SocketInputDStream: Slide time = 30000 ms
16/05/01 17:00:32 INFO dstream.SocketInputDStream: Storage level = StorageLevel(false, false, false, false, 1)
16/05/01 17:00:32 INFO dstream.SocketInputDStream: Checkpoint interval = null
16/05/01 17:00:32 INFO dstream.SocketInputDStream: Remember duration = 30000 ms
16/05/01 17:00:32 INFO dstream.SocketInputDStream: Initialized and validated org.apache.spark.streaming.dstream.SocketInputDStream@2f432294
16/05/01 17:00:32 INFO dstream.MappedDStream: Slide time = 30000 ms
16/05/01 17:00:32 INFO dstream.MappedDStream: Storage level = StorageLevel(false, false, false, false, 1)
16/05/01 17:00:32 INFO dstream.MappedDStream: Checkpoint interval = null
16/05/01 17:00:32 INFO dstream.MappedDStream: Remember duration = 30000 ms
16/05/01 17:00:32 INFO dstream.MappedDStream: Initialized and validated org.apache.spark.streaming.dstream.MappedDStream@99b8aa7
16/05/01 17:00:32 INFO dstream.TransformedDStream: Slide time = 30000 ms
16/05/01 17:00:32 INFO dstream.TransformedDStream: Storage level = StorageLevel(false, false, false, false, 1)
16/05/01 17:00:32 INFO dstream.TransformedDStream: Checkpoint interval = null
16/05/01 17:00:32 INFO dstream.TransformedDStream: Remember duration = 30000 ms
16/05/01 17:00:32 INFO dstream.TransformedDStream: Initialized and validated org.apache.spark.streaming.dstream.TransformedDStream@7e9127a
16/05/01 17:00:32 INFO dstream.MappedDStream: Slide time = 30000 ms
16/05/01 17:00:32 INFO dstream.MappedDStream: Storage level = StorageLevel(false, false, false, false, 1)
16/05/01 17:00:32 INFO dstream.MappedDStream: Checkpoint interval = null
16/05/01 17:00:32 INFO dstream.MappedDStream: Remember duration = 30000 ms
16/05/01 17:00:32 INFO dstream.MappedDStream: Initialized and validated org.apache.spark.streaming.dstream.MappedDStream@bc51cce
16/05/01 17:00:32 INFO dstream.ForEachDStream: Slide time = 30000 ms
16/05/01 17:00:32 INFO dstream.ForEachDStream: Storage level = StorageLevel(false, false, false, false, 1)
16/05/01 17:00:32 INFO dstream.ForEachDStream: Checkpoint interval = null
16/05/01 17:00:32 INFO dstream.ForEachDStream: Remember duration = 30000 ms
16/05/01 17:00:32 INFO dstream.ForEachDStream: Initialized and validated org.apache.spark.streaming.dstream.ForEachDStream@3d24c8a0
16/05/01 17:00:32 INFO scheduler.DAGScheduler: Got job 1 (start at OnlineBlanckListFilter.scala:40) with 1 output partitions
16/05/01 17:00:32 INFO scheduler.DAGScheduler: Final stage: ResultStage 2 (start at OnlineBlanckListFilter.scala:40)
16/05/01 17:00:32 INFO scheduler.DAGScheduler: Parents of final stage: List()
16/05/01 17:00:32 INFO scheduler.DAGScheduler: Missing parents: List()
16/05/01 17:00:32 INFO scheduler.DAGScheduler: Submitting ResultStage 2 (Receiver 0 ParallelCollectionRDD[4] at makeRDD at ReceiverTracker.scala:588), which has no missing parents
16/05/01 17:00:32 INFO storage.MemoryStore: Block broadcast_2 stored as values in memory (estimated size 61.2 KB, free 69.7 KB)
16/05/01 17:00:32 INFO scheduler.ReceiverTracker: Receiver 0 started
16/05/01 17:00:32 INFO storage.MemoryStore: Block broadcast_2_piece0 stored as bytes in memory (estimated size 20.5 KB, free 90.1 KB)
16/05/01 17:00:32 INFO storage.BlockManagerInfo: Added broadcast_2_piece0 in memory on 192.168.74.130:48586 (size: 20.5 KB, free: 152.8 MB)
16/05/01 17:00:32 INFO spark.SparkContext: Created broadcast 2 from broadcast at DAGScheduler.scala:1006
16/05/01 17:00:32 INFO scheduler.DAGScheduler: Submitting 1 missing tasks from ResultStage 2 (Receiver 0 ParallelCollectionRDD[4] at makeRDD at ReceiverTracker.scala:588)
16/05/01 17:00:32 INFO scheduler.TaskSchedulerImpl: Adding task set 2.0 with 1 tasks
16/05/01 17:00:33 INFO scheduler.TaskSetManager: Starting task 0.0 in stage 2.0 (TID 70, Worker2, partition 0,PROCESS_LOCAL, 2294 bytes)
16/05/01 17:00:33 INFO storage.BlockManagerInfo: Added broadcast_2_piece0 in memory on Worker2:42963 (size: 20.5 KB, free: 169.6 MB)
16/05/01 17:00:33 INFO util.RecurringTimer: Started timer for JobGenerator at time 1462093260000
16/05/01 17:00:33 INFO scheduler.JobGenerator: Started JobGenerator at 1462093260000 ms
16/05/01 17:00:33 INFO scheduler.JobScheduler: Started JobScheduler
16/05/01 17:00:34 INFO streaming.StreamingContext: StreamingContext started
16/05/01 17:00:35 INFO scheduler.ReceiverTracker: Registered receiver for stream 0 from Worker2:51587
16/05/01 17:00:35 INFO storage.BlockManagerInfo: Added input-0-1462093235000 in memory on Worker2:42963 (size: 12.0 B, free: 169.6 MB)
16/05/01 17:00:35 INFO storage.BlockManagerInfo: Added input-0-1462093235000 in memory on Worker1:40373 (size: 12.0 B, free: 169.6 MB)
16/05/01 17:00:35 INFO storage.BlockManagerInfo: Added input-0-1462093235200 in memory on Worker2:42963 (size: 24.0 B, free: 169.6 MB)
16/05/01 17:00:35 INFO storage.BlockManagerInfo: Added input-0-1462093235200 in memory on Worker1:40373 (size: 24.0 B, free: 169.6 MB)
16/05/01 17:01:01 INFO spark.SparkContext: Starting job: collect at OnlineBlanckListFilter.scala:26
16/05/01 17:01:01 INFO scheduler.DAGScheduler: Registering RDD 6 (map at OnlineBlanckListFilter.scala:23)
16/05/01 17:01:01 INFO scheduler.DAGScheduler: Registering RDD 0 (parallelize at OnlineBlanckListFilter.scala:20)
16/05/01 17:01:01 INFO scheduler.DAGScheduler: Got job 2 (collect at OnlineBlanckListFilter.scala:26) with 2 output partitions
16/05/01 17:01:01 INFO scheduler.DAGScheduler: Final stage: ResultStage 5 (collect at OnlineBlanckListFilter.scala:26)
16/05/01 17:01:01 INFO scheduler.DAGScheduler: Parents of final stage: List(ShuffleMapStage 3, ShuffleMapStage 4)
16/05/01 17:01:01 INFO scheduler.DAGScheduler: Missing parents: List(ShuffleMapStage 3, ShuffleMapStage 4)
16/05/01 17:01:01 INFO scheduler.DAGScheduler: Submitting ShuffleMapStage 3 (MapPartitionsRDD[6] at map at OnlineBlanckListFilter.scala:23), which has no missing parents
16/05/01 17:01:01 INFO storage.MemoryStore: Block broadcast_3 stored as values in memory (estimated size 2.3 KB, free 92.4 KB)
16/05/01 17:01:01 INFO storage.MemoryStore: Block broadcast_3_piece0 stored as bytes in memory (estimated size 1454.0 B, free 93.8 KB)
16/05/01 17:01:01 INFO storage.BlockManagerInfo: Added broadcast_3_piece0 in memory on 192.168.74.130:48586 (size: 1454.0 B, free: 152.8 MB)
16/05/01 17:01:01 INFO spark.SparkContext: Created broadcast 3 from broadcast at DAGScheduler.scala:1006
16/05/01 17:01:01 INFO scheduler.DAGScheduler: Submitting 2 missing tasks from ShuffleMapStage 3 (MapPartitionsRDD[6] at map at OnlineBlanckListFilter.scala:23)
16/05/01 17:01:01 INFO scheduler.TaskSchedulerImpl: Adding task set 3.0 with 2 tasks
16/05/01 17:01:01 INFO scheduler.DAGScheduler: Submitting ShuffleMapStage 4 (ParallelCollectionRDD[0] at parallelize at OnlineBlanckListFilter.scala:20), which has no missing parents
16/05/01 17:01:01 INFO scheduler.TaskSetManager: Starting task 0.0 in stage 3.0 (TID 71, Worker1, partition 0,NODE_LOCAL, 2058 bytes)
16/05/01 17:01:01 INFO storage.MemoryStore: Block broadcast_4 stored as values in memory (estimated size 1808.0 B, free 95.6 KB)
16/05/01 17:01:01 INFO storage.MemoryStore: Block broadcast_4_piece0 stored as bytes in memory (estimated size 1133.0 B, free 96.7 KB)
16/05/01 17:01:01 INFO storage.BlockManagerInfo: Added broadcast_4_piece0 in memory on 192.168.74.130:48586 (size: 1133.0 B, free: 152.8 MB)
16/05/01 17:01:01 INFO spark.SparkContext: Created broadcast 4 from broadcast at DAGScheduler.scala:1006
16/05/01 17:01:01 INFO scheduler.DAGScheduler: Submitting 2 missing tasks from ShuffleMapStage 4 (ParallelCollectionRDD[0] at parallelize at OnlineBlanckListFilter.scala:20)
16/05/01 17:01:01 INFO scheduler.TaskSchedulerImpl: Adding task set 4.0 with 2 tasks
16/05/01 17:01:01 INFO scheduler.TaskSetManager: Starting task 0.0 in stage 4.0 (TID 72, Master, partition 0,PROCESS_LOCAL, 2028 bytes)
16/05/01 17:01:01 INFO storage.BlockManagerInfo: Added broadcast_4_piece0 in memory on Master:57087 (size: 1133.0 B, free: 169.6 MB)
16/05/01 17:01:01 INFO storage.BlockManagerInfo: Added broadcast_3_piece0 in memory on Worker1:40373 (size: 1454.0 B, free: 169.6 MB)
16/05/01 17:01:01 INFO scheduler.TaskSetManager: Starting task 1.0 in stage 3.0 (TID 73, Worker1, partition 1,NODE_LOCAL, 2058 bytes)
16/05/01 17:01:01 INFO scheduler.TaskSetManager: Finished task 0.0 in stage 3.0 (TID 71) in 171 ms on Worker1 (1/2)
16/05/01 17:01:01 INFO scheduler.TaskSetManager: Starting task 1.0 in stage 4.0 (TID 74, Worker1, partition 1,PROCESS_LOCAL, 2039 bytes)
16/05/01 17:01:01 INFO scheduler.DAGScheduler: ShuffleMapStage 3 (map at OnlineBlanckListFilter.scala:23) finished in 0.192 s
16/05/01 17:01:01 INFO scheduler.DAGScheduler: looking for newly runnable stages
16/05/01 17:01:01 INFO scheduler.DAGScheduler: running: Set(ResultStage 2, ShuffleMapStage 4)
16/05/01 17:01:01 INFO scheduler.DAGScheduler: waiting: Set(ResultStage 5)
16/05/01 17:01:01 INFO scheduler.DAGScheduler: failed: Set()
16/05/01 17:01:01 INFO scheduler.TaskSetManager: Finished task 1.0 in stage 3.0 (TID 73) in 23 ms on Worker1 (2/2)
16/05/01 17:01:01 INFO scheduler.TaskSchedulerImpl: Removed TaskSet 3.0, whose tasks have all completed, from pool 
16/05/01 17:01:02 INFO scheduler.TaskSetManager: Finished task 0.0 in stage 4.0 (TID 72) in 620 ms on Master (1/2)
16/05/01 17:01:03 INFO storage.BlockManagerInfo: Added broadcast_4_piece0 in memory on Worker1:40373 (size: 1133.0 B, free: 169.6 MB)
16/05/01 17:01:03 INFO scheduler.TaskSetManager: Finished task 1.0 in stage 4.0 (TID 74) in 1412 ms on Worker1 (2/2)
16/05/01 17:01:03 INFO scheduler.DAGScheduler: ShuffleMapStage 4 (parallelize at OnlineBlanckListFilter.scala:20) finished in 1.573 s
16/05/01 17:01:03 INFO scheduler.TaskSchedulerImpl: Removed TaskSet 4.0, whose tasks have all completed, from pool 
16/05/01 17:01:03 INFO scheduler.DAGScheduler: looking for newly runnable stages
16/05/01 17:01:03 INFO scheduler.DAGScheduler: running: Set(ResultStage 2)
16/05/01 17:01:03 INFO scheduler.DAGScheduler: waiting: Set(ResultStage 5)
16/05/01 17:01:03 INFO scheduler.DAGScheduler: failed: Set()
16/05/01 17:01:03 INFO scheduler.DAGScheduler: Submitting ResultStage 5 (MapPartitionsRDD[9] at leftOuterJoin at OnlineBlanckListFilter.scala:25), which has no missing parents
16/05/01 17:01:03 INFO storage.MemoryStore: Block broadcast_5 stored as values in memory (estimated size 3.1 KB, free 99.8 KB)
16/05/01 17:01:03 INFO storage.MemoryStore: Block broadcast_5_piece0 stored as bytes in memory (estimated size 1753.0 B, free 101.5 KB)
16/05/01 17:01:03 INFO storage.BlockManagerInfo: Added broadcast_5_piece0 in memory on 192.168.74.130:48586 (size: 1753.0 B, free: 152.8 MB)
16/05/01 17:01:03 INFO spark.SparkContext: Created broadcast 5 from broadcast at DAGScheduler.scala:1006
16/05/01 17:01:03 INFO scheduler.DAGScheduler: Submitting 2 missing tasks from ResultStage 5 (MapPartitionsRDD[9] at leftOuterJoin at OnlineBlanckListFilter.scala:25)
16/05/01 17:01:03 INFO scheduler.TaskSchedulerImpl: Adding task set 5.0 with 2 tasks
16/05/01 17:01:03 INFO scheduler.TaskSetManager: Starting task 0.0 in stage 5.0 (TID 75, Master, partition 0,PROCESS_LOCAL, 2019 bytes)
16/05/01 17:01:03 INFO scheduler.TaskSetManager: Starting task 1.0 in stage 5.0 (TID 76, Worker1, partition 1,PROCESS_LOCAL, 2019 bytes)
16/05/01 17:01:03 INFO storage.BlockManagerInfo: Added broadcast_5_piece0 in memory on Master:57087 (size: 1753.0 B, free: 169.6 MB)
16/05/01 17:01:03 INFO storage.BlockManagerInfo: Added broadcast_5_piece0 in memory on Worker1:40373 (size: 1753.0 B, free: 169.6 MB)
16/05/01 17:01:03 INFO spark.MapOutputTrackerMasterEndpoint: Asked to send map output locations for shuffle 1 to Worker1:40424
16/05/01 17:01:03 INFO spark.MapOutputTrackerMaster: Size of output statuses for shuffle 1 is 148 bytes
16/05/01 17:01:03 INFO spark.MapOutputTrackerMasterEndpoint: Asked to send map output locations for shuffle 2 to Worker1:40424
16/05/01 17:01:03 INFO spark.MapOutputTrackerMaster: Size of output statuses for shuffle 2 is 165 bytes
16/05/01 17:01:04 INFO spark.MapOutputTrackerMasterEndpoint: Asked to send map output locations for shuffle 1 to Master:48964
16/05/01 17:01:04 INFO spark.MapOutputTrackerMasterEndpoint: Asked to send map output locations for shuffle 2 to Master:48964
16/05/01 17:01:06 INFO scheduler.TaskSetManager: Finished task 0.0 in stage 5.0 (TID 75) in 3733 ms on Master (1/2)
16/05/01 17:01:07 INFO scheduler.TaskSetManager: Finished task 1.0 in stage 5.0 (TID 76) in 4126 ms on Worker1 (2/2)
16/05/01 17:01:07 INFO scheduler.DAGScheduler: ResultStage 5 (collect at OnlineBlanckListFilter.scala:26) finished in 4.128 s
16/05/01 17:01:07 INFO scheduler.TaskSchedulerImpl: Removed TaskSet 5.0, whose tasks have all completed, from pool 
16/05/01 17:01:07 INFO scheduler.DAGScheduler: Job 2 finished: collect at OnlineBlanckListFilter.scala:26, took 5.896825 s
(flink,(2056 flink,None))
(uity,(4589 uity,None))
(hdaoop,(4589 hdaoop,None))
16/05/01 17:01:09 INFO scheduler.JobScheduler: Added jobs for time 1462093260000 ms

16/05/01 17:01:09 INFO scheduler.JobScheduler: Starting job streaming job 1462093260000 ms.0 from job set of time 1462093260000 ms

   下面是WEBUI展示的内容:


   我们看到这里有2次真正的StreamingJOB

   我们一个一个看下这些任务都是什么?

   JOB 0 :

   

   思考一个问题:这里为啥有这个任务 ,我们写的代码中并有没这些转换?

  我们查看Stage0 的详情:

  

 这里启动了50个JOB 我们从源码中找答案:

  

  1. /**
  2. * Get the receivers from the ReceiverInputDStreams, distributes them to the
  3. * worker nodes as a parallel collection, and runs them.
  4. */
  5. private def launchReceivers(): Unit = {
  6. val receivers = receiverInputStreams.map(nis => {
  7. val rcvr = nis.getReceiver()
  8. rcvr.setReceiverId(nis.id)
  9. rcvr
  10. })
  11. runDummySparkJob()
  12. logInfo("Starting " + receivers.length + " receivers")
  13. endpoint.send(StartAllReceivers(receivers))
  14. }
  1. 我们关注 <pre name="code" class="java">runDummySparkJob 这个方法:<pre name="code" class="java">/**
  2. * Run the dummy Spark job to ensure that all slaves have registered. This avoids all the
  3. * receivers to be scheduled on the same node.
  4. *
  5. * TODO Should poll the executor number and wait for executors according to
  6. * "spark.scheduler.minRegisteredResourcesRatio" and
  7. * "spark.scheduler.maxRegisteredResourcesWaitingTime" rather than running a dummy job.
  8. */
  9. private def runDummySparkJob(): Unit = {
  10. if (!ssc.sparkContext.isLocal) {
  11. ssc.sparkContext.makeRDD(1 to 50, 50).map(x => (x, 1)).reduceByKey(_ + _, 20).collect()
  12. }
  13. assert(getExecutors.nonEmpty)
  14. }

 
 这里启动了50个JOB,这个注释说明了这个方法是为了避免在同一个节点上启动 receivers 
</pre><pre name="code" class="java"> 我们回到JOB 1
  1. <img src="https://img-blog.csdn.net/20160501220204990?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
  2. <pre name="code" class="java"> 我们继续查看详情:
  <img src="data:image/png;base64,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" alt="" />
  我们看到这个任务是在Worker2 上执行的 而我打开Scoket 也是在Worker2 ,任务发生在数据产生的节点!!!
  我们从源码中找到答案:
  1. <pre name="code" class="java">RegisterReceiver 中的 startReceiver
  2. // Function to start the receiver on the worker node
  3. val startReceiverFunc: Iterator[Receiver[_]] => Unit =
  4. (iterator: Iterator[Receiver[_]]) => {
  5. if (!iterator.hasNext) {
  6. throw new SparkException(
  7. "Could not start receiver as object not found.")
  8. }
  9. if (TaskContext.get().attemptNumber() == 0) {
  10. val receiver = iterator.next()
  11. assert(iterator.hasNext == false)
  12. val supervisor = new ReceiverSupervisorImpl(
  13. receiver, SparkEnv.get, serializableHadoopConf.value, checkpointDirOption)
  14. supervisor.start()
  15. supervisor.awaitTermination()
  16. } else {
  17. // It's restarted by TaskScheduler, but we want to reschedule it again. So exit it.
  18. }
  19. }
  20. // Create the RDD using the scheduledLocations to run the receiver in a Spark job
  21. val receiverRDD: RDD[Receiver[_]] =
  22. if (scheduledLocations.isEmpty) {
  23. ssc.sc.makeRDD(Seq(receiver), 1)
  24. } else {
  25. val preferredLocations = scheduledLocations.map(_.toString).distinct
  26. ssc.sc.makeRDD(Seq(receiver -> preferredLocations))
  27. }
  28. receiverRDD.setName(s"Receiver $receiverId")
  29. ssc.sparkContext.setJobDescription(s"Streaming job running receiver $receiverId")
  30. ssc.sparkContext.setCallSite(Option(ssc.getStartSite()).getOrElse(Utils.getCallSite()))
  31. val future = ssc.sparkContext.submitJob[Receiver[_], Unit, Unit](
  32. receiverRDD, startReceiverFunc, Seq(0), (_, _) => Unit, ())
这里就是收集数据的节点,一个节点接收数据!
 
   思考:数据的接收是一个节点上,那计算发生在哪里?
   
 
 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/688134
推荐阅读
相关标签
  

闽ICP备14008679号