Spark从外部读取数据之textFile

本文详细介绍了如何使用Spark的textFile函数从不同位置(如HDFS、本地文件系统等)读取文本文件,并将其转换为字符串类型的RDD。此外,还讲解了如何通过设置最小分区数来控制RDD的分区。

Spark从外部读取数据之textFile

标签: spark大数据数据源码
  17091人阅读  评论(7)  收藏  举报
  分类:

textFile函数

  1. /** 
  2.    * Read a text file from HDFS, a local file system (available on all nodes), or any 
  3.    * Hadoop-supported file system URI, and return it as an RDD of Strings. 
  4.    */  
  5.   def textFile(  
  6.       path: String,  
  7.       minPartitions: Int = defaultMinPartitions): RDD[String] = withScope {  
  8.     assertNotStopped()  
  9.     hadoopFile(path, classOf[TextInputFormat], classOf[LongWritable], classOf[Text],  
  10.       minPartitions).map(pair => pair._2.toString).setName(path)  
  11.   }  
分析参数:

path: String 是一个URI,這个URI可以是HDFS、本地文件(全部的节点都可以),或者其他Hadoop支持的文件系统URI返回的是一个字符串类型的RDD,也就是是RDD的内部形式是Iterator[(String)]

minPartitions=  math.min(defaultParallelism, 2) 是指定数据的分区,如果不指定分区,当你的核数大于2的时候,不指定分区数那么就是 2

当你的数据大于128M时候,Spark是为每一个快(block)创建一个分片(hadoop-2.X之后为128m一个block)

1、从当前目录读取一个文件

  1. val path = "Current.txt"  //Current fold file  
  2. val rdd1 = sc.textFile(path,2)  

从当前目录读取一个Current.txt的文件

2、从当前目录读取多个文件

  1. val path = "Current1.txt,Current2.txt,"  //Current fold file  
  2. val rdd1 = sc.textFile(path,2)  
从当前读取两个文件,分别是Cuttent1.txt和Current2.txt


3、从本地系统读取一个文件

  1. val path = "file:///usr/local/spark/spark-1.6.0-bin-hadoop2.6/README.md"  //local file  
  2. val rdd1 = sc.textFile(path,2)  
从本地系统读取一个文件,名字是README.md

4、从本地系统读取整个文件夹

  1. val path = "file:///usr/local/spark/spark-1.6.0-bin-hadoop2.6/licenses/"  //local file  
  2. val rdd1 = sc.textFile(path,2)  
从本地系统中读取licenses这个文件夹下的所有文件

這里特别注意的是,比如這个文件夹下有35个文件,上面分区数设置是2,那么整个RDD的分区数是35*2?

這是错误的,這个RDD的分区数不管你的partition数设置为多少时,只要license這个文件夹下的這个文件a.txt

(比如有a.txt)没有超过128m,那么a.txt就只有一个partition。那么就是说只要这35个文件其中没有一个超过

128m,那么分区数就是 35个

5、从本地系统读取多个文件

  1. val path = "file:///usr/local/spark/spark-1.6.0-bin-hadoop2.6/licenses/LICENSE-scala.txt,file:///usr/local/spark/spark-1.6.0-bin-hadoop2.6/licenses/LICENSE-spire.txt"  //local file  
  2. val rdd1 = sc.textFile(path,2)  
从本地系统中读取file:///usr/local/spark/spark-1.6.0-bin-hadoop2.6/licenses/下的LICENSE-spire.txt和

LICENSE-Scala.txt两个文件。上面分区设置是2,那个RDD的整个分区数是2*2

6、从本地系统读取多个文件夹下的文件(把如下文件全部读取进来)



  1. val path = "/usr/local/spark/spark-1.6.0-bin-hadoop2.6/data/*/*"  //local file  
  2. val rdd1 = sc.textFile(path,2)  

采用通配符的形式来代替文件,来对数据文件夹进行整体读取。但是后面设置的分区数2也是可以去除的。因为一个文件没有达到128m,所以上面的一个文件一个partition,一共是20个。

7、采用通配符,来读取多个文件名类似的文件

比如读取如下文件的people1.txt和people2.txt,但google.txt不读取


  1. for (i <- 1 to 2){  
  2.       val rdd1 = sc.textFile(s"/root/application/temp/people$i*",2)  
  3.     }  
8、采用通配符读取相同后缀的文件

  1. val path = "/usr/local/spark/spark-1.6.0-bin-hadoop2.6/data/*/*.txt"  //local file  
  2. val rdd1 = sc.textFile(path,2)  


