前言
day11,我们学习了Spark HA模式、Spark submit及spark shell的演示。今天学习Spark RDD。
RDD
RDD中文名是弹性分布式数据集,它是Spark中最基本的数据抽象,它代表一个不可变、可分区、里面的元素可并行计算的集合。
RDD的创建
RDD的创建方式,有两种:
- 通过外部的数据文件创建,如HDFS。
如:sc.textFile(“hdfs://bigdata121:9000/one”) - 通过sc.parallelize进行创建
如:sc.parallelize(Array(1,2,3,4,5,6,7,8),3)
算子
RDD调用的方法称之为算子,算子分Transformation和Action两种。
Transformation:延迟计算,所有转换都是延迟加载的,它的底层使用的是Lazy,不会立即触发计算。
Action:立即计算。
RDD缓存机制
RDD通过persist方法或cache方法可以将前面的计算结果缓存,但是并不是这两个方法被调用时立即缓存,而是触发后面的action时,该RDD将会被缓存在计算节点的内存中,并供后面重用。
通过查看源码发现cache最终也是调用了persist方法,默认的存储级别都是仅在内存存储一份,Spark的存储级别还有好多种,存储级别在object StorageLevel中定义的。StorageLevel的定义有哪些,可以查看源码,如下是源码的内容:
object StorageLevel extends scala.AnyRef with scala.Serializable {
val NONE : org.apache.spark.storage.StorageLevel = { /* compiled code */ }
val DISK_ONLY : org.apache.spark.storage.StorageLevel = { /* compiled code */ }
val DISK_ONLY_2 : org.apache.spark.storage.StorageLevel = { /* compiled code */ }
val MEMORY_ONLY : org.apache.spark.storage.StorageLevel = { /* compiled code */ }
val MEMORY_ONLY_2 : org.apache.spark.storage.StorageLevel = { /* compiled code */ }
val MEMORY_ONLY_SER : org.apache.spark.storage.StorageLevel = { /* compiled code */ }
val MEMORY_ONLY_SER_2 : org.apache.spark.storage.StorageLevel = { /* compiled code */ }
val MEMORY_AND_DISK : org.apache.spark.storage.StorageLevel = { /* compiled code */ }
val MEMORY_AND_DISK_2 : org.apache.spark.storage.StorageLevel = { /* compiled code */ }
val MEMORY_AND_DISK_SER : org.apache.spark.storage.StorageLevel = { /* compiled code */ }
val MEMORY_AND_DISK_SER_2 : org.apache.spark.storage.StorageLevel = { /* compiled code */ }
val OFF_HEAP : org.apache.spark.storage.StorageLevel = { /* compiled code */ }
缓存示例,这里有一个数据文件,使用Spark shell统计它有多少行数据,使用缓存机制,然后多运行几次。
[root@bigdata121 ~]# /opt/module/spark-2.1.0-bin-hadoop2.7/bin/spark-shell --master spark://bigdata121:7077
Using Spark's default log4j profile: org/apache/spark/log4j-defaults.properties
Setting default log level to "WARN".
To adjust logging level use sc.setLogLevel(newLevel). For SparkR, use setLogLevel(newLevel).
20/01/02 19:03:03 WARN NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
20/01/02 19:03:08 WARN ObjectStore: Failed to get database global_temp, returning NoSuchObjectException
Spark context Web UI available at http://192.168.80.121:4040
Spark context available as 'sc' (master = spark://bigdata121:7077, app id = app-20200102190304-0000).
Spark session available as 'spark'.
Welcome to
____ __
/ __/__ ___ _____/ /__
_\ \/ _ \/ _ `/ __/ '_/
/___/ .__/\_,_/_/ /_/\_\ version 2.1.0
/_/
Using Scala version 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_121)
Type in expressions to have them evaluated.
Type :help for more information.
scala> val rdd1 = sc.textFile("/root/data.txt")
rdd1: org.apache.spark.rdd.RDD[String] = /root/data.txt MapPartitionsRDD[1] at textFile at <console>:24
#设置使用缓存
scala> rdd1.cache
res0: rdd1.type = /root/data.txt MapPartitionsRDD[1] at textFile at <console>:24
scala> rdd1.count
res1: Long = 20000002
scala> rdd1.count
res2: Long = 20000002
scala> rdd1.count
res3: Long = 20000002
scala>
在Spark的Web UI下查看每次的运行时间,可以看到后面的运行时间明显比前面的时间少,这是因为后面的计算使用了前面计算的缓存的原因。