Spark的认识(四)

10 篇文章 0 订阅
7 篇文章 1 订阅

Spark的认识(四)

1、本文内容

  • 1、掌握SparkStreaming底层原理

  • 2、掌握Dstream常用操作

  • 3、掌握SparkStreaming整合flume

  • 4、掌握SparkStreaming整合kafka

2、SparkStreaming概述

2.1 什么是sparkStreaming

  • Spark Streaming makes it easy to build scalable fault-tolerant streaming applications.

  • SparkStreaming是可以非常容易的构建一个可扩展、具有容错机制的流式应用程序

2.2 sparkStreaming特性

  • 1、易用性

    • 可以像开发离线批处理一样去编写流式处理程序,还是可以使用java、scala、Python等不同的语言开发

  • 2、容错性

    • sparkStreaming可以实现恰好一次语义(数据被处理且只被处理一次)

    • sparkStreaming可以实现在不需要额外代码的情况下,来实现丢失的job

  • 3、可以融合到spark生态系统

    • sparkstreaming可以和离线批处理和交互式查询相结合

3、sparkStreaming原理

3.1 sparkStreaming计算原理

Spark Streaming 是基于spark的流式批处理引擎,其基本原理是把输入数据以某一时间间隔批量的处理,当批处理间隔缩短到秒级时,便可以用于处理实时数据流。

3.2 sparkStreaming计算流程

sparkStreaming是以某一个时间间隔的批处理,按照批处理的时间间隔进行划分,划分出了很多个短小的批处理作业,每一个段数据在这里就是一个Dstream,Dstream内部是由当前该批次的数据,内部的数据是通过rdd进行封装,也就是说Dstream中封装了rdd,rdd里面有很多个分区,分区里面才是真正的数据。
​
后期Dstream做大量的transformation操作,最终都转换成了对它内部的rdd也就是对应的transformation。

3.3 sparkStreaming容错性

Dstream中内部封装了rdd,这个时候后期对它做大量操作的时候,如果某个rdd的分区数据丢失了,可以通过rdd的血统进行重新计算恢复得到。
​
通过血统在进行重新计算恢复得到丢失的数据的时候需要一定条件:就是保证数据源端安全性
sc.textFile("/words.txt").flatMap(_.split(" ")).map((_,1)).reduceByKey(_+_).collect
​
恢复数据:  血统+原始的数据进行恢复

3.4 sparkStreaming的实时性

storm是来一条数据就处理一条,实时性比较高
sparkStreamning是以某一时间间隔处理,延迟比较高,实时性比较低
​
后期再处理一些实时的应用的场景,具体使用哪一种框架去实现,一定要结合当前这个业务需求:
比如说 公司领导对实时性要求比较高,从数据生成到看到结果数据需要非常快的时间,这个时候优先考虑storm框架
公司领导对实时性要求不是特别高,从数据生成到看到结果数据可以允许有一定的延迟,这个时候就可以考虑使用sparkStreaming框架。

4、DStream

4.1 什么是Dstream

Discretized Stream是Spark Streaming的基础抽象,代表持续性的数据流和经过各种Spark算子操作后的结果数据流。在内部实现上,DStream是一系列连续的RDD来表示。每个RDD含有一段时间间隔内的数据。

4.2 Dstream操作分类

  • 1、transformation(转换)

    • 可以把一个Dstream转换生成一个新的Dstream。它也是延迟加载,不会立即触发任务的运行

    • 类似于rdd的中transformation

  • 2、outputOperation(输出)

    • 它会触发任务的真正运行

    • 类似于rdd的中action

5、Dstream操作实战

  • 引入依赖

            <dependency>
                <groupId>org.apache.spark</groupId>
                <artifactId>spark-streaming_2.11</artifactId>
                <version>2.1.3</version>
            </dependency>

