Spark数据读取与保存

Spark支持多种数据源

  • 文件格式
  • 文件系统
  • SparkSQL结构化数据
  • 数据库

文件格式

支持的文件格式有文本文件、SequenceFile、序列化对象、Hadoop输入输出格式protocol buffer、压缩文件等。介绍几种常见的文件格式api

文本文件

1、读取文本文件

文本文件输入的每一行作为RDD的一个元素,或者将一个完整的文件已文件名-文件内容键值对的形式读取。

val input = sc.textFile("path") //文本每一行为一个元素  在结尾加*表示当前文件夹下多个文件

val wholeInput = sc.textFile("path") //RDD格式为 pair RDD key:文件名 value 文件内容

2、保存文本文件

result.saveAsTextFile("outputPath")
  • JSON

文件处理方式同文本文件,每行为一个JSONObject对象

  • CSV

文件处理方式同文本文件,处理csv格式文件需要引入csv maven约束

<dependency>
    <groupId>net.sf.opencsv</groupId>
    <artifactId>opencsv</artifactId>
    <version>2.3</version>
</dependency>
SequenceFile

SequenceFile是没有相对关系结构的键值对文件组成的Hadoop格式。文件格式以记录为单位,每条记录是一个键值对。SequenceFile提供压缩机制,通过对记录进行压缩,实现文件的大量存储。

//文件输入路径   key值泛型  value值泛型
val seqData = sc.sequenceFile[String,IntWritable]("path",classOf[String],classOf[IntWritable])
                .map{case (x, y) => (x.toString, y.get())}
//文件输出路径
seqData.saveAsSequenceFile("outputPath")
序列化对象

读取对象文件的形式,存在性能慢,修改字段后历史数据失效的问题。

但拥有保存任意对象不需要额外工作内容的优势。

val objectData = sc.objectFile("inputPath")
objectData.saveAsObjectFile("outputPath")

文件系统

Spark支持从本地文件系统中读取文件,但是需要保证文件在集群的所有节点的相同路径下都可以找到。

NFSAFS

从网络文件系统中读取文件,只需要把文件当做本地文件进行处理即可。

val rdd = sc.textFile("file:///data/file.txt")
Amazon S3

访问S3数据需要将访问凭证AWS_ACCESS_KEYAWS_SECRET_ACCESS_KEY设置为环境变量。并保证访问账号具有readlist权限。

HDFS

Spark访问HDFS可以将两个分布式服务都部署在相同的节点上,这样能尽量的避免一些网络开销。

Spark SQL

后面详细讲解

数据库

Spark支持多种数据库类型:MySQL、Cassandra、HBase、Elasticsearch等,介绍两种常见数据源api:

MySQL
//处理结果集  结果集转换为rdd
def extractValues(r: ResultSet): (String, String)= {
    ((r.getString(1),r.getString(2)))
}
//获取数据库连接对象
def createConnection(): Connection = {
    Class.forName("com.mysql.jdbc.Driver").newInstance()
    DriverManager.getConnection("jdbc:mysql://localhost/test?user=root")
}
//连接api  
val data = new JdbcRDD(sc, createConnection,"SELECT * FROM test",1,3,2,extractValues)

参数讲解:

/**
sc:SparkContext

createConnection:Connection连接对象

"SELECT * FROM test":sql查询语句

1:lowerBound 查询分区下界

3:upperBound 查询分区上界

2:numPartitions 分区数

extractValues:结果集转换为rdd的函数

lowerBound与upperBound与numPartitions三个参数表示:结果集为从1到3[),有两条数据,分别存储到2个分区中。这样先对结果集进行预先判断的方式,防止结果集存储到一个分区中,导致一个节点内存溢出。
*/
HBase

Spark连接HBase并读取HBase表数据,默认读取resource路径下的hbase-default.xmlhbase-site.xml

import org.apache.hadoop.hbase.HBaseConfiguration
import org.apache.hadoop.hbase.client.Result
import org.apache.hadoop.hbase.io.ImmutableBytesWritable
import org.apache.hadoop.hbase.mapreduce.TableInputFormat

...

val conf = HBaseConfiguration.create()
conf.set(TableInputFormat.INPUT_TABLE,"tablename")

//配置 读取设置项  key值类型  value值类型  
val rdd = sc.newAPIHadoopRDD(conf, classOf[TableInputFormat], classOf[ImmutableBytesWritable], classOf[Result])