Spark-RDD编程(三)

3.持久化

我们知道RDD采用惰性机制,这对于迭代计算而言,代价是很大的,因为迭代计算经常需要多次重复使用同一组数据。

为了解决这一问题,我们可以通过持久化(缓存)机制来避免这种重复计算的开销。具体方法是使用persist()方法将一个RDD标记为持久化。


持久化RDD会占用内存空间,当不再需要一个RDD时,就可以使用unpersist()方法手动地把持久化的RDD从缓存中移除,释放内存空间。

4.分区

4.1分区的作用

RDD是弹性分布式数据集,通常RDD很大,会被分成很多个分区,分别保存在不同的节点上。

对RDD进行分区,第一个作用是增加并行度,第二个作用是减少通信开销。

4.2分区的原则

RDD分区的一个原则是时得分区的个数尽量等于集群中CPU核心(Core)数目。对于不同的Spark部署模式,都可以通过设置spark.default.parallelism这个参数的值,来配置默认的分区数目。

设置分区的个数

4.2.1创建RDD时手动设置分区个数
  def main(args: Array[String]): Unit = {
    val conf: SparkConf = new SparkConf().setMaster("local[*]").setAppName(this.getClass.getName)
    val sc = new SparkContext(conf)
    sc.textFile(path,minPartitions)
  }

//path指定加载文件的路径,minPartitions用于指定分区数
4.2.2使用repartition()方法重新设置分区个数
>>> data = sc.parallelize([1,2,3,4,5],2)
>>> len(data.glom().collect()) #显示data这个RDD的分区数量
2
>>> rdd = data.repartition(1) #对data这个RDD进行重新分区
>>> len(rdd.glom().collect()) #显示rdd这个RDD的分区数量
1
4.2.3自定义分区方法

Spark提供了自带的HashPartitioner(哈希分区)与RangePartitioner(区域 分区),能够满足大多数应用场景的需求。与此同时,Spark也支持自定义分 区方式,即通过提供一个自定义的分区函数来控制RDD的分区方式,从而利 用领域知识进一步减少通信开销

5 键值对RDD

键值对RDD是指每个RDD元素都是(Key,Values)键值对类型,是一种常见的RDD类型,可以应用于很多场景。

5.1 键值对RDD的创建

键值对RDD的创建主要有两种方式:从文件中加载生成RDD;通过并行集合(列表)创建RDD。

这和上面RDD创建类似,就是我们要对每个key值赋一个values。

    val conf: SparkConf = new SparkConf().setMaster("local[*]").setAppName(this.getClass.getName)
    val sc = new SparkContext(conf)
    val rdd: RDD[Int] = sc.makeRDD(1 to (10),1)
    val rdd2: RDD[(Int, Int)] = rdd.map((_, 1))
  }

5.2 常用的键值对转换操作

reduceByKey()和groupByKey()上面已经介绍过,不在重复介绍

5.2.1 keys()

键值对RDD每个元素都是(Key,Values)的形式,keys方法啊只会把键值对RDD中的key返回,形成一个新的RDD。

  def main(args: Array[String]): Unit = {
    val conf: SparkConf = new SparkConf().setMaster("local[*]").setAppName(this.getClass.getName)
    val sc = new SparkContext(conf)
    val rdd: RDD[(String, Int)] = sc.makeRDD(Array(("jack", 18), ("tom", 16), ("luck", 20)))
    val rddKey: RDD[String] = rdd.keys
    println(rddKey.collect().toBuffer) //结果ArrayBuffer(jack, tom, luck)
  }

5.2.2 values()

values操作只会把键值对RDD中的values返回,形成一个新的RDD。

    val rddValues: RDD[Int] = rdd.values
    println(rddValues.collect().toBuffer)  //结果ArrayBuffer(18, 16, 20)

5.2.3sortByKey()

sortByKey()的功能是返回一个根据key排序的RDD。

    val rdd: RDD[(String, Int)] = sc.makeRDD(Array(("jack", 18), ("tom", 16), ("luck", 20),("david",12)))
    val rddSort: RDD[(String, Int)] = rdd.sortByKey() //括号内填false即倒序
    println(rddSort.collect().toBuffer)
  }
//结果ArrayBuffer((david,12), (jack,18), (luck,20), (tom,16))
//字符串根据字典顺序排序

5.2.4 sortBy()

可以根据其他字段进行排序。

    val rdd: RDD[(String, Int)] = sc.makeRDD(Array(("jack", 18), ("tom", 16), ("luck", 20),("david",12)))
    val rddSort: RDD[(String, Int)] = rdd.sortBy(_._2) //根据数字排序
    println(rddSort.collect().toBuffer)  //结果 ArrayBuffer((david,12), (tom,16), (jack,18), (luck,20))

5.2.5 mapValues(func)

mapValues(func)对键值对RDD中每个value都应用一个函数,但是,key不会发生变化。

    val rdd: RDD[(String, Int)] = sc.makeRDD(Array(("jack", 18), ("tom", 16), ("luck", 20),                    ("david",12)))
    val rddSort: RDD[(String, Int)] = rdd.mapValues((_*10))
    println(rddSort.collect().toBuffer)  
    //结果 ArrayBuffer((jack,180), (tom,160), (luck,200), (david,120))

5.2.6  join()

join表示内连接,对于给定的两个输入数据集(K,V1),(K,V2),只有在两个数据集中都存在的key才会被输出,最终得到一个(K,(V1,V2))类型的数据集。

    val rdd1: RDD[(String, Int)] = sc.makeRDD(Array(("jack", 80), ("tom", 68), ("luck", 78),("david",88)))
    val rdd2: RDD[(String, Int)] = sc.makeRDD(Array(("jack", 81), ("tom", 87), ("luck", 58),("david",87)))
    val res: RDD[(String, (Int, Int))] = rdd1.join(rdd2)
    println(res.collect().toBuffer)  
    //结果 ArrayBuffer((luck,(78,58)), (tom,(68,87)), (david,(88,87)), (jack,(80,81)))

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值