我在s3存储桶中有大量文件(~500k hdf5),我需要处理并重新上传到另一个s3存储桶。
我对这些任务很陌生,所以我不太确定我的方法是否正确。我做以下事情: 我使用boto来获取存储桶中的密钥列表并将其与spark并行化:
s3keys = bucket.list()
data = sc.parallelize(s3keys)
data = data.map(lambda x: download_process_upload(x))
result = data.collect()
其中download_process_upload
是一个下载密钥指定文件的函数,对其进行一些处理并将其重新上传到另一个桶(如果一切成功则返回1,如果有错误则返回0)
所以最后我能做到
success_rate = sum(result) / float(len(s3keys))
我已经读过spark map
语句应该是无状态的,而我的自定义map函数肯定不是无状态的。它将文件下载到磁盘,然后将其加载到内存等。
这是执行此类任务的正确方法吗?
答案 0 :(得分:0)
我已成功使用您的方法从S3下载和处理数据。我没有尝试从map语句中上传数据。但是,我认为没有理由不能从s3读取文件,处理它,然后将其上传到新位置。
此外,您可以保存一些击键并从地图语句中取出显式lambda,如data = data.map(download_process_upload)
答案 1 :(得分:0)
这样做有什么好处? Spark用于并行处理,在这里我可以看到很可能仅使用单个主节点进行处理。请查看Spark UI,您将看到仅运行一个执行程序。
如果将数据重新分区到几个分区,则会因未在节点中找到某些下载文件而导致错误(本地fs)。为了克服这个问题,您将必须使用hdfs或挂载共享的fs 从性能的角度来看,您的解决方案等于:
对于数据中的元素: download_process_upload(element)
它将为每个元素运行您的函数,而无需任何并行化。