spark数据读取与保存(python)

spark支持多种输入源
常见3种数据源

  • 文件格式与文件系统
    spark可以访问很多种不同的文件格式,包括文本文件、JSON、SequenceFile、protocol buffer.
  • Spark SQL结构化数据源
    包括针对JSON、Apache Hive在内的结构化数据
  • 数据库与键值存储
    spark自带库和一些第三方库,可以用来连接Cassandra、HBase、Elasticsearch以及JDBC源

文件格式

spark支持常见格式
在这里插入图片描述

文本文件

可以将一个文本文件读取为RDD,输入的每一行都会成为RDD的一个元素。或者一次读取多个文件为一个pair RDD,键是文件名,值是文件内容。

1.读取文本文件
调用SparkContext 的textFile()函数,如果要控制分区数,可以指定minPartitions

input = sc.textFile("file:///**.txt")

如果读取一个目录下所有文件,有两种方式处理,textFile,会把各部分都读取到RDD中。如果想要知道数据来自哪个文件,且文件较小,可以用SparkContext的wholeTextFiles()方法,返回一个pair RDD.

spark支持读取给定目录的所有文件,以及输入路径中使用通配符

2.保存文本文件
saveAsTextFile()方法接受路径,并将RDD中的内容输入到对应路径中,spark将传入的路径作为目录对待,会在哪个目录下输出多个文件。
不能控制哪一部分输出到哪个文件,不过可以有些输出格式支持

rdd.saveAsTextFile(outputFile)
JSON

1.读取json
最简单的方式是将数据作为文本文件读取,然后使用JSON解析器来对RDD的值进行映射操作
该方法假设每一行都是一条JSON记录,如果有跨行数据,就只能读入整个文件进行解析

import json
data = input.map(lambda x:json.loads(x))

2.保存json
将字符串RDD转为解析好的JSON数据的库,将由结构化数据组成的RDD转为字符串RDD

