我正在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'])
但是上面的代码给了我错误。 任何人都可以帮忙!
答案 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()将它们下载回驱动程序并使用它们执行某些操作