Spark RDD基础
IDEA 创建scala spark的Mvn项目:https://blog.csdn.net/u014646662/article/details/84618032
spark快速大数据分析.pdf下载:https://download.csdn.net/download/u014646662/10816588
弹性分布式数据集(Resilient Distributed Dataset,简称RDD),RDD 其实就是分布式的元素集合。在Spark 中,对数据的所有操作不外乎创建RDD、转化已有RDD 以及调用RDD 操作进行求值。而在这一切背后,Spark 会自动将RDD 中的数据分发到集群上,并将操作并行化执行。
Spark 中的RDD 就是一个不可变的分布式对象集合。每个RDD 都被分为多个分区,这些分区运行在集群中的不同节点上。RDD 可以包含Python、Java、Scala 中任意类型的对象,甚至可以包含用户自定义的对象。
用户可以使用两种方法创建RDD:读取一个外部数据集,或在驱动器程序里分发驱动器程序中的对象集合(比如list 和set)。我们在本书前面的章节中已经见过使用SparkContext.textFile() 来读取文本文件作为一个字符串RDD 的示例 :
1:使用textFile() 创建一个字符串的RDD
scala> val userLine = sc.textFile("passwd")
userLine: org.apache.spark.rdd.RDD[String] = passwd MapPartitionsRDD[1] at textFile at <console>:27
创建出来后,RDD 支持两种类型的操作: 转化操作(transformation) 和行动操作(action)。转化操作会由一个RDD 生成一个新的RDD。例如,根据谓词匹配情况筛选数据就是一个常见的转化操作。在我们的文本文件示例中,我们可以用筛选来生成一个只存储默认使用bash shell的用户的新的RDD
scala> var bashUserLine = userLine.filter(line => line.contains("/bin/bash"))
bashUserLine: org.apache.spark.rdd.RDD[String] = MapPartitionsRDD[3] at filter at <console>:29
另一方面,行动操作会对RDD 计算出一个结果,并把结果返回到驱动器程序中,或把结果存储到外部存储系统(如HDFS)中。first() 就是我们之前调用的一个行动操作,它会返回RDD 的第一个元素。
scala> bashUserLine.first
res3: String = root:x:0:0:root:/root:/bin/bash
转化操作和行动操作的区别在于Spark 计算RDD 的方式不同。虽然你可以在任何时候定义新的RDD,但Spark 只会惰性计算这些RDD。它们只有第一次在一个行动操作中用到时,才会真正计算。
最后,默认情况下,Spark 的RDD 会在你每次对它们进行行动操作时重新计算。如果想在多个行动操作中重用同一个RDD,可以使用RDD.persist() 让Spark 把这个RDD 缓存下来。在第一次对持久化的RDD 计算之后,Spark 会把RDD 的内容保存到内存中(以分区方式存储到集群中的各机器上),这样在之后的行动操作中,就可以重用这些数据了。我们也可以把RDD 缓存到磁盘上而不是内存中。默认不进行持久化可能也显得有些奇怪,不过这对于大规模数据集是很有意义的:如果不会重用该RDD,我们就没有必要浪费存储空间,Spark 可以直接遍历一遍数据然后计算出结果。在实际操作中,你会经常用persist() 来把数据的一部分读取到内存中,并反复查询这部分数据。
scala> bashUserLine.persist
res6: org.apache.spark.rdd.RDD[String] = MapPartitionsRDD[3] at filter at <console>:29
scala> bashUserLine.count
res7: Long = 10
scala> bashUserLine.count
res8: Long = 10
scala> bashUserLine.first
res9: String = root:x:0:0:root:/root:/bin/bash
总的来说,每个Spark 程序或shell 会话都按如下方式工作。
(1) 从外部数据创建出输入RDD。
(2) 使用诸如filter() 这样的转化操作对RDD 进行转化,以定义新的RDD。
(3) 告诉Spark 对需要被重用的中间结果RDD 执行persist() 操作。
(4) 使用行动操作(例如count() 和first() 等)来触发一次并行计算,Spark 会对计算进行优化后再执行。
创建RDD
Spark 提供了两种创建RDD 的方式:读取外部数据集,以及在驱动器程序中对一个集合进行并行化。
创建RDD 最简单的方式就是把程序中一个已有的集合传给SparkContext 的parallelize()方法,看个例子:
scala> var lines = sc.parallelize("Lucky,Jon".split(","))
lines: org.apache.spark.rdd.RDD[String] = ParallelCollectionRDD[4] at parallelize at <console>:27
scala> var lines1 = sc.parallelize(List("Lucy","Helen"))
lines1: org.apache.spark.rdd.RDD[String] = ParallelCollectionRDD[5] at parallelize at <console>:27
更常用的方式是从外部存储中读取数据来创建RDD。就是刚刚用来将文本文件读入为一个存储字符串的RDD 的方法SparkContext.textFile()
scala> sc.textFile("/user/cloudera/stoke.txt")
res11: org.apache.spark.rdd.RDD[String] = /user/cloudera/stoke.txt MapPartitionsRDD[7] at textFile at <console>:28