Spark-saveAsTextFile 分区设置

scala> val rd1 =sc.parallelize(Array(1 to 10000))

rd1: org.apache.spark.rdd.RDD[scala.collection.immutable.Range.Inclusive] = ParallelCollectionRDD[24] at parallelize at <console>:24

scala> rd1.partitions.size

res32: Int = 24

scala> rd1.saveAsTextFile("/zhouwu/rd1")

[root@master]# hdfs dfs -ls /zhouwu/rd1
Found 25 items
-rw-r--r--   3 root supergroup          0 2018-01-26 16:57 /zhouwu/rd1/_SUCCESS
-rw-r--r--   3 root supergroup          0 2018-01-26 16:57 /zhouwu/rd1/part-00000
-rw-r--r--   3 root supergroup          0 2018-01-26 16:57 /zhouwu/rd1/part-00001
-rw-r--r--   3 root supergroup          0 2018-01-26 16:57 /zhouwu/rd1/part-00002
-rw-r--r--   3 root supergroup          0 2018-01-26 16:57 /zhouwu/rd1/part-00003
-rw-r--r--   3 root supergroup          0 2018-01-26 16:57 /zhouwu/rd1/part-00004
-rw-r--r--   3 root supergroup          0 2018-01-26 16:57 /zhouwu/rd1/part-00005
-rw-r--r--   3 root supergroup          0 2018-01-26 16:57 /zhouwu/rd1/part-00006
-rw-r--r--   3 root supergroup          0 2018-01-26 16:57 /zhouwu/rd1/part-00007
-rw-r--r--   3 root supergroup          0 2018-01-26 16:57 /zhouwu/rd1/part-00008
-rw-r--r--   3 root supergroup          0 2018-01-26 16:57 /zhouwu/rd1/part-00009
-rw-r--r--   3 root supergroup          0 2018-01-26 16:57 /zhouwu/rd1/part-00010
-rw-r--r--   3 root supergroup          0 2018-01-26 16:57 /zhouwu/rd1/part-00011
-rw-r--r--   3 root supergroup          0 2018-01-26 16:57 /zhouwu/rd1/part-00012
-rw-r--r--   3 root supergroup          0 2018-01-26 16:57 /zhouwu/rd1/part-00013
-rw-r--r--   3 root supergroup          0 2018-01-26 16:57 /zhouwu/rd1/part-00014
-rw-r--r--   3 root supergroup          0 2018-01-26 16:57 /zhouwu/rd1/part-00015
-rw-r--r--   3 root supergroup          0 2018-01-26 16:57 /zhouwu/rd1/part-00016
-rw-r--r--   3 root supergroup          0 2018-01-26 16:57 /zhouwu/rd1/part-00017
-rw-r--r--   3 root supergroup          0 2018-01-26 16:57 /zhouwu/rd1/part-00018
-rw-r--r--   3 root supergroup          0 2018-01-26 16:57 /zhouwu/rd1/part-00019
-rw-r--r--   3 root supergroup          0 2018-01-26 16:57 /zhouwu/rd1/part-00020
-rw-r--r--   3 root supergroup          0 2018-01-26 16:57 /zhouwu/rd1/part-00021
-rw-r--r--   3 root supergroup          0 2018-01-26 16:57 /zhouwu/rd1/part-00022
-rw-r--r--   3 root supergroup       2464 2018-01-26 16:57 /zhouwu/rd1/part-00023

一般而言,saveAsTextFile会按照执行task的多少生成多少个文件,比如part-00000一直到part-0000n,n自然就是task的个数,亦即是最后的stage的分区数。那么有没有办法最后只生成一个文件,而不是成百上千个文件了?答案自然是有办法。

在RDD上调用   coalesce(1,true).saveAsTextFile(),   意味着做完计算之后将数据汇集到一个分区,然后再执行保存的动作,显然,一个分区,Spark自然只起一个task来执行保存的动作,也就只有一个文件产生了。

 又或者,可以调用repartition(1),它其实是coalesce的一个包装,默认第二个参数为true。

事情最终就这么简单吗?显然不是。你虽然可以这么做,但代价是巨大的。因为Spark面对的是大量的数据,并且是并行执行的,如果强行要求最后只有一个分区,必然导致大量的磁盘IO和网络IO产生,并且最终执行reduce操作的节点的内存也会承受很大考验。Spark程序会很慢,甚至死掉。

