【Spark | Spark-Core篇】RDD(弹性分布式数据集)概述

1. 什么是RDD

RDD(Resilient Distributed Dataset)叫做弹性分布式数据集,是Spark中最基本的数据抽象。

代码中是一个抽象类,它代表一个弹性的、不可变、可分区、里面的元素可并行计算的集合。

RDD类比工厂生产。

2. RDD五大特性

3. RDD的创建

3.1 内存中(集合)创建RDD

Scala 复制代码
object Spark01_RDD_Memory {
  def main(args: Array[String]): Unit = {
    // TODO 准备环境
    val sparkConf = new SparkConf().setMaster("local[*]").setAppName("RDD")

    val sc = new SparkContext(sparkConf)

    // 从内存中创建RDD,将内存中集合的数据作为处理的数据源
//    val rdd = sc.makeRDD(List(1, 2, 3, 4))
    // makeRDD方法第二个参数不写默认的是,分区个数=cpu的核数

    // 如果给了第二个参数,即rdd有两个分区
    val rdd = sc.makeRDD(List(1, 2, 3, 4), 2)
    
    // 将分区信息保存在datas文件夹下
    rdd.saveAsTextFile("datas")


    // 关闭环境
    sc.stop()

  }
}

// datas下的文件分区信息

3.2 从外部存储系统的数据集创建

由外部存储系统的数据集创建RDD包括:本地的文件系统,还有所有Hadoop支持的数据集,比如HDFS、HBase等。

Scala 复制代码
object Spark01_RDD_File {
  def main(args: Array[String]): Unit = {
    // TODO 准备环境
    val sparkConf = new SparkConf().setMaster("local[*]").setAppName("RDD")

    val sc = new SparkContext(sparkConf)

    // TODO 创建RDD
    // 从文件中创建RDD,将文件中的数据作为处理的数据源
    // path路径默认当前的环境路径为基准,可以写绝对路径,也可相对路径
    // path可以是文件的具体路径,也可以是目录名称
    val rdd = sc.textFile("datas/1.txt")
    // 以行为单位读取数据
    rdd.collect().foreach(println)
    // 输出:
    //hello scala
    //hello spark
    //hello java

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

  }
}

4. RDD并行度与分区

4.1 内存创建的RDD的分区

默认情况下,Spark可以将一个作业切分为多个任务后,发送给Executer节点开始计算,而能够并行计算的任务数量我们称之为并行度。这个数量可以在创建RDD的时候指定。注意,这里的并行执行的任务数量,并不是指切分任务的数量。

RDD方法可以传递第二个参数,这个参数表示分区的数量。

但第二个参数也可以不传递,那么RDD将使用默认值:查看源码发现:

Scala 复制代码
numSlices: Int = defaultParallelism

4.2 文件中创建的RDD分区

可以查看textfire方法中可以传入第二个参数minPartitions,最小分区个数。

Scala 复制代码
minPartitions: Int = defaultMinPartitions

def defaultMinPartitions: Int = math.min(defaultParallelism, 2)

如果不传入第二个参数,默认填写的最小分区数 2和环境的核数取小的值 一般为2

5. 集合中分区数据的分配

Scala 复制代码
object Spark01_RDD_Memory_Par1 {
  def main(args: Array[String]): Unit = {
    // TODO 准备环境
    val sparkConf = new SparkConf().setMaster("local[*]").setAppName("RDD")

    val sc = new SparkContext(sparkConf)

    val rdd = sc.makeRDD(List(1, 2, 3, 4), 2)
    // 如果makeRDD方法的第二个参数numSlices为2,很容易想到将会创建两个分区
    // 一个是1, 2.
    // 一个是3, 4

    rdd.saveAsTextFile("datas")

    // 关闭环境
    sc.stop()

  }
}
Scala 复制代码
object Spark01_RDD_Memory_Par1 {
  def main(args: Array[String]): Unit = {
    // TODO 准备环境
    val sparkConf = new SparkConf().setMaster("local[*]").setAppName("RDD")

    val sc = new SparkContext(sparkConf)

//    val rdd = sc.makeRDD(List(1, 2, 3, 4), 2)
    // 如果makeRDD方法的第二个参数numSlices为2,很容易想到将会创建两个分区
    // 一个是1, 2.
    // 一个是3, 4


    // 如果numSlices为3的话,将会产生三个分区文件,那么4个数据是如何分配到3的分区文件的呢?
    val rdd = sc.makeRDD(List(1, 2, 3, 4), 3)

    rdd.saveAsTextFile("datas")

    // 关闭环境
    sc.stop()

  }
}

