Spark RDD学习笔记

一、学习Spark RDD

RDD是Spark中的核心数据模型,一个RDD代表着一个被分区(partition)的只读数据集。

RDD的生成只有两种途径:

一种是来自于内存集合或外部存储系统;

另一种是通过转换操作来自于其他RDD;

一般需要了解RDD的以下五个接口:

partition分区,一个RDD会有一个或者多个分区

dependencies()RDD的依赖关系

preferredLocations(p)对于每个分区而言,返回数据本地化计算的节点

compute(p,context)对于分区而言,进行迭代计算

partitioner()RDD的分区函数


1.1 RDD分区(partitions)

一个RDD包含一个或多个分区,每个分区都有分区属性,分区的多少决定了对RDD进行并行计算的并行度。

在生成RDD时候可以指定分区数,如果不指定分区数,则采用默认值,系统默认的分区数,是这个程序所分配到的资源的CPU核数。

可以使用RDD的成员变量partitions返回RDD对应的分区数组:

scala> var file = sc.textFile("/tmp/lxw1234/1.txt")

file: org.apache.spark.rdd.RDD[String] = MapPartitionsRDD[5] at textFile at :21


scala> file.partitions

res14: Array[org.apache.spark.Partition] = Array(org.apache.spark.rdd.HadoopPartition@735, org.apache.spark.rdd.HadoopPartition@736)


scala> file.partitions.size

res15: Int = 2 //默认两个分区


//可以指定RDD的分区数

scala> var file = sc.textFile("/tmp/lxw1234/1.txt",4)

file: org.apache.spark.rdd.RDD[String] = MapPartitionsRDD[7] at textFile at :21


scala> file.partitions

res16: Array[org.apache.spark.Partition] = Array(org.apache.spark.rdd.HadoopPartition@787, org.apache.spark.rdd.HadoopPartition@788, org.apache.spark.rdd.HadoopPartition@789, org.apache.spark.rdd.HadoopPartition@78a)


scala> file.partitions.size

res17: Int = 4

1.2 RDD依赖关系(dependencies)

由于RDD即可以由外部存储而来,也可以从另一个RDD转换而来,因此,一个RDD会存在一个或多个父的RDD,这里面也就存在依赖关系,

窄依赖:

每一个父RDD的分区最多只被子RDD的一个分区所使用,如图所示:


宽依赖

多个子RDD的分区会依赖同一个父RDD的分区,如图所示:


以下代码可以查看RDD的依赖信息:

scala> var file = sc.textFile("/tmp/lxw1234/1.txt")

file: org.apache.spark.rdd.RDD[String] = MapPartitionsRDD[9] at textFile at :21


scala> file.dependencies.size

res20: Int = 1 //返回RDD的依赖数量

scala> file.dependencies(0)

res19:

org.apache.spark.Dependency[_] = org.apache.spark.OneToOneDependency@33c5abd0

//返回RDD file的第一个依赖

scala> file.dependencies(1)

java.lang.IndexOutOfBoundsException: 1

//因为file只有一个依赖,想获取第二个依赖时候,报了数组越界

需要大数据学习资料和交流学习的同学可以加大数据学习群:724693112 有免费资料分享和一群学习大数据的小伙伴一起努力

再看一个存在多个父依赖的例子:

scala> var rdd1 = sc.textFile("/tmp/lxw1234/1.txt")

rdd1: org.apache.spark.rdd.RDD[String] = MapPartitionsRDD[11] at textFile at :21


scala> var rdd2 = sc.textFile("/tmp/lxw1234/1.txt")

rdd2: org.apache.spark.rdd.RDD[String] = MapPartitionsRDD[13] at textFile at :21


scala> var rdd3 = rdd1.union(rdd2)

rdd3: org.apache.spark.rdd.RDD[String] = UnionRDD[14] at union at :25


scala> rdd3.dependencies.size

res24: Int = 2 // rdd3依赖rdd1和rdd2两个RDD


//分别打印出rdd3的两个父rdd,即 rdd1和rdd2的内容

scala> rdd3.dependencies(0).rdd.collect

res29: Array[_] = Array(hello world, hello spark, hello hive, hi spark)


scala> rdd3.dependencies(1).rdd.collect

res30: Array[_] = Array(hello world, hello spark, hello hive, hi spark)

1.3 RDD优先位置(preferredLocations)

RDD的优先位置,返回的是此RDD的每个partition所存储的位置,这个位置和Spark的调度有关(任务本地化),Spark会根据这个位置信息,尽可能的将任务分配到数据块所存储的位置,以从Hadoop中读取数据生成RDD为例,preferredLocations返回每一个数据块所在的机器名或者IP地址,如果每一个数据块是多份存储的(HDFS副本数),那么就会返回多个机器地址。

看以下代码:

scala> var file = sc.textFile("/tmp/lxw1234/1.txt")

file: org.apache.spark.rdd.RDD[String] = MapPartitionsRDD[16] at textFile at :21

//这里的file为MappedRDD

scala> var hadoopRDD = file.dependencies(0).rdd

hadoopRDD: org.apache.spark.rdd.RDD[_] = /tmp/lxw1234/1.txt HadoopRDD[15] at textFile at :21 //这里获取file的父RDD,即hdfs文件/tmp/lxw1234/1.txt对应的HadoopRDD

scala> hadoopRDD.partitions.size

res31: Int = 2 //hadoopRDD默认有两个分区


//下面分别获取两个分区的位置信息

scala> hadoopRDD.preferredLocations(hadoopRDD.partitions(0))

res32: Seq[String] = WrappedArray(slave007.lxw1234.com, slave004.lxw1234.com)


scala> hadoopRDD.preferredLocations(hadoopRDD.partitions(1))

res33: Seq[String] = WrappedArray(slave007. lxw1234.com, slave004.lxw1234.com)


##

由于HDFS副本数设置为2,因此每个分区的位置信息中包含了所有副本(2个)的位置信息,这样Spark可以调度时候,根据任何一个副本所处的位置进行本地化任务调度。


1.4 RDD分区计算(compute)

基于RDD的每一个分区,执行compute操作。

对于HadoopRDD来说,compute中就是从HDFS读取分区中数据块信息。

对于JdbcRDD来说,就是连接数据库,执行查询,读取每一条数据。


1.5 RDD分区函数(partitioner)

目前Spark中实现了两种类型的分区函数,HashPartitioner(哈希分区)和RangePartitioner(区域分区)。

partitioner只存在于类型的RDD中,非类型的RDD的partitioner值为None.


partitioner函数既决定了RDD本身的分区数量,也可作为其父RDD Shuffle输出中每个分区进行数据切割的依据。


scala> var a = sc.textFile("/tmp/lxw1234/1.txt").flatMap(line => line.split("\\s+"))

a: org.apache.spark.rdd.RDD[String] = MapPartitionsRDD[19] at flatMap at :21


scala> a.partitioner

res15: Option[org.apache.spark.Partitioner] = None // RDD a为非类型


scala> var b = a.map(l => (l,1)).reduceByKey((a,b) => a + b)

b: org.apache.spark.rdd.RDD[(String, Int)] = ShuffledRDD[21] at reduceByKey at :30


scala> b.partitioner

res16: Option[org.apache.spark.Partitioner] = Some(org.apache.spark.HashPartitioner@2)

//RDD b为类型,采用的是默认的partitioner- HashPartitioner

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,393评论 5 467
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,790评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,391评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,703评论 1 270
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,613评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,003评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,507评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,158评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,300评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,256评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,274评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,984评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,569评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,662评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,899评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,268评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,840评论 2 339

推荐阅读更多精彩内容