Spark RDD操作讲解
来源:互联网 发布:淘宝身高体重尺码表 编辑:程序博客网 时间:2024/05/21 07:48
一、spark rdd 介绍
1.rdd概念 rdd是弹性分布式数据集,存储在硬盘或者内存上。2.rdd特征 1)有一个分片列表,就是能被切分,和Hadoop一样,能够切分的数据才能够并行计算 2)由一个函数计算每一个分片 3)对其他rdd有依赖,但并不是所有的rdd都有依赖 4)key-value的rdd是根据哈希来分区的
二、spark rdd创建
1.数据集合 val data = Array(1, 2,3, 4, 5, 6, 7, 8, 9) val distData = sc.parallelize(data, 3)2.外部数据源 val distFile1 = sc.textFile("data.txt") //本地当前目录下文件 val distFile2=sc.textFile("hdfs://192.168.1.100:9000/input/data.txt") //HDFS文件 val distFile3 =sc.textFile("file:/input/data.txt") //本地指定目录下文件 val distFile4 =sc.textFile("/input/data.txt") //本地指定目录下文件 textFile("/input/001.txt, /input/002.txt ") //读取多个文件 textFile("/input") //读取目录 textFile("/input /*.txt") //含通配符的路径 textFile("/input /*.gz") //读取压缩文件
三、rdd算子分类及功能
1.rdd算子作用: 1)输入:在Spark程序运行中,数据从外部数据空间(如分布式存储:textFile读取HDFS等,parallelize方法输入Scala集合或数据)输入Spark,数据进入Spark运行时数据空间,转化为Spark中的数据块,通过BlockManager进行管理。 2)运行:在Spark数据输入形成RDD后便可以通过变换算子,如fliter等,对数据进行操作并将RDD转化为新的RDD,通过Action算子,触发Spark提交作业。如果数据需要复用,可以通过Cache算子,将数据缓存到内存。 3)输出:程序运行结束数据会输出Spark运行时空间,存储到分布式存储中(如saveAsTextFile输出到HDFS),或Scala数据或集合中(collect输出到Scala集合,count返回Scala int型数据)。2.rdd算子分类: 1)Value数据类型的Transformation算子,这种变换并不触发提交作业,针对处理的数据项是Value型的数据。 2)Key-Value数据类型的Transfromation算子,这种变换并不触发提交作业,针对处理的数据项是Key-Value型的数据对。 3)Action算子,这类算子会触发SparkContext提交Job作业。
四、spark rdd转换操作
1.map map是对RDD中的每个元素都执行一个指定的函数来产生一个新的RDD;RDD之间的元素是一对一关系; val rdd1 = sc.parallelize(1 to 9, 3) val rdd2 = rdd1.map(x => x*2) rdd2.collect res3: Array[Int] = Array(2, 4, 6, 8, 10, 12, 14, 16, 18)2.filter Filter是对RDD元素进行过滤;返回一个新的数据集,是经过func函数后返回值为true的原元素组成; val rdd3 = rdd2. filter (x => x> 10) rdd3.collect res4: Array[Int] = Array(12, 14, 16, 18)3.flatMap flatMap类似于map,但是每一个输入元素,会被映射为0到多个输出元素(因此,func函数的返回值是一个Seq,而不是单一元素),RDD之间的元素是一对多关系; val rdd4 = rdd3. flatMap (x => x to 20) res5: Array[Int] = Array(12, 13, 14, 15, 16, 17, 18, 19, 20, 14, 15, 16, 17, 18, 19, 20, 16, 17, 18, 19, 20, 18, 19, 20)4.mapPartitions mapPartitions是map的一个变种。map的输入函数是应用于RDD中每个元素,而mapPartitions的输入函数是每个分区的数据,也就是把每个分区中的内容作为整体来处理的。5.mapPartitionsWithIndex mapPartitionsWithSplit与mapPartitions的功能类似, 只是多传入split index而已,所有func 函数必需是 (Int, Iterator<T>) =>Iterator<U> 类型。6.sample sample(withReplacement,fraction,seed)是根据给定的随机种子seed,随机抽样出数量为frac的数据。withReplacement:是否放回样;fraction:比例,0.1表示10% ; val a = sc.parallelize(1 to 10000, 3) a.sample(false, 0.1, 0).count res24: Long = 9607.union union(otherDataset)是数据合并,返回一个新的数据集,由原数据集和otherDataset联合而成。 val rdd8 = rdd1.union(rdd3) rdd8.collect res14: Array[Int] = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 12, 14, 16, 18)8.intersection intersection(otherDataset)是数据交集,返回一个新的数据集,包含两个数据集的交集数据; val rdd9 = rdd8.intersection(rdd1) rdd9.collect res16: Array[Int] = Array(6, 1, 7, 8, 2, 3, 9, 4, 5)9.distinct distinct([numTasks]))是数据去重,返回一个数据集,是对两个数据集去除重复数据,numTasks参数是设置任务并行数量。 val rdd10 = rdd8.union(rdd9).distinct rdd10.collect res19: Array[Int] = Array(12, 1, 14, 2, 3, 4, 16, 5, 6, 18, 7, 8, 9)10.groupByKey groupByKey([numTasks])是数据分组操作,在一个由(K,V)对组成的数据集上调用,返回一个(K,Seq[V])对的数据集。 val rdd0 = sc.parallelize(Array((1,1), (1,2) , (1,3) , (2,1) , (2,2) , (2,3)), 3) val rdd11 = rdd0.groupByKey() rdd11.collect res33: Array[(Int, Iterable[Int])] = Array((1,ArrayBuffer(1, 2, 3)), (2,ArrayBuffer(1, 2, 3)))11.reduceByKey reduceByKey(func, [numTasks])是数据分组聚合操作,在一个(K,V)对的数据集上使用,返回一个(K,V)对的数据集,key相同的值,都被使用指定的reduce函数聚合到一起。 val rdd12 = rdd0.reduceByKey((x,y) => x + y) rdd12.collect res34: Array[(Int, Int)] = Array((1,6), (2,6))12.aggregateByKey aggreateByKey(zeroValue: U)(seqOp: (U, T)=> U, combOp: (U, U) =>U) 和reduceByKey的不同在于,reduceByKey输入输出都是(K, V),而aggreateByKey输出是(K,U),可以不同于输入(K, V) ,aggreateByKey的三个参数: zeroValue: U,初始值,比如空列表{} ; seqOp: (U,T)=> U,seq操作符,描述如何将T合并入U,比如如何将item合并到列表 ; combOp: (U,U) =>U,comb操作符,描述如果合并两个U,比如合并两个列表 ; 所以aggreateByKey可以看成更高抽象的,更灵活的reduce或group 。 val z = sc.parallelize(List(1,2,3,4,5,6), 2) z.aggreate(0)(math.max(_, _), _ + _) res40: Int = 9 val z = sc.parallelize(List((1, 3), (1, 2), (1, 4), (2, 3))) z.aggregateByKey(0)(math.max(_, _), _ + _) res2: Array[(Int, Int)] = Array((2,3), (1,9))13.combineByKey combineByKey是对RDD中的数据集按照Key进行聚合操作。聚合操作的逻辑是通过自定义函数提供给combineByKey。 combineByKey[C](createCombiner: (V) ⇒ C, mergeValue: (C, V) ⇒ C, mergeCombiners: (C, C) ⇒ C, numPartitions: Int):RDD[(K, C)]把(K,V) 类型的RDD转换为(K,C)类型的RDD,C和V可以不一样。combineByKey三个参数: val data = Array((1, 1.0), (1, 2.0), (1, 3.0), (2, 4.0), (2, 5.0), (2, 6.0)) val rdd = sc.parallelize(data, 2) val combine1 = rdd.combineByKey(createCombiner = (v:Double) => (v:Double, 1), mergeValue = (c:(Double, Int), v:Double) => (c._1 + v, c._2 + 1), mergeCombiners = (c1:(Double, Int), c2:(Double, Int)) => (c1._1 + c2._1, c1._2 + c2._2),numPartitions = 2 )combine1.collect res0: Array[(Int, (Double, Int))] = Array((2,(15.0,3)), (1,(6.0,3)))14.sortByKey sortByKey([ascending],[numTasks])是排序操作,对(K,V)类型的数据按照K进行排序,其中K需要实现Ordered方法。 val rdd14 = rdd0.sortByKey() rdd14.collect res36: Array[(Int, Int)] = Array((1,1), (1,2), (1,3), (2,1), (2,2), (2,3))15.join join(otherDataset, [numTasks])是连接操作,将输入数据集(K,V)和另外一个数据集(K,W)进行Join, 得到(K, (V,W));该操作是对于相同K的V和W集合进行笛卡尔积 操作,也即V和W的所有组合; val rdd15 = rdd0.join(rdd0) rdd15.collect res37: Array[(Int, (Int, Int))] = Array((1,(1,1)), (1,(1,2)), (1,(1,3)), (1,(2,1)), (1,(2,2)), (1,(2,3)), (1,(3,1)), (1,(3,2)), (1,(3,3)), (2,(1,1)),(2,(1,2)), (2,(1,3)), (2,(2,1)), (2,(2,2)), (2,(2,3)), (2,(3,1)), (2,(3,2)), (2,(3,3))) 连接操作除join 外,还有左连接、右连接、全连接操作函数: leftOuterJoin、rightOuterJoin、fullOuterJoin。16.cogroup cogroup(otherDataset, [numTasks])是将输入数据集(K, V)和另外一个数据集(K, W)进行cogroup,得到一个格式为(K, Seq[V], Seq[W])的数据集。 val rdd16 = rdd0.cogroup(rdd0) rdd16.collect res38: Array[(Int, (Iterable[Int], Iterable[Int]))] = Array((1,(ArrayBuffer(1, 2, 3),ArrayBuffer(1, 2, 3))), (2,(ArrayBuffer(1, 2,3),ArrayBuffer(1, 2, 3))))17.cartesian cartesian(otherDataset)是做笛卡尔积:对于数据集T和U 进行笛卡尔积操作, 得到(T, U)格式的数据集。 val rdd17 = rdd1.cartesian(rdd3) rdd17.collect res39: Array[(Int, Int)] = Array((1,12), (2,12), (3,12), (1,14), (1,16), (1,18), (2,14), (2,16), (2,18), (3,14), (3,16), (3,18), (4,12), (5,12),(6,12), (4,14), (4,16), (4,18), (5,14), (5,16), (5,18), (6,14), (6,16), (6,18), (7,12), (8,12), (9,12), (7,14), (7,16), (7,18), (8,14), (8,16),(8,18), (9,14), (9,16), (9,18))
五、spark rdd行动操作
1.reduce reduce(func)是对数据集的所有元素执行聚集(func)函数,该函数必须是可交换的。 val rdd1 = sc.parallelize(1 to 9, 3) val rdd2 = rdd1.reduce(_ + _) rdd2: Int = 452.collect collect相当于toArray,toArray已经过时不推荐使用,collect将分布式的RDD返回为一个单机的scala Array数组。在这个数组上运用scala的函数式操作。 rdd1.collect() res8: Array[Int] = Array(1, 2, 3, 4, 5, 6, 7, 8, 9)3.count 返回数据集中元素的个数。 rdd1.count() res9: Long = 94.first 返回数据集中的第一个元素, 类似于take(1)。 rdd1.first() res10: Int = 15.take Take(n)返回一个包含数据集中前n个元素的数组, 当前该操作不能并行。 rdd1.take(3) res11: Array[Int] = Array(1, 2, 3)6.takeSample takeSample(withReplacement,num, [seed])返回包含随机的num个元素的数组,和Sample不同,takeSample 是行动操作,所以返回的是数组而不是RDD , 其中第一个参数withReplacement是抽样时是否放回,第二个参数num会精确指定抽样数,而不是比例。 rdd1.takeSample(true, 4) res15: Array[Int] = Array(9, 5, 5, 6)7.takeOrdered takeOrdered(n, [ordering])是返回包含随机的n个元素的数组,按照顺序输出。 rdd1.takeOrdered(4) res16: Array[Int] = Array(1, 2, 3, 4)8.saveAsTextFile 把数据集中的元素写到一个文本文件,Spark会对每个元素调用toString方法来把每个元素存成文本文件的一行。存储到HDFS的指定目录。9.countByKey 对于(K, V)类型的RDD. 返回一个(K, Int)的map, Int为K的个数。10.foreach foreach(func)是对数据集中的每个元素都执行func函数。不返回RDD和Array,而是返回Uint。11.saveAsObjectFile saveAsObjectFile将分区中的每10个元素组成一个Array,然后将这个Array序列化,映射为(Null,BytesWritable(Y))的元素,写入HDFS为SequenceFile的格式。12.collectAsMap collectAsMap对(K,V)型的RDD数据返回一个单机HashMap。对于重复K的RDD元素,后面的元素覆盖前面的元素。13.reduceByKeyLocally 实现的是先reduce再collectAsMap的功能,先对RDD的整体进行reduce操作,然后再收集所有结果返回为一个HashMap。14.lookup Lookup函数对(Key,Value)型的RDD操作,返回指定Key对应的元素形成的Seq。这个函数处理优化的部分在于,如果这个RDD包含分区器,则只会对应处理K所在的分区,然后返回由(K,V)形成的Seq。如果RDD不包含分区器,则需要对全RDD元素进行暴力扫描处理,搜索指定K对应的元素。15.top top可返回最大的k个元素。16.reduce reduce函数相当于对RDD中的元素进行reduceLeft函数的操作。函数实现如下。 Some(iter.reduceLeft(cleanF)) reduceLeft先对两个元素<K,V>进行reduce函数操作,然后将结果和迭代器取出的下一个元素<k,V>进行reduce函数操作,直到迭代器遍历完所有元素,得到最后结果。 在RDD中,先对每个分区中的所有元素<K,V>的集合分别进行reduceLeft。每个分区形成的结果相当于一个元素<K,V>,再对这个结果集合进行reduceleft操作。17.fold fold和reduce的原理相同,但是与reduce不同,相当于每个reduce时,迭代器取的第一个元素是zeroValue。
阅读全文
0 0
- Spark RDD操作讲解
- [Spark]Spark RDD 指南四 RDD操作
- Spark RDD操作
- spark RDD keyvalue操作
- Spark RDD transformation操作
- spark RDD transformation操作
- spark RDD 基本操作
- spark rdd 操作
- Spark RDD创建操作
- Spark中RDD操作
- Spark RDD基本操作
- spark-RDD集合操作
- Spark RDD基本操作
- spark rdd操作API
- Spark RDD基础操作
- Spark入门RDD操作
- Spark RDD操作总结
- Spark常用RDD操作汇总
- 中后缀表达式的相互转换和四则运算表达式求值
- 模仿AlphaGo围棋博弈,MuGo实现策略网络以及蒙特卡洛树搜索
- Java菜鸟学习日记27
- 学习体系+杂想
- poj 3243 Clever Y
- Spark RDD操作讲解
- C语言实现的一个简单的HTTP程序
- C++中循环语句语法
- 指针与句柄的区别
- Aggressive Cows
- python中的进程, 线程
- 如何学习C#和C++
- 【整数划分+DP】HDU_1028_D
- hdu 6097 Mindis