RDD创建
从文件系统中加载数据创建RDD
spark采用**textFile()**方法来从文件系统中加载数据创建RDD
该方法吧文件的URI作为参数,这个URI可以是:
- 本地文件系统的地址
- 或者是分布式文件系统HDFS的地址
- 或者是Amazon S3的地址等等
(1)从本地文件系统加载数据创建RDD
例如scala代码:注意是3条斜杠
scala> val lines = sc.textFile("E:///1-研究生/01-课程/大数据分析应用与实践/运行代码的测试文件/textFile.txt")
运行结果:
原理示意图:
(2) 从分布式文件系统HDFS中加载数据
scala代码实现:以下3条语句完全等价,注意第一个是两条斜杠
scala> val lines = sc.textFile("hdfs://localhost:9000/user/hadoop/word.txt")
scala> val lines = sc.textFile("/user/hadoop/word.txt")
scala> val lines = sc.textFile("world.txt")
通过并行集合(数组)创建RDD
可以调用SparkContext的parallelize方法,在Driver中一个已经存在的集合(数组)上创建
原理:
scala代码实现:
scala> val array = Array(1,2,3,4,5)
scala> val rdd = sc.parallelize(array)
运行结果:
或者从列表中创建:
scala> val list= List(1,2,3,4,5)
scala> val rdd = sc.parallelize(list)
运行结果:
RDD操作
转换操作
常用RDD转换操作API:
- filter(func):筛选出满足函数func的元素,并返回一个新的数据集
- map(func):将每个元素传递到函数func中,并将结果返回为一个新的数据集
- flatMap(func):与map()相似,但每个输入元素都可以映射到0或多个输出结果
- groupByKey():应用于(K,V)键值对的数据集时,返回一个新的(K,Iterable)形式的数据集
- reduceByKey(func):应用于(K,V)键值对的数据集时,返回一个新的(K,V)形式的数据集,其中每个值是将每个key传递到函数func中进行聚合后的结果
行动操作
行为操作是真正触发计算的地方
spark程序执行到行动操作时,才会执行真正的计算,从数据中加载数据,完成一次又一次的转换操作,最终,完成行动操作得到结果
常用RDD行动操作API:
- count(): 返回数据集中的元素个数
- collect(): 以数组的形式返回数据集中的所有元素
- first(): 返回数据集中的第一个元素
- take(n): 以数据的形式返回数据集中的前n个元素
- reduce(func): 通过函数func(输入两个参数并返回一个值)聚合数据集中的元素
- foreach(func): 将数据集中的每个元素传递到函数func中运行
惰性机制和持久化机制
惰性机制指只有遇到行动操作,才会触发真正的计算
惰性操作对于迭代计算而言,代价很大,为此需要使用持久化机制避免重复计算的开销
使用**persist()**方法对一个RDD标记为持久化
- 方法为:persist(MEMORY_ONLY)
persist()与cache():
- 使用cache()可以调用persist(MEMORY_ONLY)生成缓存
RDD分区
分区作用
- 增加并行度
- 减少通信开销
分区原则
- 使得分区的个数尽量等于集群中的CPU核数
注:
- 本地模式(local):默认本地机器的CPU数目,若设置了local[N],则默认为N
- Apche Mesos:默认的分区数为8
- Standalone或YARN:在“集群中所有CPU核心数目总和”和“2”,二者中取较大值作为默认值
设置分区的个数
(1) 创建RDD时手动指定分区个数
在调用**textFile()和parallelize()**方法的时候手动指定分区个数即可
格式:sc.textFile(path, partitionNum)
其中,path参数用于指定要加载的文件的地址,partitionNum参数指定分区个数
(2) 使用reparition方法重新设置分区数量
通过转换操作得到新的RDD时,直接调用reparition方法即可
(3) 自定义分区方法
Spark提供了自带的HashPartitioner(哈希分区) 与 RangePartitioner(区域分区),能够满足大多数应用场景需求
spark也支持自定义分区方式,即提供一个自定义的Partitioner对象来控制RDD的分区方式,而利用领域知识进一步减少通信开销