目录:
5、数据读取与保存
5.1、文件格式
表5-1:Spark支持的一些常见格式
格式文件 | 结构化 | 备注 |
文本文件 | 否 | 普通的文本文件,每行一条记录 |
JSON | 半结构化 | 常见的基于文本的格式,通常在电子表格应用中使用一种用于键值对数据的常见Hadoop文件格式 |
CSC | 是 | 非常常见的基于文本的格式,通常在电子表格应用各种使用 |
SequenceFiles | 是 | 一种用于键值对数据的常见Hadoop文件格式 |
Protocol buffers | 是 | 一种快速、节约空间的跨语言格式 |
对象文件 | 是 | 用来将Spark作业中的数据存储下来以让共享的代码读取。改变类的时候它会失效,因为它依赖于Java序列化 |
5.1.1、文本文件
在Spark中读写文本文件很容易。当我们将一个文本文件读取为RDD时,输入的一行都会成为RDD的一个元素。也可以将多个完成的文本文件一次性读取为一个pairRDD,其中键是文件名,值是文件内容。
1、读取文本文件:
只需要使用文件路径作为参数调用SparkContext中的textFile()的函数,就可以读取一个文本文件。
在Scale中读取一个文本文件:
val input = sc.textFile(“README.MD”)
在Java中读取一个文本文件:
JavaRDD<String> input = sc.textFile(“README.ME”);
如果多个输入文件以一个包含数据所有部分的目录的形式出现,可以用两种方式来处理。可以仍使用textFile函数,传递目录作为函数,这样它会把各部分都读取到RDD中。有时候有必要知道数据的各部分分别来自哪个文件(比如将键放在文件名中的时间数据),有时候则希望同时处理整个文件。如果文件足够小,那么可以使用SparkContext.wholeTextFiles()方法,该方法会返回一个pairRDD,其中键是输入文件的文件名。
2、保存文本文件:
saveAsTextFile()方法接收一个路径,并将RDD中的内容都输入到路径对应的文件中。Spark将传入的路径作为目录对待,会在那个目录下输出多个文件。
5.1.2、JSON
1、在Java中读取JSON:
2、保存JSON
5.1.3、逗号分隔值与制表符分隔值
1、读取CSV:
如果恰好你的CSV的所有数据字段均没有包含换行符,可以直接使用textFile()读取并解析数据。
在Java中使用textFile()读取CSV:
如果在字段中嵌有换行符,就需要完整读入每个文件,然后解析各段。
在Java中完整读取CSV:
2、保存CSV:
调用saveAsTextFile(outFile)方法。
5.1.4、SequenceFile
SequenceFile是由没有相对关系结构的键值对文件组成的常用Hadoop格式。SequenceFile文件有同步标记,Spark可以用来定位到文件中某个点,然后再与记录的边界对其。
由于 Hadoop 使用了一套自定义的序列化框架,因此 SequenceFile 是由实现 Hadoop 的 Writable
接口的元素组成。
表5-2:HadoopWritable类型对应表:
1、读取SequenceFile:
2、在Java中保存SequenceFile
在Java 中保存SequenceFile要稍微复杂一些,因为JavaPairRDD上没有saveAsSequenceFile()方法。我们要使用Spark保存自定义Hadoop格式的功能来实现。
5.1.5、对象文件
对象文件看起来就像是对 SequenceFile 的简单封装,它允许存储只包含值的 RDD。和SequenceFile 不一样的是,对象文件是使用 Java 序列化写出的。
要保存对象文件,只需在 RDD 上调用 saveAsObjectFile() 就行了。读回对象文件也相当简单:用 SparkContext 中的 objectFile() 函数接收一个路径,返回对应的 RDD。
5.2、文件系统
5.2.1、本地/“常规”文件系统
Spark支持从本地系统文件中读取文件,不够它要求文件在集群中所有节点的相同路径下都可以找到。一些像 NFS、AFS 以及 MapR 的 NFS layer 这样的网络文件系统会把文件以常规文件系统的形式暴露给用户。如果你的数据已经在这些系统中,那么你只需要指定输入为一个 file://路径;只要这个文件系统挂载在每个节点的同一个路径下,Spark 就会自动处理。
如果文件还没有放在集群中的所有节点上,你可以在驱动器程序中从本地读取该文件而无需使用整个集群,然后再调用 parallelize 将内容分发给工作节点。不过这种方式可能会比较慢,所以推荐的方法是将文件先放到像 HDFS、NFS、S3 等共享文件系统上。
5.2.3、HDFS
在 Spark 中使用 HDFS 只需要将输入输出路径指定为 hdfs://master:port/path 就够了。