Spark:Spark csv花费的时间太长

Spark:Spark csv花费的时间太长,csv,apache-spark,pyspark,Csv,Apache Spark,Pyspark,我正在尝试使用DataRicks软件包和: 这不会在4个m3.xlarges的集群上终止。我正在寻找从PySpark中S3上的CSV文件创建数据帧的建议。或者,我尝试将文件放在HDFS上并从HFD读取,但这也没有终止。文件不太大(12 GB)。要读取性能良好的仅为12 GB的csv文件,您可以将其复制到所有Worker和驱动程序计算机上,然后在“,”上手动拆分。这可能不会解析任何RFC4180 csv,但它解析了我所拥有的 在申请群集时,为每个工作线程至少添加12GB的额外工作线程磁盘空间 使

我正在尝试使用DataRicks软件包和:


这不会在4个
m3.xlarge
s的集群上终止。我正在寻找从PySpark中S3上的CSV文件创建
数据帧的建议。或者,我尝试将文件放在HDFS上并从HFD读取,但这也没有终止。文件不太大(12 GB)。

要读取性能良好的仅为12 GB的csv文件,您可以将其复制到所有Worker和驱动程序计算机上,然后在“,”上手动拆分。这可能不会解析任何RFC4180 csv,但它解析了我所拥有的

  • 在申请群集时,为每个工作线程至少添加12GB的额外工作线程磁盘空间
  • 使用至少有12GB RAM的机器类型,如
    c3.2xlarge
    。如果您不想让集群保持闲置状态,并且可以负担更高的费用,那么就扩大规模。更大的机器意味着要开始的磁盘文件拷贝更少。我经常在现货市场上看到c3.8XL低于每小时0.50美元
将文件复制到每个worker上的同一目录中的每个worker。这应该是物理连接的驱动器,即每台机器上的不同物理驱动器

确保驱动程序计算机上也有相同的文件和目录

raw = sc.textFile("/data.csv")

print "Counted %d lines in /data.csv" % raw.count()

raw_fields  = raw.first()
# this regular expression is for quoted fields. i.e. "23","38","blue",...
matchre = r'^"(.*)"$'
pmatchre = re.compile(matchre)

def uncsv_line(line):
    return [pmatchre.match(s).group(1) for s in line.split(',')]

fields = uncsv_line(raw_fields)

def raw_to_dict(raw_line):
    return dict(zip(fields, uncsv_line(raw_line)))

parsedData = (raw
        .map(raw_to_dict)
        .cache()
        )

print "Counted %d parsed lines" % parsedData.count()
parsedData将是DICT的RDD,其中DICT的键是第一行的CSV字段名,值是当前行的CSV值。如果CSV数据中没有标题行,这可能不适合您,但应该清楚的是,您可以覆盖读取第一行的代码并手动设置字段

请注意,这对于创建数据帧或注册sparksql表并不是立即有用的。但对于其他任何东西,它都是可以的,如果需要将它转储到spark SQL中,您可以进一步提取它并将其转换为更好的格式


我在一个7GB的文件上使用它,没有任何问题,只是我删除了一些过滤逻辑来检测有效数据,这会对从解析数据中删除头产生副作用。您可能需要重新实现一些过滤

保罗,谢谢你的评论,我很感激你能回答我的问题。但是你会建议一种不同的方法吗?比如先将CSV从HDFS读入配置单元,然后从配置单元表创建数据帧?考虑到基础设施,将12 GB文件作为数据帧读取的最佳方式是什么?抱歉,我们目前不使用HDFS/Hive基础设施,因此没有意见。Paul,请提供一些细节,说明如何获取dict的RDD并从中生成
数据帧
?使用map和lambda函数将每个dict转换为所需值的值元组。手动编写模式。如果您需要每行的所有值,那么将解析映射更改为不使用zip可能更容易。我还没有运行过这些,但对我来说似乎是合理的。如果你只需要快速SQL,你也可以看看谷歌专有的托管BigQuery。扫描每TB成本为5美元,外加每月2美分每gb的存储成本。如果spark csv lib是1.2.0+版本,您可以尝试将
parserLib
选项设置为
univocity
?@rchukh不是默认值吗?我今天从师傅那里造了这个罐子。编辑:不,不是。我会试试的。
raw = sc.textFile("/data.csv")

print "Counted %d lines in /data.csv" % raw.count()

raw_fields  = raw.first()
# this regular expression is for quoted fields. i.e. "23","38","blue",...
matchre = r'^"(.*)"$'
pmatchre = re.compile(matchre)

def uncsv_line(line):
    return [pmatchre.match(s).group(1) for s in line.split(',')]

fields = uncsv_line(raw_fields)

def raw_to_dict(raw_line):
    return dict(zip(fields, uncsv_line(raw_line)))

parsedData = (raw
        .map(raw_to_dict)
        .cache()
        )

print "Counted %d parsed lines" % parsedData.count()