spark学习笔记(四)——sparkcore核心编程-RDD

目录

RDD定义&特点

RDD处理流程

RDD核心属性

RDD基础编程

创建RDD

RDD并行度与分区

RDD转换算子

RDD行动算子

RDD序列化

RDD依赖关系

RDD持久化

RDD分区器

累加器

广播变量


RDD定义&特点

RDD(Resilient Distributed Dataset)叫做弹性分布式数据集,是 Spark 中最基本的数据处理模型。它代表一个弹性的、不可变、可分区、里面的元素可并行计算的集合。

RDD特点:

(1)弹性;

1)存储的弹性:内存与磁盘的自动切换;

2)容错的弹性:数据丢失可以自动恢复;

3)计算的弹性:计算出错重试机制;

4)分片的弹性:可根据需要重新分片。

(2)不可变: RDD 封装了计算逻辑,是不可以改变的;想要改变,只能产生新的 RDD;
(3)分布式:数据存储在集群不同节点上;
(4)可分区、并行计算;
(5)数据集:RDD 封装了计算逻辑,并不保存数据;
(6)数据抽象:RDD 是一个抽象类,需要子类具体实现。

RDD处理流程

执行原理

简单RDD处理流程

wordcount处理流程

 wordcount代码

def main(args: Array[String]): Unit = {
  //建立spark运行配置对象
  val sparkConf = new SparkConf().setMaster("local[*]").setAppName("WordCount")
  //建立连接对象
  val sc:SparkContext = new SparkContext(sparkConf)
  //读取文件
  val fileRDD: RDD[String] = sc.textFile("datas")
  //分词
  val wordRDD: RDD[String] = fileRDD.flatMap(_.split(" "))
  //数据结构转换
  val word2RDD: RDD[(String, Int)] = wordRDD.map((_,1))
  //分组聚合
  val word2count: RDD[(String, Int)] = word2RDD.reduceByKey(_+_)
  //采集结果到内存
  val wordend: Array[(String, Int)] = word2count.collect()
  //打印
  word2count.foreach(println)
  //关闭spark
  sc.stop()
}

RDD核心属性

(1)分区列表

RDD 数据结构中存在分区列表,用于执行任务时并行计算,是实现分布式计算的重要属性。

(2)分区计算函数

Spark 在计算时,是使用分区函数对每一个分区进行计算。
(3)RDD 之间的依赖关系
RDD 是计算模型的封装,当需求中需要将多个计算模型进行组合时,就需要将多个 RDD
立依赖关系。
(4)分区器
当数据为 KV 类型数据时,可以通过设定分区器自定义数据的分区。
(5)首选位置
计算数据时,可以根据计算节点的状态选择不同的节点位置进行计算。

RDD基础编程

创建RDD

1) 从集合/内存中创建RDD

从集合中创建RDD,Spark主要提供了两个方法:parallelize和makeRDD;

  def main(args: Array[String]): Unit = {

    //准备环境
    val sparkConf = new SparkConf().setMaster("local[*]").setAppName("RDD")
    val sc = new SparkContext(sparkConf)
    //创建RDD
    //从内存创建RDD,数据源为内存的数据
    //Spark主要提供了两个方法:parallelize和makeRDD
    val seq1 = Seq[Int](1,2,3,4)
    val seq2 = Seq[Int](2,4,6,8)
    //parallelize
    val rdd1: RDD[Int] = sc.parallelize(seq1)
    //makeRDD
    val rdd2: RDD[Int] = sc.makeRDD(seq2)
    rdd1.collect().foreach(println)
    rdd2.collect().foreach(println)
    //关闭环境
    sc.stop()
  }

2) 从外部文件创建RDD

从外部存储系统的数据集创建RDD;包括本地的文件系统和所有Hadoop支持的数据集, 比如HDFS、HBase;

  def main(args: Array[String]): Unit = {

    //准备环境
    val sparkConf = new SparkConf().setMaster("local[*]").setAppName("RDD")
    val sc = new SparkContext(sparkConf)
    //创建RDD
    //从文件中创建,数据源为文件
    //path路径默认为当前环境的根路径为基准,可以写绝对路径或者相对路径
    val rdd: RDD[String] = sc.textFile("datas/word1.txt")
    //sc.textFile("D:\\spark\\ec\\word.txt")本地文件路径
    //sc.textFile("hdfs://hadoop01:8020/datas/word.txt")分布式存储路径
    //sc.textFile("datas")目录路径
    //sc.textFile("datas/*.txt")通配符路径

    //sc.wholeTextFiles("datas")
    //以文件为单位读取数据,结果表示为元组,第一个为文件路径,第二个为内容
    rdd.collect().foreach(println)

    //关闭环境
    sc.stop()
  }

3) 从其他RDD创建RDD

通过一个RDD运算完后,产生新的RDD;

例:wordcount程序