为什么1,2, 3, 4分配到三个分区中分配为什么会是[1], [2], [3, 4]呢

查看源码:

Scala 复制代码
def positions(length: Long, numSlices: Int): Iterator[(Int, Int)] = {
      (0 until numSlices).iterator.map { i =>
        val start = ((i * length) / numSlices).toInt
        val end = (((i + 1) * length) / numSlices).toInt
        (start, end)
      }
    }

返回一个元组:

以numSlices为3为例:0到3(但取不到3)的迭代器:i从0开始,start计算为:0;end计算得到为:1 * 4 / 3 = 1 => (0, 1)但1取不到,即第一个分区文件为List(1, 2, 3, 4)索引为0的元素。

.......

6. 文件中分区数据的分配

发现textFire方法内有hadoopFire方法。说明spark读取文件的方式是跟hadoop是一样的。

// 具体的分区个数需要经过公式计算

// 首先获取文件的总长度 totalSize

// 计算平均长度 goalSize = totalSize / numSplits

// 获取块大小 128M

// 计算切分大小 splitSize = Math.max(minSize, Math.min(goalSize, blockSize));

// 最后使用splitSize 按照1.1倍原则切分整个文件 得到几个分区就是几个分区

// 实际开发中 只需要看文件总大小 / 填写的分区数 和块大小比较 谁小拿谁进行切分

lineRDD.saveAsTextFile("output");

// 数据会分配到哪个分区

// 如果切分的位置位于一行的中间 会在当前分区读完一整行数据

①分区数量的计算方式:

totalSize = 10

goalSize = 10 / 3 = 3(byte) 表示每个分区存储3字节的数据

分区数= totalSize/ goalSize = 10 /3 => 3,3,4

4子节大于3子节的1.1倍,符合hadoop切片1.1倍的策略,因此会多创建一个分区,即一共有4个分区 3,3,3,1

②Spark读取文件,采用的是hadoop的方式读取,所以一行一行读取,跟字节数没有关系

③数据读取位置计算是以偏移量为单位来进行计算的。

相关推荐
Java 第一深情42 分钟前
零基础入门Flink,掌握基本使用方法
大数据·flink·实时计算
MXsoft6181 小时前
华为服务器(iBMC)硬件监控指标解读
大数据·运维·数据库
PersistJiao2 小时前
Spark 分布式计算中网络传输和序列化的关系(二)
大数据·网络·spark·序列化·分布式计算
九河云2 小时前
如何对AWS进行节省
大数据·云计算·aws
FreeIPCC2 小时前
谈一下开源生态对 AI人工智能大模型的促进作用
大数据·人工智能·机器人·开源
梦幻通灵3 小时前
ES分词环境实战
大数据·elasticsearch·搜索引擎
Elastic 中国社区官方博客3 小时前
Elasticsearch 中的热点以及如何使用 AutoOps 解决它们
大数据·运维·elasticsearch·搜索引擎·全文检索
天冬忘忧3 小时前
Kafka 工作流程解析:从 Broker 工作原理、节点的服役、退役、副本的生成到数据存储与读写优化
大数据·分布式·kafka
sevevty-seven4 小时前
幻读是什么?用什么隔离级别可以防止幻读
大数据·sql
Yz98766 小时前
hive复杂数据类型Array & Map & Struct & 炸裂函数explode
大数据·数据库·数据仓库·hive·hadoop·数据库开发·big data