1.RDD的创建:
RDD的创建两种方式:
- 并行化已有的集合
val RDD1 = sc.makeRDD(List(3,5,6,7,8))
val RDD2 = sc.parallelize(Array(1,3,4,6,7))
以上两种方式是都可以创建RDD的,虽有区别,但是实现方式都一样makeRDD的底层也是用parallelize方法实现的
并行集合的一个重要参数是要将数据集拆分后的分区数。spark将为集群的每个分区运行一个任务。通常,您需要为集群中的每个CPU分配2-4个分区。通常,spark会根据集群自动设置分区数。但是,您也可以通过将其作为第二个参数传递给parallelize
函数
- 引用外部存储中的数据集
sc.testFile("hdfs://master:9000/Spark")
使用spark读取文件的一些注意事项
-
如果在本地文件系统上使用路径,则该文件也必须可以在工作节点上的同一路径上访问
-
Spark所有基于文件的输入方法,包括textfile、支持在目录上运行、压缩文件和通配符。
例如,可以使用textfile(“/my/directory”)、textfile(“/my/directory/.txt”)和textfile(“/my/directory/.gz”)
- textfile方法还采用可选的第二个参数来控制文件的分区数。默认情况下,spark为文件的每个块创建一个分区(HDFS中的块默认为64MB),但您也可以通过传递较大的值来请求更多的分区。请注意,分区数不能少于块的数量
2.RDD的操作
RDD支持类型的操作:
Transformation:
将现有的数据集转换成另一种数据集
Spark中所有的transformation操作都是懒惰的,因此它们并不会立即计算结果。相反,它们只是记住应用于某些基本数据集的转换。只有在执行action操作将结果返回到Driver program时,才会开始对transformation操作进行计算。这种设计使Spark能够更高效的运行
转换 | 描述 |
---|---|
map(func) | 返回一个新的RDD,该RDD由每一个输入元素经过func函数转换后组成 |
filter(func) | 返回一个新的RDD,该RDD经过func函数计算后返回值为true的输入元素组成 |
flatMap(func) | 类似于map,但每个输入元素可以被映射为0或多个输出元素(所以func应该返回一个序列,而不是单一元素) |
mapPartitions(func) | 类似于map,但独立的在RDD的每个分区上运行,因此在类型为T的RDD上运行时,func函数的类型必须是Iterator => Iterator |
mapPartitionsWithIndex(func) | 类似于mapPartitions,但func带有一个整形参数表示分片的索引值,因此在类型为T的RDD上运行时,func函数的类型必须(Int, Iterator) => Iterator |
sample(withReplacement, fraction, seed) | 根据fraction指定的比例对数据进行采样,这个采样概率分布在其左右,可以选择是否使用随机数进行替换,seed用于指定随机数生成器种子,使每次随机生成数据保持一致 |
union(otherDataset) | 对源RDD和参数RDD求并集后并返回一个新的RDD |
intersection(otherDataset) | 对源RDD和参数RDD求交集后并返回一个新的RDD |
distinct([numTasks])) | 对源RDD进行去重后,返回一个新的RDD |
groupByKey([numTasks]) | 在一个(K,V)形式的RDD上调用,返回一个(K,Iterator[V])的RDD |
reduceByKey(func, [numTasks]) | 在一个(K,V)形式的RDD上调用,返回一个(K,V)的RDD,使用指定的reduce函数,将相同key的值聚合到一起,与groupBy类似,reduce任务的个数可以通过第二个参数来设置 |
aggregateByKey(zeroValue)(seqOp, combOp, [numTasks]) | 当调用(K,V)对的数据集时,返回(K,U)数据集,其中每个key的值使用给定的聚合函数和中性"零"值进行聚合。与groupbykey类似,reduce任务的数量可以通过可选的第二个参数进行配置 |
sortByKey([ascending], [numTasks]) | 在一个(K,V)形式的RDD上调用,K必须实现Ordered接口,返回一个按照key进行排序的(K,V)的RDD |
join(otherDataset, [numTasks]) | 当调用(K,V)和(K,W)类型的数据集时,返回一个(K,(V,W))形式的数据集,支持leftouterjoin、rightouterjoin和fulloterjoin |
cogroup(otherDataset, [numTasks]) | 当调用(K,V)和(K,W)类型的数据集时,返回(K,(iterable,iterable)元组的数据集 |
cartesian(otherDataset) | 当调用T和U类型的数据集时,返回一个(T,U)类型的数据集 |
pipe(command, [envVars]) | 通过shell命令(例如perl或bash脚本)对RDD的每个分区进行管道连接。RDD元素写入进程的stdin,输出到其stdout的行作为字符串的RDD返回 |
coalesce(numPartitions) | 将RDD中的分区数减少到numPartitions。在过滤大型数据集后,可以更高效地运行操作 |
repartition(numPartitions) | 随机重组RDD中的数据,以创建更多或更少的分区,并在分区之间进行平衡,总是会产生shuffle操作 |
repartitionAndSortWithinPartitions(partitioner) | 根据给定的分区器对RDD重新分区,并在每个生成的分区内,按键对记录进行排序。这比调用重新分区然后在每个分区内进行排序更有效,因为它可以将排序向下推送到无序处理机器中 |
Action:
将数据集进行运算后将值返回给Driver Program
动作 | 描述 |
---|---|
reduce(func) | 使用函数func聚合数据集的元素(函数func接受两个参数并返回一个参数)。函数应该是交换的和结合的,这样才能正确地并行计算 |
collect() | 在driver program中,以数组的形式返回数据集的所有元素 |
count() | 返回RDD的元素个数 |
first() | 返回RDD的第一个元素(类似take(1)) |
take(n) | 返回一个由数据集前n个元素组成的数组 |
takeSample(withReplacement, num, [seed]) | 返回一个数组,该数组由从数据集中随机采样num个元素组成。可以选择是否采用随机数替换不足的部分,seed用于指定随机数生成器种子 |
takeOrdered(n, [ordering]) | 使用RDD的自然顺序或自定义比较器返回RDD的前n个元素 |
saveAsTextFile(path) | 将数据集的元素以textfile的形式保存到HDFS文件系统或其他文件系统 |
saveAsSequenceFile(path) (Java and Scala) | 将数据集中的元素以Hadoop sequencefile的格式保存到指定的目录下 |
saveAsObjectFile(path) (Java and Scala) | 使用Java序列化将数据集的元素以一种简单的格式写入,然后可以使用 |
countByKey() | 针对(K,V)类型的RDD,返回一个(K,int)的map,表示每一个key对应元素的个数 |
foreach(func) | 对数据集的每个元素运行函数func |