5.1 通过sparkStreaming接受socket数据实现单词统计

  • 1、代码开发

    package demo.socket
    ​
    import org.apache.spark.streaming.dstream.{DStream, ReceiverInputDStream}
    import org.apache.spark.{SparkConf, SparkContext}
    import org.apache.spark.streaming.{Seconds, StreamingContext}
    ​
    //todo:利用sparkStreaming接受socket数据实现单词统计
    object SparkStreamingSocket {
      def main(args: Array[String]): Unit = {
        //1、创建SparkConf对象
          val sparkConf: SparkConf = new SparkConf().setAppName("SparkStreamingSocket").setMaster("local[2]")
    ​
        //2、创建SparkContext对象
          val sc = new SparkContext(sparkConf)
          sc.setLogLevel("warn")
    ​
        //3、创建StreamingContext,需要2个 参数,第一个是SparkContext对象,第二个是批处理时间间隔
          val ssc = new StreamingContext(sc,Seconds(5))
    ​
        //4、接受socket数据
           val socketTextStream: ReceiverInputDStream[String] = ssc.socketTextStream("node1",9999)
    ​
        //5、切分每一行获取所有的单词
          val words: DStream[String] = socketTextStream.flatMap(_.split(" "))
    ​
        //6、每个单词计为1
          val wordAndOne: DStream[(String, Int)] = words.map((_,1))
    ​
        //7、相同单词出现的1累加
          val result: DStream[(String, Int)] = wordAndOne.reduceByKey(_+_)
    ​
        //8、打印
          result.print()
    ​
        //9、开启流式计算
          ssc.start()
          ssc.awaitTermination()
      }
    }
    ​

5.2 通过sparkStreaming接受socket数据实现所有批次单词统计的结果累加

  • 1、代码开发

    package demo.socket
    ​
    import org.apache.spark.streaming.dstream.{DStream, ReceiverInputDStream}
    import org.apache.spark.streaming.{Seconds, StreamingContext}
    import org.apache.spark.{SparkConf, SparkContext}
    ​
    //todo:利用sparkStreaming接受socket数据实现所有批次单词统计结果累加
    object SparkStreamingSocketTotal {
    ​
      //currentValues:表示在当前批次中相同的单词出现的所有的1(hadoop---->List(1,1,1,1))
      //historyValues:表示每一个单词在之前所有批次中出现总次数
    ​
         //Option类型:可以表示可能存在或者不存在的值   存在Some,  不存在None
      def updateFunc(currentValues:Seq[Int],historyValues:Option[Int]):Option[Int] = {
           val newValue: Int = currentValues.sum  +  historyValues.getOrElse(0)
           Some(newValue)
      }
    ​
      def main(args: Array[String]): Unit = {
          //1、创建SparkConf
          val sparkConf: SparkConf = new SparkConf().setAppName("SparkStreamingSocketTotal").setMaster("local[2]")
    ​
          //2、创建SparkContext
          val sc = new SparkContext(sparkConf)
          sc.setLogLevel("warn")
    ​
         //3、创建StreamingContext
          val ssc = new StreamingContext(sc,Seconds(5))
    ​
           //设置checkpoint目录,主要的作用:用于保存之前批次每一个单词出现的总次数
            ssc.checkpoint("./socket")
    ​
         //4、接受socket数据
          val socketTextStream: ReceiverInputDStream[String] = ssc.socketTextStream("node1",9999)
    ​
        //5、切分每一行获取所有的单词
          val words: DStream[String] = socketTextStream.flatMap(_.split(" "))
    ​
        //6、每个单词计为1
          val wordAndOne: DStream[(String, Int)] = words.map((_,1))
    ​
        //7、相同单词出现的1累加
          val result: DStream[(String, Int)] = wordAndOne.updateStateByKey(updateFunc)
    ​
        //8、打印
          result.print()
    ​
        //9、开启流式计算
          ssc.start()
          ssc.awaitTermination()
      }
    }
    ​

 

5.3 通过sparkStreaming接受socket数据,利用reduceByKeyAndWindow来实现单词统计

  • 1、代码开发

    package demo.socket
    
    import org.apache.spark.{SparkConf, SparkContext}
    import org.apache.spark.streaming.{Seconds, StreamingContext}
    import org.apache.spark.streaming.dstream.{DStream, ReceiverInputDStream}
    
    //todo:利用reduceByKeyAndWindow来实现单词统计
    object SparkStreamingSocketWindow {
      def main(args: Array[String]): Unit = {
        //1、创建SparkConf对象
        val sparkConf: SparkConf = new SparkConf().setAppName("SparkStreamingSocketWindow").setMaster("local[2]")
    
        //2、创建SparkContext对象
        val sc = new SparkContext(sparkConf)
        sc.setLogLevel("warn")
    
        //3、创建StreamingContext,需要2个 参数,第一个是SparkContext对象,第二个是批处理时间间隔
        val ssc = new StreamingContext(sc,Seconds(5))
    
        //4、接受socket数据
        val socketTextStream: ReceiverInputDStream[String] = ssc.socketTextStream("node1",9999)
    
        //5、切分每一行获取所有的单词
        val words: DStream[String] = socketTextStream.flatMap(_.split(" "))
    
        //6、每个单词计为1
        val wordAndOne: DStream[(String, Int)] = words.map((_,1))
    
        //7、相同单词出现的1累加
           //需要3个参数
    //    reduceFunc: (V, V) => V,   它就是一个函数
    //    windowDuration: Duration,  窗口的长度
    //    slideDuration: Duration    窗口的滑动时间间隔,表示每隔多久计算一次
        val result: DStream[(String, Int)] = wordAndOne.reduceByKeyAndWindow((x:Int,y:Int)=>x+y,Seconds(5),Seconds(10))
    
        //8、打印
        result.print()
    
        //9、开启流式计算
        ssc.start()
        ssc.awaitTermination()
      }
    }
    
    

