• spark学习进度12——RDD简介


    一、简介

    RDDResilient Distributed Datasets)弹性-分布式-数据集。

    1、RDD是spark中最基本的抽象,它代表的是一个只读的不能被改变的被分区的数据集。spark中存在很多的方法,这些方法都可以进行操作RDD,而这些方法就叫做算子。算子用来操作RDD的,算子的分类:转换类[transFormation]和行动类[action]。

    2、特点

    • 只读:一旦创建,不能被修改,因为RDD是一个抽象。

    • 不可变:一旦创建,不能被修改,只能生成新的RDD.

    • 弹性:可变大变小,默认优先使用内存,如果超大的话借助磁盘。

    • 分布式:其实就是分区的概念,并行处理执行的,逻辑一样,但是数据不一样。

    • 数据集:一系列数据放在集合中的表示。

    • 高容错性:通过RDD中的血缘关系,也就是上一个RDD和下一个RDD之间通过算子的相互依赖关系。

    • 分区:RDD肯定是分区的,不然不可能被多个Executor执行。每个Executor中的task任务对应的是一个分区中的数据。所以有多少个分区就有多少个task任务。所以RDD在创建的时候会被分区。

    • 底层:RDD是一个抽象类,在抽象类中有很多的实现类。


    二、创建方式

    1、makeRDD-集合并行化

    (1)集合并行化或者makeRDD产生的RDD是:ParallelCollectionRDD

    [将集合转换为RDD的方式称为集合并行化的创建方式,用于测试]

    (2)makeRDD:  【只要是集合都可以进行创建RDD

     

    val a=Array(1,2,3)
    sc.makeRDD(a)  //or: sc.parallelize(a)

     

    说明:makeRDD底层调用的就是parallelize(collection集合并行化)

    2、读取外部文件形式

    (1)读取外部文件产生的RDD是:MapPartitionsRDD

    (2)textFile就是读取文件的--可读本地文件,同时也能读取hdfs文件。

     sc.textFile("hdfs://1803-spark4:50070/in/word.txt")

    (3)读取本地文件:做测试的时候偶尔可以使用,但是后期在处理数据的时候都是读取外部文件的形式。

    sc.textFile("/home/data/a.txt")

    3、使用转换类算子进行创建

    (1)通过算子产生RDD,会产生各种类型的RDD

    val rdd1: RDD[String] = sc.textFile(input)
    val rdd2 = rdd1.flatMap(a=>a.split(" "))
    val rdd3 = rdd2.map(a=>(a,1))
    val rdd4 = rdd3.reduceByKey(_+_)

    (2)调用转换类算子会生成新的rdd,而调用行动类算子不会生成新的rdd,行动类算子只能是执行。

    转换类算子:    一个RDD转换为另一个RDD,map、flatMap、groupBy、sortBy ....遇到行动类才触发程序执行

    行动类算子:    colleact、reduce、foreach..... 

     


     

    三、RDD分区

    1、创建

     

    (1)、集合并行化的方式创建分区: [默认根据cores数自动分区,可以手动设置分区数量]

    总共4个cores,所以创建了4个分区,有多少cores创建多少个分区。Cpu有多少个cores,就证明这个集群能并行执行处理多少个任务,所以系统在创建RDD的时候做到了最大并行化。

    问题:excutor总共有3个,每个excutor有4个cores,一个Executor可以并行处理4个分区中的数据,也就是可以同时执行4个task.

    (2)、读取外部文件的形式创建分区:

    读取外部文件的时候分区的数量是变化的。因为读取外部文件的时候分区的数量=文件的block数量【如果block的数量如果小于2,那么分区默认就是2,如果大于2那么就是具体的block的数量,有多少个block就有多少个分区,然后要给task任务处理一个分区中的任务】。

    (3)、转换类算子产生的分区: [转换类算子产生的新的RDD,分区默认不改变]

     (4)总结:

    • 1-通过集合并行化的形式:有多少个cores就会产生多少个分区;可以手动修改;

    • 2-通过读取HDFS文件的形式产生分区,有多少个block块就会产生多少个分区。

    • 3-调用转换类算子产生的分区,转换类算子产生新的RDD默认分区数量不变。

    2、修改分区数量的方法

    分区的数量决定了任务并行化处理任务的程度

     

    (1)集合并行化创建RDD的时候可以手动的设置分区数量

     

    (2)读取外部文件的形式,使用手动修改分区数量的方式失效。可以控制,但是不能完全控制读取HDFS文件数据的分区

    (3)通过算子转换的RDD默认情况下分区数量不变,但是可以使用算子修改分区数量

     

    sc.makeRDD(a,3)
    res0.reduceByKey(_+_,4)

     

    3、总结

    (1)一般情况下,不会手动设置分区数量。

    (2)使用3个特殊的转换类算子。

    使用reduceByKey  groupByKey  distinct 一般不常用

    常用的改变分区的算子有:coalesce(合并)  repartition(再分配) 

     


     

    四、总结

     

    1、集合并行化;默认的分区数量是集群cores的总数

     

    makeRDD(seq,numpartition)   

     

    parallelize(seq,numpartition)

     

    2、读取hdfs文件,默认的分区数量是block块的数量,如果block的数量小于2默认就是2

    sc.textFile(path,numberPartitions),如果修改分区的时候,必须大于block,不一定设定多少就是多少,是自适配的。

    3、RDD转换类算子生成新的RDD,默认情况下,分区数量不会发生改变,除了3个特殊的转换类算子。

     

    简单来说,RDD的分区数量决定了任务并行化的程度,根据核数进行合适的分区。

     

     

     

     

     

     

     

  • 相关阅读:
    编译hadoop eclipse的插件(hadoop1.0)
    HBase体系结构剖析
    hadoop2.6完全分布式安装HBase1.1
    HDFS主要特性和体系结构
    一些C语言学习的国外资源
    一个监控系统进程网络流量的程序
    python解析发往本机的数据包示例 (解析数据包)
    使用Fiddler抓包调试https下的页面
    fiddler Android下https抓包全攻略
    C++使用hiredis连接带密码的redis服务
  • 原文地址:https://www.cnblogs.com/znjy/p/15790455.html
Copyright © 2020-2023  润新知