源码跟踪,案例详解Spark的分区规则

news2024/12/24 9:45:32

水善利万物而不争,处众人之所恶,故几于道💦

目录

一、默认分区规则

  1. 从集合中创建RDD - makeRDD
  2. 读取外部存储系统创建RDD - textFile

二、指定分区规则

  1. 从集合中创建RDD指定分区 - makeRDD
  2. 读取外部存储系统创建RDD指定分区 - textFile


一、默认分区规则

  spark中有三种创建RDD的方式:从集合中创建(parallelize和makeRDD)、从外部存储系统的数据集创建(textFile)、从其他RDD的转换创建。创建的时候分区可以不指定,他会有一个默认的分区规则,那这个默认的分区规则是什么呢?下面就以makeRDDtextFile为例进行分析。

1. 从集合中创建RDD - makeRDD

  从集合中创建RDD时,默认的分区规则是分配给应用的CPU核数,也就是创建SparkConf对象时,设置的setMaster参数。

在这里插入图片描述


  综上所述:如果通过集合创建RDD,默认的分区规则是:分配给应用的CPU核数,如果local[*]是这台机器的CPU个数就是分区数,local只有一个分区


2. 读取外部存储系统创建RDD - textFile

  读取外部文件创建RDD的话,默认的分区规则是min(分配给应用的cpu核数,2)

在这里插入图片描述

二、指定分区规则

1. 从集合中创建RDD指定分区 - makeRDD

// 创建SparkConf并设置App名称及运行模式
val conf: SparkConf = new SparkConf().setAppName("SparkCoreStudy").setMaster("local[*]")

// 创建SparkContext,该对象是提交Spark App的入口
val sc = new SparkContext(conf)

// 指定3个分区,实际输出3个分区     0分区->1, 1分区->2, 3分区->3 4
//    val rdd: RDD[Int] = sc.makeRDD(List(1, 2, 3, 4),3)

// 指定4个分区,实际输出4个分区    0分区->1  ,  1分区->2   ,  2分区->3  ,  3分区->4 5   
//    val rdd: RDD[Int] = sc.makeRDD(List(1, 2, 3, 4,5),4)

// 指定5个分区,实际输出5个分区      0分区->1  ,  1分区->2   ,  2分区->3  ,  3分区->4   ,  4分区->5
//    val rdd: RDD[Int] = sc.makeRDD(List(1, 2, 3, 4,5),5)

// 指定3个分区,实际输出3个分区      0分区-> a  ,  1分区-> b c   ,  2分区->  d e
val rdd: RDD[String] = sc.makeRDD(List("a","b","c","d","e"),3)

rdd.saveAsTextFile("F:\\IdeaProjects\\spark\\output")

// 关闭连接
sc.stop()

  集合中创建RDD,指定分区数是多少,实际就分几个区。除了分几个区后,我们还关心每个分区中数据怎么存放。

在这里插入图片描述
  通过跟踪代码,我们发现切片的具体过程是:用集合的长度和分区数进行运算然后求出一个分区的下标范围(这个范围是前闭后开的),然后将集合中这个下标范围的数据放到这个分区中。

  根据集合长度和分区数的具体计算逻辑是:

     起始位置下标 = (分区号*集合长度)/分区数
     结束位置下标 = ((分区号+1)*集合长度)/分区数

  说明:分区号和分区数不一样,分区号是分区的编号,从0号分区开始,分区数是你指定的几个分区。

例如:集合长度为5,我指定3个分区,那么
 0号分区的起始位置下标=(0*5)/3=0,结束位置下标=(1*5)/3=1 => [0,1)
 1号分区的起始位置下标=(1*5)/3=1,结束位置下标=(2*5)/3=3 => [1,3)
 2号分区的起始位置下标=(2*5)/3=3,结束位置下标=(3*5)/3=5 => [3,5)


2. 读取外部存储系统创建RDD指定分区 - textFile

  在textFile方法中,第二个参数minPartitions,表示最小分区数,是最小,不是实际的分区个数,实际几个分区会通过要读取的文件总大小和最小分区数进行计算得出。

// 创建SparkConf并设置App名称及运行模式
val conf: SparkConf = new SparkConf().setAppName("SparkCoreStudy").setMaster("local[*]")

// 创建SparkContext,该对象是提交Spark App的入口
val sc = new SparkContext(conf)