9、从HDFS读取一个文件
  1. val path = "hdfs://master:9000/examples/examples/src/main/resources/people.txt"  
  2. val rdd1 = sc.textFile(path,2)  
从HDFS中读取文件的形式和本地上一样,只是前面的路径要表明是HDFS中的
### 关于 Spark 从 HDFS 读取数据进行分布式批处理的思维导图 以下是对 Spark 从 HDFS 读取数据并进行分布式批处理的核心流程解析,涵盖数据加载、转换、分析和结果输出的关键环节,并提供完整的思维导图。 --- ### 1. **核心概念解析** #### (1)HDFS(Hadoop Distributed File System) - HDFS 是一种分布式的文件系统,能够高效存储大规模的数据集。 - Spark 支持直接从 HDFS 中读取数据作为其计算的基础输入[^1]。 #### (2)SparkContext - SparkContext 是 Spark 应用程序的入口点,负责初始化集群环境并与资源管理器交互。 - 它提供了方法来创建 RDD 或 DataFrame/Dataset 来表示数据集。 #### (3)RDD(Resilient Distributed Dataset) - RDD 是 Spark 的基本抽象,表示不可变的分布式对象集合。 - 用户可以通过 Transformation 操作对 RDD 进行转换,或者通过 Action 操作触发实际计算[^1]。 #### (4)Transformation 和 Action - **Transformation**:如 `map()`、`filter()`、`reduceByKey()` 等操作,用于定义数据变换逻辑。 - **Action**:如 `collect()`、`count()`、`saveAsTextFile()` 等操作,用于触发实际计算并返回结果或写入外部存储。 #### (5)Shuffle 操作 - 当 Transformation 导致数据重新分区时会发生 Shuffle 操作。 - Shuffle 是分布式计算中的昂贵操作,应尽量减少以提高性能。 --- ### 2. **Spark 从 HDFS 读取数据的批处理流程** #### (1)初始化 SparkContext - 创建 SparkConf 对象配置应用程序参数。 - 初始化 SparkContext 实例连接到集群。 #### (2)加载数据 - 使用 `sc.textFile(path)` 方法从指定路径加载 HDFS 数据为 RDD。 - 数据按块分割成多个 Partition,默认情况下每个 Block 映射为一个 Partition[^1]。 #### (3)数据清洗与转换 - 利用 Transformation 操作清理和预处理原始数据。 - 常见的操作包括过滤无效记录 (`filter()`)、切分字段 (`map()`) 等。 #### (4)数据分析 - 使用 Transformation 和 Action 组合实现复杂的数据分析任务。 - 示例:统计某个键值对的频率 (`map().reduceByKey()`)。 #### (5)结果输出 - 将最终结果保存回 HDFS 或打印至控制台。 - 使用 `result.saveAsTextFile(output_path)` 方法将结果写入目标目录。 --- ### 3. **思维导图** 以下是 Spark 从 HDFS 读取数据进行分布式批处理的整体流程及关键步骤的思维导图: ``` Spark 分布式批处理流程 ├── 初始化 SparkContext │ └── 创建 SparkConf 并启动 SparkContext ├── 加载数据 │ └── 使用 sc.textFile('hdfs://...') 从 HDFS 加载数据 ├── 数据清洗与转换 │ ├── filter(): 过滤掉不符合条件的记录 │ └── map(): 提取所需字段或将数据映射为目标结构 ├── 数据分析 │ ├── reduceByKey(): 聚合相同 key 的 value │ └── groupByKey(): 按照 key 分组聚合 ├── 结果输出 │ ├── saveAsTextFile(): 将结果保存到 HDFS │ └── collect(): 获取结果并在驱动端显示 └── 清理资源 └── 停止 SparkContext (sc.stop()) ``` --- ### 4. **注意事项** - 在设计 Transformation 流程时,尽量避免不必要的 Shuffle 操作以降低性能开销。 - 合理设置分区数以充分利用集群资源,可通过 `repartition()` 或 `coalesce()` 动态调整。 - 使用广播变量传递只读共享数据,使用累加器收集全局汇总信息。 --- ### --相关问题--: 1. 如何优化 Spark 作业中从 HDFS 读取大数据量时的性能? 2. 在 Spark 批处理过程中,如何有效减少 Shuffle 操作带来的影响? 3. 是否可以自定义 Partitioner 来改进数据分布策略?如果可以,具体该如何实现? 4. Spark 中的广播变量适用于哪些场景?它有哪些优势和局限性? 5. 如果在 Spark 作业中遇到 OOM 错误,应该采取哪些措施解决该问题?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值