5.4 通过sparkStreaming使用开窗函数来统计一定内的热门词汇

  • 1.代码开发

    package demo.socket
    
    import org.apache.spark.rdd.RDD
    import org.apache.spark.streaming.dstream.{DStream, ReceiverInputDStream}
    import org.apache.spark.streaming.{Seconds, StreamingContext}
    import org.apache.spark.{SparkConf, SparkContext}
    
    //todo:利用开窗函数来实现一定时间内的热门词汇
    object SparkStreamingSocketWindowHotWords {
      def main(args: Array[String]): Unit = {
          //1、创建SparkConf
          val sparkConf: SparkConf = new SparkConf().setAppName("SparkStreamingSocketWindowHotWords").setMaster("local[2]")
    
          //2、创建SparkContext
          val sc = new SparkContext(sparkConf)
          sc.setLogLevel("warn")
    
         //3、创建StreamingContext
          val ssc = new StreamingContext(sc,Seconds(5))
    
        //4、接受socket数据
        val socketTextStream: ReceiverInputDStream[String] = ssc.socketTextStream("node1",9999)
    
        //5、切分每一行获取所有的单词
        val words: DStream[String] = socketTextStream.flatMap(_.split(" "))
    
        //6、每个单词计为1
        val wordAndOne: DStream[(String, Int)] = words.map((_,1))
    
        //7、相同单词出现的1累加
        val result: DStream[(String, Int)] = wordAndOne.reduceByKeyAndWindow((x:Int,y:Int)=>x+y,Seconds(10),Seconds(10))
    
        //按照单词出现的次数降序排列
        val sortDstream: DStream[(String, Int)] = result.transform(rdd => {
          //按照单词次数降序
          val sortRDD: RDD[(String, Int)] = rdd.sortBy(_._2, false)
          //取出次数最多的前3位
          val top3: Array[(String, Int)] = sortRDD.take(3)
          println("---------------top3--------------start")
          top3.foreach(println)
          println("---------------top3--------------end")
          sortRDD
        })
    
        //8、打印
        sortDstream.print()
    
        //9、开启流式计算
        ssc.start()
        ssc.awaitTermination()
      }
    }
    
    

6、sparkStreaming整合flume