这往往是初学Spark的一个思维陷阱,需要改变原先那种单线程单节点的思维,对程序的理解要转变多多个节点多个进程中去,需要熟悉多节点集群自然产生多个文件这种模式。

此外,saveAsTextFile要求保存的目录之前是没有的,否则会报错。所以,最好程序中保存前先判断一下目录是否存在。

原链接:

http://blog.youkuaiyun.com/power0405hf/article/details/50596233

当我运行完一个Spark程序想把结果保存为saveAsTextFile, 
结果使用Hadoop fs -ls /output  后发现里面有一系列的part,好几千个。 
原因: 
运行Spark的时候把数据分成了很多份(partition),每个partition都把自己的数据保存成partxxx文件形式。 
如果想保存为一份的话,就要: 

collect

或者

data.coalesce(1,true).saveAsTextFile()

也或者

data.repartition(1).saveAsTextFile( )       //You can also use repartition(1), which is just a wrapper for coalesce() with the suffle argument set to true.

data.repartition(1).saveAsTextFile( “HDFS://OUTPUT”) 

但是如果你的数据很大,难以在单机内存上装下,以上操作可能会造成单机内存不足。

原因在于以上操作都是讲分布在各个机器上的数据汇总到单机,然后再保存到磁盘(HDFS)上。

以上操作将各个机器上的RDD partition 合并到单一主机后再读入磁盘。

以下给出更安全的操作,即采用HDFS磁盘合并操作。

如果已经存了很多个part: 
可以把大文件夹getmerge:

把HDFS 上的多个文件 合并成一个  本地文件:

hadoop fs -getmerge /hdfs/output /local/file.txt

也可以:

hadoop fs -cat /hdfs/output/part-r-* > /local/file.txt

### Spark RDD 编程教程 RDD(Resilient Distributed Dataset)是 Spark 的核心抽象之一,表示一个不可变的、分区的数据集[^4]。它可以被并行操作,并支持多种转换和动作操作。 #### 创建 RDD 可以通过两种方式创建 RDD: 1. **从外部存储加载数据**:例如 HDFS 文件或其他分布式文件系统中的文件。 2. **通过已有的 Scala 集合对象**:适用于小型测试数据集。 以下是基于 `spark-shell` 的交互式编程示例: ```scala // 加载本地文件作为 RDD val textFile = sc.textFile("file:///path/to/your/file.txt") // 使用集合创建 RDD val data = Array(1, 2, 3, 4, 5) val distData = sc.parallelize(data) // 显示前几个元素 textFile.take(5).foreach(println) distData.collect().foreach(println) ``` 上述代码展示了如何从文件或内存数组中创建 RDD 并查看其内容。 --- ### Spark Shell 交互式编程 示例 `spark-shell` 是一种快速启动 Spark 上下文的方式,适合开发人员进行调试和原型设计[^2]。以下是一个简单的交互式编程流程: #### 启动 Spark Shell 运行命令如下: ```bash bin/spark-shell ``` 这将在本地模式下启动 Spark,默认绑定地址为 `http://localhost:4040`,提供 Web UI 查看任务状态。 #### 数据处理实例 假设有一个名为 `input.txt` 的文本文件,其中每行包含若干单词。我们希望统计每个单词出现的次数。 ```scala // 读取文件并分割成单词 val lines = sc.textFile("file:///path/to/input.txt") val words = lines.flatMap(line => line.split(" ")) // 将每个单词映射为 (word, 1),然后按 key 聚合计数 val wordCounts = words.map(word => (word, 1)).reduceByKey(_ + _) // 输出结果 wordCounts.foreach(println) ``` 此代码片段实现了经典的 WordCount 功能,利用了 RDD 的 `flatMap`、`map` 和 `reduceByKey` 方法[^5]。 --- ### 关键方法解析 - **Transformation**: 如 `map`, `filter`, `flatMap`, `groupByKey`, `reduceByKey` 等用于定义计算逻辑。 - **Action**: 如 `collect`, `count`, `take`, `saveAsTextFile` 等触发实际计算。 这些方法共同构成了 Spark 中的核心编程模型。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值