从pyspark中的s3存储桶中检索数据

时间:2017-11-03 11:50:50

标签: amazon-s3 pyspark

我正在pyspark的s3桶中读取数据。我需要并行化读操作并对数据进行一些转换。但它的投掷错误。以下是代码。

s3 = boto3.resource('s3',aws_access_key_id=access_key,aws_secret_access_key=secret_key)
bucket = s3.Bucket(bucket)

prefix = 'clickEvent-2017-10-09'
files = bucket.objects.filter(Prefix = prefix)
keys=[k.key for k in files]
pkeys = sc.parallelize(keys)

我有一个全局变量d,这是一个空列表。我正在将deviceId数据附加到此。

applying flatMap on the keys

pkeys.flatMap(map_func)

这个功能

 def map_func(key):
   print "in map func"
   for line in key.get_contents_as_string().splitlines():
    # parse one line of json
     content = json.loads(line)
     d.append(content['deviceID'])

但是上面的代码给了我错误。 任何人都可以帮忙!

1 个答案:

答案 0 :(得分:0)

我可以看到两个问题。首先是您尝试使用boto从S3手动读取数据,而不是使用内置于spark和hadoop中的直接S3支持。看起来您正在尝试读取每行包含json记录的文本文件。如果是这种情况,你可以在spark中执行此操作:

df = spark.read.json('s3://my-bucket/path/to/json/files/')

这将为您创建一个spark DataFrame,方法是将每一行作为一行读入JSON数据。 DataFrames需要一个严格的预定义模式(如关系数据库表),它试图通过对一些JSON数据进行采样来确定。获得DataFrame后,您需要做的只是选择它:

df.select('deviceID')

值得指出的另一个问题是,您正在尝试使用全局变量来存储在spark群集中计算的数据。可以使用广播变量或隐式闭包将数据从驱动程序发送到在spark worker上运行的所有执行程序。但是没有办法从执行程序写入驱动程序中的变量!要将数据从执行程序传回驱动程序,您需要使用spark的Action方法来实现此目的。

动作是告诉你想要计算结果的火花的方法,所以它需要执行你告诉它的变换。在你的情况下,你可能想要:

如果结果很大:使用DataFrame.write将转换结果保存回S3

如果结果很小: DataFrame.collect()将它们下载回驱动程序并使用它们执行某些操作

相关问题