Spark03:RDD编程接口

2024-09-01 08:18
文章标签 接口 编程 rdd spark03

本文主要是介绍Spark03:RDD编程接口,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

公众号:数据挖掘与机器学习笔记

Spark中提供了通用接口来抽象每个RDD,包括:

  • 分区信息:数据集的最小分片
  • 依赖关系:指向其父RDD
  • 函数:基于父RDD的计算方法
  • 划分策略和数据位置的元数据

image-20200902104853809

1.RDD分区

RDD的分区是一个逻辑概念,变换前后的新旧分区在物理上可能是同一块内存或存储,这种优化防止函数式不变性导致的内存需求无限扩张。在RDD操作中可以使用Partitions方法获取RDD划分的分区数,也可以设定分区数目。如果没有指定将使用默认值,而默认数值是该程序所分配到的CPU核数,如果是从HDFS文件创建,默认为文件的数据块数。

//默认两个分区
val part=sc.textFile("input/input1.txt")
println(part.partitions.size)//显式设置为4个partitions
val part=sc.textFile("input/input1.txt",minPartitions = 4)
println(part.partitions.size)

2. RDD首选位置(PreferredLocations)

Spark在形成任务的DAG时,会尽可能把计算分配到靠近数据的位置,减少数据网络传输。当RDD产生的时候存在首选位置,如HadoopRDD分区的首选位置就是HDFS块所在的节点;当RDD分区被缓存,则计算应该发送到缓存分区所在的节点进行,再不然回溯RDD的“血统”一直找到具有首选位置属性的父RDD,并据此决定子RDD的位置。

3.RDD依赖关系

Spark中RDD存在两种依赖:窄依赖(Narrow Dependencies)和宽依赖(Wide Dependencies)。

image-20200902111336831
  • 窄依赖:每个父RDD的分区至多被一个子RDD的分区使用
  • 宽依赖:多个子RDD的分区依赖一个父RDD的分区

区别:

  • 窄依赖允许在单个集群节点上流水线式执行,这个节点可以计算所有父级分区;宽依赖需要所有父RDD的数据可用,并且数据已经通过类MR操作Shuffle完成
  • 在窄依赖中,节点失败后的恢复更加高效。因为只有丢失的父级分区重新计算,并且这些丢失的父级分区可以并行地在不同节点上重新计算。而在宽依赖地继承关系中,单个节点地失败可能导致一个RDD的所有祖先RDD中的一些分区丢失,导致计算的重新执行。
val part = sc.textFile("input/input1.txt")val wordmap = part.flatMap(_.split(" ")).map(x => (x, 1))println(wordmap)//wordmap的依赖关系为OneToOneDependency,属于窄依赖wordmap.dependencies.foreach {dep =>println("dependency type:" + dep.getClass)println("dependency RDD:" + dep.rdd)println("dependency partitions:" + dep.rdd.partitions)println("dependency partitions size:" + dep.rdd.partitions.length)}val wordreduce = wordmap.reduceByKey(_ + _)println(wordreduce)wordreduce.dependencies.foreach{dep =>println("dependency type:" + dep.getClass)println("dependency RDD:" + dep.rdd)println("dependency partitions:" + dep.rdd.partitions)println("dependency partitions size:" + dep.rdd.partitions.length)}
image-20200903100355916

4.RDD分区计算

RDD的基本单位是partition,计算函数都是对迭代器进行复合,不需要保存每次计算的结果。如mapPartitions对每个分区内容作为整体来处理。

 val a = sc.parallelize(1 to 12, 3)a.mapPartitions {x =>var res = List[(Int, Int)]()var pre = x.next()while (x.hasNext) {val cur = x.next()res ::= (pre, cur)pre = cur}res.iterator}.foreach(t2 => print(t2))

image-20200903101735418

上述代码把每个分区中的元素和下一个元素组成一个Tuple,因为分区中最后一个元素没有下一个元素,所以没有(4,5)和(8,9)

5. RDD分区函数

分区的划分对于Shuffle类操作很关键,决定了该操作的父RDD和子RDD之间的依赖类型。在Spark中默认提供两种分区划分器:哈希分区划分器(HashPartitioner)和范围分区划分器(RangePartitioner),且Partitioner只存在于(K,V)类型的RDD中,对于非(K,V)类型的Partitioner值为None。

    val mapRDD = sc.textFile("input/input1.txt")println(mapRDD.partitioner)val groupRDD = mapRDD.map(x => (x, x)).groupByKey(new HashPartitioner(4))print(groupRDD.partitioner)