sc.textFile("F:\\IdeaProjects\\spark\\input\\19b.txt",5).saveAsTextFile("F:\\IdeaProjects\\spark\\output")

// 关闭连接
sc.stop()

  上述代码中,读取的本地文件的大小为19字节,最小分区数是5,则实际输出7个分区。

在这里插入图片描述

  通过源码的追踪,发现读取外部文件的实际分区是:剩余待切片的大小/目标大小,结果是否大于1.1,如果大于1.1则切一片,起始位置是0,结束位置是0+goalSize,然后再根据剩余的判断,如果不大于1.1,则再单独切一片就行了。注意实际读取的时候是TextInputFormat中的getRecordReader方法,但是这个方法使用LineRecordReader方法读,它是一行一行读的,停不住,也就是说读到这一行,这一行都会被读完,从而放到一个分区里面

例如:文件大小为19字节,我指定5个分区,那么

goalSize = 19/5 = 3  也就是说3个字节一片

分区切片规划(切片区间)剩余切片大小是否>1.1
0[0,0+3]19-3=1616/3 - 是
1[3,3+3]16-3=1313/3 - 是
2[6,6+3]13-3=1010/3 - 是
3[9,9+3]10-3=76/3 - 是
4[12,12+3]7-3=44/3 - 是
5[15,15+3]4-3=11/3 - 否
6[18,18+1]只要不大于1.1不管剩下多少都是一个切片

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/788117.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于Java+SpringBoot+vue前后端分离甘肃非物质文化网站设计实现

博主介绍:✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专…

TCP/UDP的首部

TCP/UDP首部信息 TCP首部第一个4字节第二个4字节与第三个4字节第四个4字节第五个4字节选项最大报文段长度(MSS)选项窗口扩大选项时间戳选项 什么时候发送RST包UDP首部 TCP首部 TCP 首部长度为20字节,加上选项部分最大可达60字节。 第一个4…

移动端商品详情页设计

效果图 代码如下 页面设计 <div class"container"><!--商品详情 start--><van-image class"goods-item-image" :src"goods.goodsHeadImg"></van-image><div class"goods-price">&#xffe5;<span&…

MySQL函数讲解(谓词、CASE)

目录 MySQL常见函数 字符串函数 进行字符串操作的函数 算术函数 进行数值计算的函数 日期函数 进行日期操作的函数 转换函数 进行数据类型和值转换的函数 流程函数 进行条件删选 聚合函数 进行数据聚合的函数 谓词 一般用于条件判断 什么是函数 函数指一段可以直接被…

web前端tips:js继承——原型链继承

原型链继承 原型链继承是 JavaScript 中实现继承的一种方式&#xff0c;它通过使用原型来实现对象之间的继承关系。 在 JavaScript 中&#xff0c;每个对象都有一个原型&#xff08;prototype&#xff09;&#xff0c;它是一个指向另一个对象的引用。当我们访问一个对象的属性…

Quartz线程调度源码分析

Quartz作为任务调度的组件&#xff0c;其中涉及到多种线程&#xff0c;主要分为主线程、调度线程和工作线程。 主线程&#xff1a;创建Quartz的调度工厂(SchedulerFactory)、调度器(Scheduler)、触发器(Trigger)、任务&#xff08;Job&#xff09;并启动调度器的线程。这里的主…

Pytest结合数据驱动-yaml

Pytest 结合数据驱动 YAML 数据驱动 什么是数据驱动&#xff1f; 数据驱动就是数据的改变从而驱动自动化测试的执行&#xff0c;最终引起测试结果的改变。简单来说&#xff0c;就是参数化的应用。数据量小的测试用例可以使用代码的参数化来实现数据驱动&#xff0c;数据量大的…

Ceph社区上游正式合入openEuler原生支持,并通过CI持续验证

作为覆盖全场景应用、支持多样性算力的面向数字基础设施的开源操作系统&#xff0c;openEuler始终遵循“上游优先”的策略&#xff0c;帮助上游开源软件原生支持openEuler&#xff0c;让openEuler系操作系统的用户可以在开发、集成、使用这些开源软件或基于这些开源软件的产品和…

比较版本号(力扣)思维 JAVA

给你两个版本号 version1 和 version2 &#xff0c;请你比较它们。 版本号由一个或多个修订号组成&#xff0c;各修订号由一个 ‘.’ 连接。每个修订号由 多位数字 组成&#xff0c;可能包含 前导零。每个版本号至少包含一个字符。修订号从左到右编号&#xff0c;下标从 0 开始…