6.1 Poll拉模式整合

  • 1、需要将spark-streaming-flume-sink_2.11-2.1.3.jar放入到flume的lib目录下,同时还需要把flume自带的scala依赖2.10改为2.11

  • 2、修改flume配置文件

    • vim flume-poll-spark.conf

      a1.sources = r1
      a1.sinks = k1
      a1.channels = c1
      
      #source
      a1.sources.r1.channels = c1
      a1.sources.r1.type = spooldir
      a1.sources.r1.spoolDir = /root/data
      a1.sources.r1.fileHeader = true
      
      
      #channel
      a1.channels.c1.type =memory
      a1.channels.c1.capacity = 20000
      a1.channels.c1.transactionCapacity=5000
      
      
      #sinks
      a1.sinks.k1.channel = c1
      a1.sinks.k1.type = org.apache.spark.streaming.flume.sink.SparkSink
      a1.sinks.k1.hostname=node1
      a1.sinks.k1.port = 8888
      a1.sinks.k1.batchSize= 2000
      
  • 3、引入依赖

            <dependency>
                <groupId>org.apache.spark</groupId>
                <artifactId>spark-streaming-flume_2.11</artifactId>
                <version>2.1.3</version>
            </dependency>
    
  • 4、代码开发

    package demo.flume
    
    import java.net.InetSocketAddress
    
    import org.apache.spark.storage.StorageLevel
    import org.apache.spark.streaming.dstream.{DStream, ReceiverInputDStream}
    import org.apache.spark.{SparkConf, SparkContext}
    import org.apache.spark.streaming.{Seconds, StreamingContext}
    import org.apache.spark.streaming.flume.{FlumeUtils, SparkFlumeEvent}
    
    //todo:利用sparkStreaming整合flume-------Poll拉模式整合
    object SparkStreamingFlumePoll {
      def main(args: Array[String]): Unit = {
        //1、创建SparkConf对象
        val sparkConf: SparkConf = new SparkConf().setAppName("SparkStreamingFlumePoll").setMaster("local[2]")
    
        //2、创建SparkContext对象
        val sc = new SparkContext(sparkConf)
        sc.setLogLevel("warn")
    
        //3、创建StreamingContext,需要2个 参数,第一个是SparkContext对象,第二个是批处理时间间隔
        val ssc = new StreamingContext(sc,Seconds(5))
    
        //4、通过拉模式接受flume的数据
       val pollingStream: ReceiverInputDStream[SparkFlumeEvent] = FlumeUtils.createPollingStream(ssc,"node1",8888)
    
         //接受多台flume收集到的数据
    //        val addresses=List(new InetSocketAddress("node1",8888),new InetSocketAddress("node2",8888),new InetSocketAddress("node3",8888))
    //       val stream: ReceiverInputDStream[SparkFlumeEvent] = FlumeUtils.createPollingStream(ssc,addresses,StorageLevel.MEMORY_AND_DISK_SER_2)
    //
        //5、获取flume中数据  flume中数据传输的最小单元是一个event:{"headers":xxxxx,"body":xxxxxx}
             //获取body中的数据
        val data: DStream[String] = pollingStream.map(x=>new String(x.event.getBody.array()))
    
        //6、切分每一行获取所有的单词
        val words: DStream[String] = data.flatMap(_.split(" "))
    
        //7、每个单词计为1
        val wordAndOne: DStream[(String, Int)] = words.map((_,1))
    
        //8、相同单词出现的1累加
        val result: DStream[(String, Int)] = wordAndOne.reduceByKey(_+_)
    
        //9、打印
        result.print()
    
        //10、开启流式计算
        ssc.start()
        ssc.awaitTermination()
    
      }
    }
    
    

6.2 Push推模式整合

  • 1、编写flume的配置文件

    • vim flume-push-spark.conf

      #push mode
      a1.sources = r1
      a1.sinks = k1
      a1.channels = c1
      #source
      a1.sources.r1.channels = c1
      a1.sources.r1.type = spooldir
      a1.sources.r1.spoolDir = /root/data
      a1.sources.r1.fileHeader = true
      #channel
      a1.channels.c1.type =memory
      a1.channels.c1.capacity = 20000
      a1.channels.c1.transactionCapacity=5000
      #sinks
      a1.sinks.k1.channel = c1
      a1.sinks.k1.type = avro
      #是sparkStreaming应用程序所在的ip地址和端口
      a1.sinks.k1.hostname=192.168.25.48
      a1.sinks.k1.port = 8888
      a1.sinks.k1.batchSize= 2000
      
  • 2、代码开发

    package demo.flume
    
    import org.apache.spark.streaming.dstream.{DStream, ReceiverInputDStream}
    import org.apache.spark.{SparkConf, SparkContext}
    import org.apache.spark.streaming.{Seconds, StreamingContext}
    import org.apache.spark.streaming.flume.{FlumeUtils, SparkFlumeEvent}
    
    //todo:sparkStreaming整合flume-------Push推模式
    object SparkStreamingFlumePush {
      def main(args: Array[String]): Unit = {
        //1、创建SparkConf对象
        val sparkConf: SparkConf = new SparkConf().setAppName("SparkStreamingFlumePush").setMaster("local[2]")
    
        //2、创建SparkContext对象
        val sc = new SparkContext(sparkConf)
        sc.setLogLevel("warn")
    
        //3、创建StreamingContext,需要2个 参数,第一个是SparkContext对象,第二个是批处理时间间隔
        val ssc = new StreamingContext(sc,Seconds(5))
    
        //4、接受flume中的数据
        val stream: ReceiverInputDStream[SparkFlumeEvent] = FlumeUtils.createStream(ssc,"192.168.25.48",8888)
    
        //5、获取flume中数据  flume中数据传输的最小单元是一个event:{"headers":xxxxx,"body":xxxxxx}
        //获取body中的数据
        val data: DStream[String] = stream.map(x=>new String(x.event.getBody.array()))
    
        //6、切分每一行获取所有的单词
        val words: DStream[String] = data.flatMap(_.split(" "))
    
        //7、每个单词计为1
        val wordAndOne: DStream[(String, Int)] = words.map((_,1))
    
        //8、相同单词出现的1累加
        val result: DStream[(String, Int)] = wordAndOne.reduceByKey(_+_)
    
        //9、打印
        result.print()
    
        //10、开启流式计算
        ssc.start()
        ssc.awaitTermination()
    
      }
    
    }
    
    