4) 直接创建RDD

使用new的方式直接构造RDD,一般由Spark框架自身使用。

RDD并行度与分区

Spark将一个作业切分为多个任务,发送给Executor节点并行计算,而能够并行计算的任务数量我们称之为并行度。

这个数量可以在构建 RDD 时指定。这里的并行执行的任务数量并不是指的切分任务的数量。

例:把任务切分成100个,任务数量为100,并行度为20,并行执行的任务数量就为20。

内存

读取内存数据时,数据可以按照并行度的设定进行数据的分区操作。

  def main(args: Array[String]): Unit = {

    //环境准备
    val sparkConf = new SparkConf().setMaster("local[*]").setAppName("RDD")
    //sparkConf.set("spark.default.parallelism","4")配置4个分区(方式一)
    val sc = new SparkContext(sparkConf)

    //创建RDD
    //并行度&分区
    //sc.makeRDD(List(1,2,3,4,5,6,7,8),4)配置4个分区(方式二)
    val rdd = sc.makeRDD(List(1,2,3,4,5,6,7,8),2)

    rdd.saveAsTextFile("out")

    //关闭环境
    sc.stop()
  }

 

文件

读取文件数据时,数据是按照Hadoop文件读取的规则进行切片分区。

  def main(args: Array[String]): Unit = {

    //创建环境
    val sparkConf = new SparkConf().setMaster("local[*]").setAppName("RDD")
    val sc = new SparkContext(sparkConf)

    //创建RDD
    //textFile将文件作为数据源,默认可以分区
    //minPartitions:最小分区数
    //math.min(defaultParallelism, 2)默认分区为2
    //val rdd = sc.textFile("datas/word1.txt")默认分区
    //val rdd = sc.textFile("datas/word1.txt",3)设置最小分区数为3

    val rdd = sc.textFile("datas/word1.txt",3)
    //分区计算方式:totalSize=7,goalSize = 7/3=2...1   3分区    注:7是字节数

    //val rdd = sc.textFile("datas/word1.txt",3)
    //totalSize=9,goalSize = 7/4 =1....3    2+1=3分区

    rdd.saveAsTextFile("output1")

    //关闭环境
    sc.stop()
  }

 

RDD转换算子

spark学习笔记(五)——sparkcore核心编程-RDD转换算子_一个人的牛牛的博客-优快云博客

RDD行动算子

spark学习笔记(六)——sparkcore核心编程-RDD行动算子_一个人的牛牛的博客-优快云博客

RDD序列化

RDD依赖关系

RDD持久化

RDD分区器

spark学习笔记(七)——sparkcore核心编程-RDD序列化/依赖关系/持久化/分区器/累加器/广播变量_一个人的牛牛的博客-优快云博客

累加器

广播变量

spark学习笔记(七)——sparkcore核心编程-RDD序列化/依赖关系/持久化/分区器/累加器/广播变量_一个人的牛牛的博客-优快云博客

本文仅仅是笔记的记录!!!
### 关于蓝桥杯 2021 AB 组 第二题 完全平方数 的 Java 实现 对于蓝桥杯 2021 年赛中的完全平方数问题,可以采用枚举的方法来解决。具体来说,在给定范围内查找满足条件的整数对 \((a, b)\),使得 \(b\) 是 \(a\) 的倍数且两者均为完全平方数。 #### 方法概述 为了提高效率并减少不必要的计算量,可以通过预处理的方式先找出一定范围内的所有完全平方数,并存储在一个列表中以便后续快速访问。接着利用双重循环遍历这些预先准备好的数据集,检查每一对组合是否符合条件。 下面是具体的算法实现: ```java import java.util.ArrayList; import java.util.List; public class PerfectSquare { public static void main(String[] args) { List<Integer> squares = new ArrayList<>(); // 预处理得到所有的完全平方数 for (int i = 1; ; ++i){ int square = i * i; if (square > 1e8) break; // 设定上限防止溢出 squares.add(square); } long count = 0L; final int LIMIT = 1_0000_0000; // 枚举 a 和 b ,其中 b >= a for(int idx_a = 0; idx_a < squares.size(); ++idx_a){ int a = squares.get(idx_a); if(a*a>LIMIT || a*4>LIMIT){break;} // 提前终止 for(int idx_b = idx_a; idx_b<squares.size();++idx_b){ int b=squares.get(idx_b); if(b*LIMIT/a>b||b/LIMIT<a){continue;} // 排除非法情况 if ((long)b % a == 0 && (long)a*b<=LIMIT ) { count++; } } } System.out.println(count); } } ``` 此程序通过构建一个包含所有可能的完全平方数值的小型数组来进行高效的查询操作[^1]。注意这里设置了一个合理的上界以确保不会发生整数溢出的情况。此外,还加入了一些简单的剪枝逻辑用于加速运行时间。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值