关于spark

RDD五大特性

转换算子与操作算子

转换算子是懒执行,直到action算子触发才会执行;一个action算子触发一个job

/**
     * 转换算子:将一个RDD转换成另一个RDD, 转换算子是懒执行,需要一个action算子来触发执行
     * 操作算子:触发任务执行,一个action算子会触发一次任务执行, 同时每一个ation算子都会触发前面的代码执行
     *
     */

    println("map之前")
    val studnetRDD: RDD[(String, String, Int, String, String)] = linesRDD
      .map(_.split(","))
      .map {
        case Array(id: String, name: String, age: String, gender: String, clazz: String) =>
          println("=======map============")
          (id, name, age.toInt, gender, clazz)
      }
    println("map之后")

    studnetRDD.foreach(println)
    println("=" * 100)
    studnetRDD.foreach(println)


    /**
     * action算子,action算子的返回值不是一个rdd, 每一个action算子都会触发一个job执行
     * foreach:循环RDD
     * saveAsTextFile:保持数据
     * count:统计行数
     * collect:将rdd转换成集合
     * take:取top
     * reduce:全局聚合
     * sum:求和,rdd必须可以求和
     *
     */

    //保持数据
    studnetRDD.saveAsTextFile("data/temp")

    //统计RDD行数
    val count: Long = studnetRDD.count()

    println(count)

    /**
     * 将rdd转换成数组
     *
     * 当处理的数据量很大时,会导致内存溢出
     */
    val studentArr: Array[(String, String, Int, String, String)] = studnetRDD.collect()

    //取top
    val top: Array[(String, String, Int, String, String)] = studnetRDD.take(100)

 数据缓存

        对于一个RDD(studentRDD)进行多次操作,则该RDD每次都会重新读取文件进行计算,因为RDD中默认不保存数据,数据只是从RDD一条一条流过,所以下次再对该RDD操作时,它会重新计算获取数据

        RDD若使用多次,可将RDD的数据进行缓存,此时RDD中就有数据,下面对该RDD进行操作时,可直接使用RDD中的数据,该RDD不用再重复计算

    //设置checkpoint保存路径
    sc.setCheckpointDir("data/checkpoint")

    //读取学生表数据
    val linesRDD: RDD[String] = sc.textFile("data/students.txt")


    //整理取出字段
    val mapRDD: RDD[Array[String]] = linesRDD.map(_.split(","))


    val studnetRDD: RDD[(String, String, Int, String, String)] = mapRDD.map {
      case Array(id: String, name: String, age: String, gender: String, clazz: String) =>
        println("=======map============")
        (id, name, age.toInt, gender, clazz)
    }

    /**
     * 对多次使用的RDD进行缓存
     *
     */

    //缓存再内存中
    //studnetRDD.cache()
    //内存放不下放磁盘,对数据做压缩
    // studnetRDD.persist(StorageLevel.MEMORY_AND_DISK_SER)
    //studnetRDD.persist(StorageLevel.MEMORY_AND_DISK)

    /**
     * checkpoint:将rdd的数据缓存到hdfs中,任务失败了数据也不会丢失
     * cache是将数据缓存再spark执行的服务器的内存或者磁盘上,如果任务执行失败数据就没了
     * persist是将数据缓存在内存或磁盘中,临时存储
     * checkpoint: 主要是再spark streaming中使用,用来保证任务的高可用
     * checkpoint:为了数据安全,会单独新开一个进程再执行一遍RDD缓存数据
     * 为了提高效率,可以结合cache 和checkpoint一起使用,则checkpoint就不会再执行一遍RDD
     */
    studnetRDD.checkpoint()

    //1、统计班级人数
    studnetRDD
      .map {
        case (_, _, _, _, clazz: String) =>
          (clazz, 1)
      }
      .reduceByKey(_ + _)
      .saveAsTextFile("data/clazz_num")

    println("=" * 100)

    //统计性别的人数
    studnetRDD
      .map {
        case (_, _, _, gender: String, _) =>
          (gender, 1)
      }
      .reduceByKey(_ + _)
      .saveAsTextFile("data/gender_num")


    //统计年龄的人数
    studnetRDD
      .map {
        case (_, _, age: Int, _, _) =>
          (age, 1)
      }
      .reduceByKey(_ + _)
      .saveAsTextFile("data/age_num")

