我正在尝试分发从s3获取6000万个密钥(文件名)列表的过程。
背景 我试图通过pyspark处理文件夹中的所有文件,大约6000万。详细信息HERE,典型的sc.textFile('s3a:// bucket / *')会将所有数据加载到驱动程序中,然后将其分发到集群中。建议的方法是首先获取文件列表,并行化列表,然后让每个节点获取文件的子集。
问题: 在此方法中,如果该列表足够大,则“获取文件列表”步骤仍然存在瓶颈。获取s3存储桶中的密钥(文件名)列表的步骤也必须分发才能有效。
我尝试过的事情: 我尝试了两种不同的方法:
使用python aws api(boto3),它会对结果进行分页。理想情况下,我们可以估计页数,并分配范围,以便节点1请求页面1-100,节点2将请求页面101-200,等等。不幸的是,您不能指定任意页面ID,您必须得到“下一个标记“来自前一页,也就是结果的链接列表。
aws cli,允许排除和包含过滤器。由于我检索的文件名全部以8位数字开头,理论上我可以让节点一请求匹配10 *的文件的完整文件列表,第二个节点请求匹配11的文件名的完整文件列表*等。这可以通过以下方式完成:
aws s3 --recursive --exclude =“”include =“10 ”s3:// bucket /
不幸的是,似乎每个请求都在执行完全扫描,而不是使用某个索引,因为它挂起了>每个请求15分钟。
有没有办法让这两种解决方案都可行?有第三种选择吗?我确信我并不是唯一一个需要消化数百万个s3文件的人。
答案 0 :(得分:4)
如果您需要Amazon S3内容列表并且您不需要它完全是最新的,您可以使用Amazon S3 Storage Inventory,它将存储S3存储桶中所有文件的每日CSV列表。然后,您可以使用该列表来触发您的pyspark工作。
类似地,您可以维护所有文件的数据库,并使用Amazon S3 Event Notifications在从桶中添加/删除对象时更新数据库的过程。这样,列表始终是最新的,可供您的pyspark工作使用。
答案 1 :(得分:0)
如果您的文件名足以作为分解文件的方法,则可以使用list_objects_v2
的Prefix
参数。