7、SparkStreaming整合kafka

  • 引入依赖

            <dependency>
                <groupId>org.apache.spark</groupId>
                <artifactId>spark-streaming-kafka-0-8_2.11</artifactId>
                <version>2.1.3</version>
            </dependency>
    

7.1 KafkaUtils.createStream

  • 1、代码开发

    package demo.kafka
    
    import org.apache.spark.streaming.dstream.{DStream, ReceiverInputDStream}
    import org.apache.spark.{SparkConf, SparkContext}
    import org.apache.spark.streaming.{Seconds, StreamingContext}
    import org.apache.spark.streaming.kafka.KafkaUtils
    
    import scala.collection.immutable
    
    //todo:sparkStreaming整合kafka -------基于receiver接收器,使用了kafka高层次消费者api(消息的偏移量由zk去维护)
    object SparkStreamingKafkaReceiver {
      def main(args: Array[String]): Unit = {
        //1、创建SparkConf对象
        val sparkConf: SparkConf = new SparkConf()
                                  .setAppName("SparkStreamingKafkaReceiver")
                                  .setMaster("local[4]")
          //开启WAL日志,作用:保证数据源端的安全性,后期某些rdd的分区数据丢失了,是可以通过 血统+原始数据进行恢复
                                    .set("spark.streaming.receiver.writeAheadLog.enable","true")
    
        //2、创建SparkContext对象
        val sc = new SparkContext(sparkConf)
        sc.setLogLevel("warn")
    
        //3、创建StreamingContext,需要2个 参数,第一个是SparkContext对象,第二个是批处理时间间隔
        val ssc = new StreamingContext(sc,Seconds(5))
    
           //设置checkpoint目录,用于保存接受到的数据   实际工作中是指向HDFS目录
            ssc.checkpoint("./spark-receiver")
    
        //4、接受kafka中topic的数据
            //指定zk服务地址
            val zkQuorum="node1:2181,node2:2181,node3:2181"
           //指定消费者组id
           val groupId="spark-receiver"
           //指定topic相关信息  key:topic名称  value:表示一个receiver接收器使用多少个线程消费topic数据
            val topics=Map("itcast" ->1)
           //(String, String): 第一个String就是消息的key,第二个String就是消息的value
          //val kafkaDstream: ReceiverInputDStream[(String, String)] = KafkaUtils.createStream(ssc,zkQuorum,groupId,topics)
    
        //构建了3个receiver接收器去接受数据,加快数据的接受速度
        val kafkaDstreamList: immutable.IndexedSeq[ReceiverInputDStream[(String, String)]] = (1 to 3).map(x => {
          val kafkaDstream: ReceiverInputDStream[(String, String)] = KafkaUtils.createStream(ssc, zkQuorum, groupId, topics)
          kafkaDstream
        })
         //ssc.union方法 把多个receiver接受器产生的Dstream汇总成一个Dstream
          val totalKafkaDstream: DStream[(String, String)] = ssc.union(kafkaDstreamList)
    
    
        // kafkaDstream.print()
    
        //5、获取topic中的真实数据
          val data: DStream[String] = totalKafkaDstream.map(_._2)
    
        //6、切分每一行获取所有的单词
        val words: DStream[String] = data.flatMap(_.split(" "))
    
        //7、每个单词计为1
        val wordAndOne: DStream[(String, Int)] = words.map((_,1))
    
        //8、相同单词出现的1累加
        val result: DStream[(String, Int)] = wordAndOne.reduceByKey(_+_)
    
        //9、打印
        result.print()
    
        //10、开启流式计算
        ssc.start()
        ssc.awaitTermination()
      }
    }
    
    
  • 2、总结

    第一种方式使用了receiver接受器去接受数据,后期可以使用多个receiver接收器来加快接受的速度,使用了kafka高层次的消费者api,就是消息的偏移量由zk去维护。
    默认会出现数据的丢失,可以启动WAL日志将接受到的数据同步写入到分布式文件系统HDFS上,保证数据源端它的安全性,后面就可以使用血统+原始数据,来重新计算恢复得到丢失的数据。
    
    开启WAL日志:
    set("spark.streaming.receiver.writeAheadLog.enable","true")
    需要设置数据保存目录:
    ssc.checkpoint("目录")
    
    这种方式可以解决数据不丢失的问题,但是它解决不了数据被处理且只被处理一次。在这里由于更新偏移量到zk没有成功,导致数据正常消费成功了,没有把这个消费的标识记录下来,最后导致数据的重复消费。
    
    