(data.filter(lambda x:x["xx"]).map(lambda x:json.dumps(x)).saveAsTextFile(outputfile)
逗号分隔值与制表符分隔值

与JSON中的字段不一样的是,这里的每条记录都没有相关联的字段名,只能得到对应的序号。常规做法是使用第一行每列的值作为字段名。
1.读取CSV
与读取JSON数据类似,都需要先把文件当做普通文本文件来读取,再对数据进行处理。
如果CSV的所有数据字段均没有包含换行符,可以使用textFile读取并解析数据

import csv
import StringIO
def loadRecord(line):
	input = StringIO.StringIO(line)
	reader = csv.DictReader(input,fieldnames=['name'])
	return reader.next()
input = sc.textFile(inputFile).map(loadRecord)

如果在字段中嵌有换行符,需要完整读入整个文件,然后解析

import csv
import StringIO
def loadRecordS(fileNameContents):
	input = StringIO.StringIO(fileNameContents[1])
	reader = csv.DictReader(input,fieldnames=['name'])
	return reader
fullFileData = sc.wholeTextFile(inputFile).flatMap(loadRecord)

可能需要对输入数据进行重新分区使得Spark能够高效地并行化执行后续操作

2.保存CSV
由于CSV不会在每条记录中输出字段名,因此为了使输出保持一致,需要创建一种映射关系。

一种简单做法是写一个函数,用于将各字段转为指定顺序的数据。在Python中,如果输出字典,CSV输出器会根据输出器时指定的fieldnames顺序完成这一行为

import StringWriter
import StringIO
def writeRecords(records):
	output = StringIO.StringIO()
	writer = csv.DictWriter(output,fieldnames=['name'])
	for record in records:
		writer.writerow(record)
	return [output.getvalue()]
rdd.mapPartitions(writeRecords).saveAsTextFile(outputfile)

如果字段名未知,则需要使用其他方法,比如遍历所有的数据,提取不同的键,然后分别输出

SequenceFile

SequenceFile 是由没有相对关系结构的键值对文件组成的常用 Hadoop 格式。SequenceFile文件有同步标记,Spark 可以用它来定位到文件中的某个点,然后再与记录的边界对齐。这可以让 Spark 使用多个节点高效地并行读取 SequenceFile 文件。SequenceFile 也是Hadoop MapReduce 作业中常用的输入输出格式,所以如果你在使用一个已有的 Hadoop 系统,数据很有可能是以 SequenceFile 的格式供你使用的。

由于 Hadoop 使用了一套自定义的序列化框架,因此 SequenceFile 是由实现 Hadoop 的 Writable接口的元素组成。下表 列出了一些常见的数据类型以及它们对应的 Writable 类。标准的经验法则是尝试在类名的后面加上 Writable 这个词,然后检查它是否是 org.apache.hadoop.io.Writable 已知的子类。如果你无法为要写出的数据找到对应的 Writable 类型(比如自定义的 case class),你可以通过重载 org.apache.hadoop.io.Writable 中的 readfields 和 write 来实现自己的 Writable 类。
  在这里插入图片描述

1.读取SequenceFile
Spark 有专门用来读取 SequenceFile 的接口。在 SparkContext 中,可以调用 sequenceFile(path,keyClass, valueClass, minPartitions) 。SequenceFile 使用 Writable 类,因此 keyClass 和 valueClass 参数都必须使用正确的 Writable 类。

data = sc.sequenceFile(inFile,"org.apach.hadoop.io.Text","org.apache.hadoop.io.InWritable")

2.保存SequenceFile
在 Scala 中将数据写出到 SequenceFile 的做法也很类似。可以直接调用 saveSequenceFile(path) 保存你的 PairRDD ,它会帮你写出数据。

scala代码

val data = sc.parallelize(List(("pandas",3),("Key",1)))
data.saveSequenceFile(outputFile)
对象文件

对象文件是用java序列化写出的,看起来就像SequenceFile的简单封装,它允许只包含值的RDD

要保存对象文件,只需在RDD上调用saveAsObjectFile。读取对象文件:用sparkContext中的objectFile()函数接受一个路径,返回对应RDD

对象文件在python中无法使用,鸡蛋时可以使用saveAsPickleFile()和pickleFile()方法作为替代。pickle库可能很慢,修改了类定义后,已经生产的数据文件可能无法再读出来

注意:
使用java序列化:对同样的对象,对象文件输出和Hadoop输出不一样,对象通常用于spark作业间通信,序列化很慢

hadoop输入输出格式

1.读取其他hadoop输入格式

keyValueTextInputFormat是最简单的Hadoop输入格式之一,可以用于文本文件读取键值对数据,每一行独立处理,键与值之间用制表符隔开。

scala

val input = sc.hadoopFile[Text,Text,scala](inputFile).map{
	case (x,y) => (x.toString,y.toString)
}

2.保存hadoop输出格式

在这里插入图片描述
3.非文件系统数据源
4.示例:protocol buffer

文件压缩

对数据进行压缩节省网络开销
在这里插入图片描述
有些输入格式,如SequenceFile允许只压缩键值对中数据的值

文件系统

本地/常规文件系统

sc.textFile("file:///'***.txt)

Amazon S3

HDFS
只需要把输入输出路径指定为hdfs://master:port/path

Spark SQL中的结构化数据

Spark SQL操作结构化和半结构化的数据的方式

在这里插入图片描述
hive
Spark SQL可以读取Hive支持的所有表

from pyspark.sql import HiveContext
hiveCtx = HiveContext(sc)
rows = hiveCtx("select name from uers")
firstRow = rows.first()
print(firstRow.name)

json
在这里插入图片描述
注册为一张表,然后取出特定字段

在这里插入图片描述

tweets = hiveCtx.jsonFile("tweets.json")
tweets.registerTempTable("tweets")
results = hiveCtx.sql("select name from uers")

数据库

java数据库连接

在这里插入图片描述

在这里插入图片描述

Cassandra

HBase
在这里插入图片描述
在这里插入图片描述

Elasticsearch

在这里插入图片描述

参考:《Spark快速大数据分析》
所有代码可以参考:https://github.com/databricks/learning-spark

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值