Spark编程(一) RDD编程
1.RDD创建
1.1从文件系统加载数据创建RDD
测试如下当前系统中存在一个文件word.txt 位置和内容如下
读取成功
1.2通过数组创建RDD
2.RDD操作
2.1 转换操作
2.2 行动操作
2.3 惰性机制
2.4 实例
filter操作
找出文本文件中单行文本所包含的单词数量最大值
还可以用这个语句我觉得简单一点lines.map(_.split(" ").size).max
3.RDD持久化
persist()
方法对RDD标记为持久化
LRU的意思就是Least Recently Used
,即最近最少使用的意思。
也就是使用rdd.cache
即可,unpersist
可以达到移除的效果
4.RDD分区
问题:spark在读取本地文件时,在执行action的时候会拷贝相应分区到多个worker节点进行并行计算吗?
答案:不是,这种读取local file system而不是hdfs的情况,需要同一个文件存在所有的worker node上面,在读取的时候每个worker node的task会去读取本文件的一部分。打个比方,比如你有一个file,有一个spark集群(node1是master,node2,node3两个是slaves),那么这个file需要在node2,node3上面都存在,这两个节点的task会各读一半,不然会出错。(这里其实还有一个点注意,你的spark app所运行的节点也需要有这个file,因为需要用到file进行Partition划分)。
关于repartition的用法问题
有时候需要重新设置Rdd的分区数量,比如Rdd的分区中,Rdd分区比较多,但是每个Rdd的数据量比较小,需要设置一个比较合理的分区。或者需要把Rdd的分区数量调大。还有就是通过设置一个Rdd的分区来达到设置生成的文件的数量。
import org.apache.spark.{Partitioner, SparkContext, SparkConf}
//自定义分区类,需继承Partitioner类
class UsridPartitioner(numParts:Int) extends Partitioner{
//覆盖分区数
override def numPartitions: Int = numParts
//覆盖分区号获取函数
override def getPartition(key: Any): Int = {
key.toString.toInt%10
}
}
object Test {
def main(args: Array[String]) {
val conf=new SparkConf()
val sc=new SparkContext(conf)
//模拟5个分区的数据
val data=sc.parallelize(1 to 10,5)
//根据尾号转变为10个分区,分写到10个文件
data.map((_,1)).partitionBy(new UsridPartitioner(10)).saveAsTextFile("/chenm/partition")
}
}
5.RDD打印元素