7.2 KafkaUtils.createDirectStream

  • 1、代码开发

    package demo.kafka
    
    import kafka.serializer.StringDecoder
    import org.apache.spark.streaming.dstream.{DStream, InputDStream}
    import org.apache.spark.{SparkConf, SparkContext}
    import org.apache.spark.streaming.{Seconds, StreamingContext}
    import org.apache.spark.streaming.kafka.KafkaUtils
    
    //todo:sparkStreaming整合kafka -------使用消费者低级api(消息的偏移量不在由zk去维护,由客户端程序自己去维护)
    object SparkStreamingKafkaDirect {
      def main(args: Array[String]): Unit = {
        //1、创建SparkConf对象
        val sparkConf: SparkConf = new SparkConf()
          .setAppName("SparkStreamingKafkaDirect")
          .setMaster("local[4]")
    
        //2、创建SparkContext对象
        val sc = new SparkContext(sparkConf)
        sc.setLogLevel("warn")
    
        //3、创建StreamingContext,需要2个 参数,第一个是SparkContext对象,第二个是批处理时间间隔
        val ssc = new StreamingContext(sc,Seconds(5))
    
          //设置checkpoint目录 用于保存消息消费的偏移量
          ssc.checkpoint("./spark-direct")
    
        //4、接受kafka中的数据
            val kafkaParams=Map("bootstrap.servers" ->"node1:9092,node2:9092,node3:9092","group.id" ->"spark-direct")
            val topics=Set("itcast")
    
          //通过下面这种方式获取得到的Dstream它内部的rdd分区数跟kafka中topic的分区数相等。
        val kafkaDstream: InputDStream[(String, String)] = KafkaUtils.createDirectStream[String,String,StringDecoder,StringDecoder](ssc,kafkaParams,topics)
    
        //5、获取topic中的真实数据
        val data: DStream[String] = kafkaDstream.map(_._2)
    
        //6、切分每一行获取所有的单词
        val words: DStream[String] = data.flatMap(_.split(" "))
    
        //7、每个单词计为1
        val wordAndOne: DStream[(String, Int)] = words.map((_,1))
    
        //8、相同单词出现的1累加
        val result: DStream[(String, Int)] = wordAndOne.reduceByKey(_+_)
    
        //9、打印
        result.print()
    
        //10、开启流式计算
        ssc.start()
        ssc.awaitTermination()
      }
    }
    

7.3 打成jar包 集群运行

spark-submit --master spark://node1:7077 --class cn.itcast.kafka.SparkStreamingKafkaDirect --executor-memory 1g --total-executor-cores 2 spark_class12-1.0-SNAPSHOT.jar

对于实时处理来说什么情况下是比较理想的状态? 在当前批次时间内就把上一个批次的数据处理完成。
每隔10s去处理上一个10s的数据

第一个10s的数据                  -------------------------------------> 1分钟
第二个10s的数据              -------------------------------------> 1分钟
第三个10s的数据         -------------------------------------> 1分钟
.....
后面来的批次数据,一直会等待,会出现数据积压。

在企业中,我们正常通过本地开发代码程序,可以通过指定master为local,先本地测试,测试后数据没问题,可以把程序打成jar提交到集群中运行。
访问:master主机名:8080

可以先来一些资源参数进行测试:
 --executor-memory 5g --total-executor-cores 10
 --executor-memory 5g --total-executor-cores 20
 --executor-memory 10g --total-executor-cores 20
 --executor-memory 10g --total-executor-cores 30
请关注我的公众号:

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值