cache:数据缓存在内存中

checkpoint:缓存在hdfs上,需设置hdfs路径;多用于spark streaming 

存在多个缓存级别;SER:压缩

累加器

//再算子内对算子外的一个普通变量进行累加,再算子外读不到累加结果
      //因为算子内的代码运行再Executor,算子外的代码运行再Driver
      //算子内的变量只是一个变量副本

    /**
     * 累加器
     *
     */
    //1、定义累加器
    val accumulator: LongAccumulator = sc.longAccumulator

    val mapRDD: RDD[String] = studentsRDD.map(stu => {

      //2、对累累加器进行累加
      accumulator.add(1)
      stu
    })

    mapRDD.foreach(println)


    //3、再Driver端读取累加结果
    println(s"accumulator:${accumulator.value}")

广播变量

/**
     * 广播变量
     * 当在算子内使用算子外的一个比较大的变量时,可以将这个变量广播出去,可以减少变量的副本数
     *
     */


    //读取学生表,以学号作为key构建一个map集合
    val studentMap: Map[String, String] = Source
      .fromFile("data/students.txt")
      .getLines()
      .toList
      .map(stu => {
        val ud: String = stu.split(",")(0)
        (ud, stu)
      })
      .toMap


    val scoresRDD: RDD[String] = sc.textFile("data/score.txt", 10)

    println(s"scoresRDD:${scoresRDD.getNumPartitions}")

    /**
     * 关联学生表和分数表
     * 循环分数表,使用学号到学生表的mao集合中查询学生的信息
     *
     */

    /**
     * 将Driver端的一个普通变量广播到Executor端
     *
     */
    val broadCastMap: Broadcast[Map[String, String]] = sc.broadcast(studentMap)

    val joinRDD: RDD[(String, String)] = scoresRDD.map(sco => {
      val id: String = sco.split(",")(0)

      //使用学号到学生表中获取学生的信息

      /**
       * 在算子内使用广播变量
       * 1、当第一个task在执行过程中如果使用了广播变量,会向Executor获取广播变量
       * 2、如果Executor中没有这个广播变量,Executor会去Driver端获取
       * 3、如果下一个task再使用到这个广播变量就可以直接用了
       *
       */
      //在算子内获取广播变量
      val map: Map[String, String] = broadCastMap.value
      val studentInfo: String = map.getOrElse(id, "默认值")

      (sco, studentInfo)
    })


    joinRDD.foreach(println)

spark的运行模式 

1、 local 本地模式

该模式主要用作测试用,一般编写的 spark 程序,将 master 设置为 local 或者 local[n],以本地模式运行,所有的代码都在一个 Jvm 里面。

2、 Mesos 模式

和 yarn 一样,Mesos 中,Spark 的资源管理从 Standalone 的 Master 转移到 Mesos Manager 中。

3、 Standalone 模式

该模式由 Spark 自带的集群管理模式,不依赖外部的资源管理器,由 Master 负责资源的分配管理,Worker 负责运行 Executor ,具体的运行过程可参考之前介绍 Spark 运行模式的篇章。

4、 yarn 模式

该模式由 yarn 负责管理整个集群资源,不再有 Master 和 Worker,根据 yarn-client 和 yarn-cluster 的不同。

yarn-client   中 driver运行在本地客户端,负责调度application,会与yarn集群产生大量的网络通信,但本地可以看见日志。

yarn-cluster 中 driver运行在yarn集群中,看不见日志。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值