vue3+ts+elementui-plus二次封装树形表格

复制粘贴即可&#xff1a; 一、定义table组件 <template><div classmain><div><el-table ref"multipleTableRef" :height"height" :default-expand-all"isExpend" :data"treeTableData"style"width: 100%…

IL汇编字符串连接

在此实现了一个基本的IL汇编程序&#xff1b; 了解MSIL汇编和IL汇编评估堆栈_bcbobo21cn的博客-CSDN博客 它用了下面两句来在屏幕输出字符串&#xff0c; ldstr "I am from the IL Assembly Language..." call void [mscorlib]System.Console::WriteLine (string) …

Ros终端出现找不到bash: /home/***/devel/setup.bash: 没有那个文件或目录

现象&#xff1a;Ros终端出现找不到bash: /home/***/devel/setup.bash: 没有那个文件或目录 问题&#xff1a;配置时路径写错 解决方法&#xff1a;改正路径 1.打开文件 gedit ~/.bashrc2.修改正确路径

Day 42算法记录| 动态规划 08

这里写目录标题 139. 单词拆分多重背包问题背包问题总结 139. 单词拆分 单词就是物品&#xff0c;字符串s就是背包 1.dp[0]背包啥也不要用装&#xff0c;true。 2. for循环&#xff0c;顺序很重要&#xff0c;所以先背包再物品 如果求组合数就是外层for循环遍历物品&#xff0…

UG\NX二次开发 遍历部件中所有表达式

文章作者:里海 来源网站:https://blog.csdn.net/WangPaiFeiXingYuan 简介: 遍历部件中所有表达式 效果: 代码: #include "me.hpp" #include <uf_defs.h> #include <NXOpen/NXException.hxx> #include <NXOpen/Session.hxx> #include <NXO…

java根据模板导出word

java根据模板导出word 日常开发中&#xff0c;常常会遇到各种各样的表格进行导出&#xff0c;比较好的办法就是提前弄好word模版&#xff0c;再通过遍历的方式进行导出文档 1、制作word模版 模版编写 内容替换 目标下面模版进行多页展示 将word转换成xml 将xml格式化 再将x…

FTP文件传输工具:简单、高效、实用的数据传输方式

在当今的信息化社会&#xff0c;数据已经成为各行各业的重要资产&#xff0c;而数据的传输和交换则是数据价值的体现。在很多场景中&#xff0c;企业需要传输或接收大文件&#xff0c;比如设计图纸、视频素材、软件开发包、数据库备份等。这些文件的大小通常在几百兆字节到几十…

版本控制泄露代码

在文章的开头我们首先得了解什么是版本控制 在实际的开发过程中&#xff0c;我们会用到两个工具来进行版本控制和代码托管&#xff0c;它们分别是git和svn。 而在CTF中我们主要面对的就是git或svn的版本控制泄露。 &#xff08;1&#xff09;在使用 SVN 管理本地代码过程中&am…

在拦截器中使用redis报错空指针

问题 当在拦截器中使用 redis 时&#xff0c;获取不到 RedisTemplate 对象 原因 拦截器在SpringContext初始化之前就执行了&#xff0c;即Bean初始化之前它就执行了&#xff0c;所以肯定是无法获取SpringIOC容器中的内容的 解决 提前实例化拦截器 在配置类里面先实例化拦截…

vue2项目迁移到vue3中的改动——vuex部分——基础积累2

pinia中文文档里面有关于vuex的部分&#xff1a; Pinia 最初是在 2019 年 11 月左右重新设计使用 Composition API 。从那时起&#xff0c;最初的原则仍然相同&#xff0c;但 Pinia 对 Vue 2 和 Vue 3 都有效&#xff0c;并且不需要您使用组合 API。 除了安装和 SSR 之外&…

【使用时空RBF-NN进行非线性系统识别】实现了 RBF、分数 RBF 和时空 RBF 神经网络,用于非线性系统识别研究(Matlab代码实现)

目录 &#x1f4a5;1 概述 &#x1f4da;2 运行结果 2.1 算例1 2.2 算例2 &#x1f389;3 参考文献 &#x1f308;4 Matlab代码实现 &#x1f4a5;1 概述 本文用于非线性系统识别任务的径向基函数神经网络&#xff08;RBF-NN&#xff09;的三种变体。特别是&#xff0c;我实现…