参考:

[1]《图解Spark:核心技术与案里实战》
在这里插入图片描述

这篇关于Spark03:RDD编程接口的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1126406

相关文章

揭秘Python Socket网络编程的7种硬核用法

《揭秘PythonSocket网络编程的7种硬核用法》Socket不仅能做聊天室,还能干一大堆硬核操作,这篇文章就带大家看看Python网络编程的7种超实用玩法,感兴趣的小伙伴可以跟随小编一起... 目录1.端口扫描器:探测开放端口2.简易 HTTP 服务器:10 秒搭个网页3.局域网游戏:多人联机对战4.

Java并发编程必备之Synchronized关键字深入解析

《Java并发编程必备之Synchronized关键字深入解析》本文我们深入探索了Java中的Synchronized关键字,包括其互斥性和可重入性的特性,文章详细介绍了Synchronized的三种... 目录一、前言二、Synchronized关键字2.1 Synchronized的特性1. 互斥2.

go中空接口的具体使用

《go中空接口的具体使用》空接口是一种特殊的接口类型,它不包含任何方法,本文主要介绍了go中空接口的具体使用,具有一定的参考价值,感兴趣的可以了解一下... 目录接口-空接口1. 什么是空接口?2. 如何使用空接口?第一,第二,第三,3. 空接口几个要注意的坑坑1:坑2:坑3:接口-空接口1. 什么是空接

Python异步编程中asyncio.gather的并发控制详解

《Python异步编程中asyncio.gather的并发控制详解》在Python异步编程生态中,asyncio.gather是并发任务调度的核心工具,本文将通过实际场景和代码示例,展示如何结合信号量... 目录一、asyncio.gather的原始行为解析二、信号量控制法:给并发装上"节流阀"三、进阶控制

如何用java对接微信小程序下单后的发货接口

《如何用java对接微信小程序下单后的发货接口》:本文主要介绍在微信小程序后台实现发货通知的步骤,包括获取Access_token、使用RestTemplate调用发货接口、处理AccessTok... 目录配置参数 调用代码获取Access_token调用发货的接口类注意点总结配置参数 首先需要获取Ac

讯飞webapi语音识别接口调用示例代码(python)

《讯飞webapi语音识别接口调用示例代码(python)》:本文主要介绍如何使用Python3调用讯飞WebAPI语音识别接口,重点解决了在处理语音识别结果时判断是否为最后一帧的问题,通过运行代... 目录前言一、环境二、引入库三、代码实例四、运行结果五、总结前言基于python3 讯飞webAPI语音

MyBatis-Plus中Service接口的lambdaUpdate用法及实例分析

《MyBatis-Plus中Service接口的lambdaUpdate用法及实例分析》本文将详细讲解MyBatis-Plus中的lambdaUpdate用法,并提供丰富的案例来帮助读者更好地理解和应... 目录深入探索MyBATis-Plus中Service接口的lambdaUpdate用法及示例案例背景

Java8需要知道的4个函数式接口简单教程

《Java8需要知道的4个函数式接口简单教程》:本文主要介绍Java8中引入的函数式接口,包括Consumer、Supplier、Predicate和Function,以及它们的用法和特点,文中... 目录什么是函数是接口?Consumer接口定义核心特点注意事项常见用法1.基本用法2.结合andThen链

Deepseek R1模型本地化部署+API接口调用详细教程(释放AI生产力)

《DeepseekR1模型本地化部署+API接口调用详细教程(释放AI生产力)》本文介绍了本地部署DeepSeekR1模型和通过API调用将其集成到VSCode中的过程,作者详细步骤展示了如何下载和... 目录前言一、deepseek R1模型与chatGPT o1系列模型对比二、本地部署步骤1.安装oll

MyBatis-Flex BaseMapper的接口基本用法小结

《MyBatis-FlexBaseMapper的接口基本用法小结》本文主要介绍了MyBatis-FlexBaseMapper的接口基本用法小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具... 目录MyBATis-Flex简单介绍特性基础方法INSERT① insert② insertSelec