如何搜索亚马逊s3桶?

我有一个装满了上千份文件的桶。我如何搜索水桶?

260767 次浏览

S3没有原生的“搜索此桶”,因为实际内容是未知的-此外,由于S3是基于键/值的,因此没有原生的方法可以一次访问多个节点,而更传统的数据存储提供(SELECT * FROM ... WHERE ...)(在SQL模型中)。

你需要做的是执行ListBucket来获得bucket中对象的列表,然后遍历每个项,执行你实现的自定义操作——这就是你的搜索。

(至少)有两个不同的用例可以描述为“搜索桶”:

  1. 搜索某个inside存储在bucket中的每个对象;这假设该bucket中的所有对象(比如文本文件)都有一个通用的格式,等等。对于这样的事情,你不得不做科迪·考兰刚刚回答的事情。AWS S3文档有示例代码,展示了如何使用AWS SDK for Java做到这一点:列出键使用AWS SDK for Java(在那里你还会找到PHP和c#的例子)。

  2. 在该bucket中包含的keys对象中搜索内容;S3 doespartial对此的支持,形式是允许前缀精确匹配+分隔符后的折叠匹配。这在AWS S3开发者指南中有更详细的解释。这允许,例如,通过使用诸如

    文件夹/子文件夹/file.txt
    之类的对象键来实现“文件夹”。如果您遵循这个约定,大多数S3 gui(如AWS控制台)将向您显示存储桶的文件夹视图。

另一种选择是在您的web服务器上镜像S3桶并在本地遍历。诀窍在于本地文件是空的,只用作骨架。或者,本地文件可以保存您通常需要从S3获取的有用元数据(例如,文件大小、mimetype、作者、时间戳、uuid)。当您提供下载文件的URL时,在本地搜索,但要提供到S3地址的链接。

本地文件遍历很容易,而且这种用于S3管理的方法与语言无关。本地文件遍历还可以避免维护和查询文件数据库,或者延迟执行一系列远程API调用来验证和获取桶内容。

您可以允许用户通过FTP或HTTP直接将文件上传到您的服务器,然后在非高峰时段通过递归遍历任意大小文件的目录将一批新的和更新的文件传输到Amazon。在完成向Amazon的文件传输后,将web服务器文件替换为同名的空文件。如果一个本地文件有任何文件大小,那么直接提供它,因为它正在等待批量传输。

考虑到你在AWS…我认为你会想要使用他们的CloudSearch工具。把你想要搜索的数据放到他们的服务中…让它指向S3密钥。

http://aws.amazon.com/cloudsearch/

有多种选择,没有一个是简单的“一次性”全文解决方案:

  1. 键名模式搜索:搜索以某些字符串开头的键-如果您仔细设计键名,那么您可能有相当快速的解决方案。

  2. 搜索key附加的元数据:在向AWS S3发布文件时,您可以对内容进行处理,提取一些元信息,并将这些元信息以自定义头的形式附加到key中。这允许您获取键名和标头,而不需要获取完整的内容。搜索必须按顺序进行,没有“类似sql”的搜索选项。对于大文件,这可以节省大量的网络流量和时间。

  3. :如上所述,但是将元数据存储在SimpleDB上。这里有类似select语句的sql。在大数据集的情况下,您可能会遇到SimpleDB的限制,这是可以克服的(跨多个SimpleDB域划分元数据),但如果您真的需要使用另一种metedata类型的数据库。

  4. 顺序全文搜索的内容-逐个处理所有键。非常慢,如果你有太多的键要处理。

几年来,我们每天存储1440个版本的文件(每分钟一个),使用版本化桶,这是很容易实现的。但要获得一些较旧的版本需要时间,因为人们必须一个版本一个版本地按顺序进行。有时我使用简单的CSV记录索引,显示发布时间和版本id,有了这个,我可以很快跳转到旧版本。

正如你所看到的,AWS S3并不是为全文搜索而设计的,它是一个简单的存储服务。

这里要补充一点:现在已经3年了,但当你输入“如何搜索S3 Bucket”时,这篇文章是谷歌的顶部。

也许你正在寻找一些更复杂的东西,但如果你在这里试图弄清楚如何简单地通过标题找到一个对象(文件),这是疯狂的简单:

打开桶,选择右边的“none”,并开始输入文件名。

http://docs.aws.amazon.com/AmazonS3/latest/UG/ListingObjectsinaBucket.html < a href = " http://docs.aws.amazon.com/AmazonS3/latest/UG/ListingObjectsinaBucket.html " > < / >

看一下这个文档:http://docs.aws.amazon.com/AWSSDKforPHP/latest/index.html#m=amazons3/get_object_list

您可以使用perl兼容正则表达式(PCRE)来筛选名称。

我的方法是: 我在s3中有数千个文件。 我在列表中看到一个文件的属性面板。你可以看到该文件的URI,我复制粘贴到浏览器-这是一个文本文件,它呈现得很好。现在我用手边的uuid替换了url中的uuid文件就在这里。

我希望AWS有更好的方法来搜索文件,但这对我来说很管用。

试试这个命令:

aws s3api list-objects --bucket your-bucket --prefix sub-dir-path --output text --query 'Contents[].{Key: Key}'

然后,您可以将其输送到grep中,以获得特定的文件类型,以便对它们做任何您想做的事情。

在S3控制台中按前缀搜索

直接在AWS Console桶视图中。

enter image description here

使用s3-dist-cp复制需要的文件

当你有数千或数百万个文件时,另一种获取所需文件的方法是使用分布式复制将它们复制到另一个位置。你在Hadoop作业中的EMR上运行这个。关于AWS最酷的事情是他们提供了他们的自定义S3版本s3-dist-cp。它允许您在groupBy字段中使用正则表达式对需要的文件进行分组。例如,您可以在EMR的自定义步骤中使用它

[
{
"ActionOnFailure": "CONTINUE",
"Args": [
"s3-dist-cp",
"--s3Endpoint=s3.amazonaws.com",
"--src=s3://mybucket/",
"--dest=s3://mytarget-bucket/",
"--groupBy=MY_PATTERN",
"--targetSize=1000"
],
"Jar": "command-runner.jar",
"Name": "S3DistCp Step Aggregate Results",
"Type": "CUSTOM_JAR"
}
]

我做了如下的事情来在我的桶中寻找模式

def getListOfPrefixesFromS3(dataPath: String, prefix: String, delimiter: String, batchSize: Integer): List[String] = {
var s3Client = new AmazonS3Client()
var listObjectsRequest = new ListObjectsRequest().withBucketName(dataPath).withMaxKeys(batchSize).withPrefix(prefix).withDelimiter(delimiter)
var objectListing: ObjectListing = null
var res: List[String] = List()


do {
objectListing = s3Client.listObjects(listObjectsRequest)
res = res ++ objectListing.getCommonPrefixes
listObjectsRequest.setMarker(objectListing.getNextMarker)
} while (objectListing.isTruncated)
res
}

对于较大的存储桶,这会消耗太多时间,因为所有对象摘要都由Aws返回,而不仅仅是匹配前缀和分隔符的对象。我正在寻找提高性能的方法,到目前为止,我只发现我应该命名键,并将它们正确地组织在桶中。

下面是一个使用AWS CLI搜索文件名的简短而丑陋的方法:

aws s3 ls s3://your-bucket --recursive | grep your-search | cut -c 32-

AWS发布了一个新的服务,使用SQL: Amazon Athena https://aws.amazon.com/athena/查询S3桶

< p > 2018 - 07年现状: 亚马逊有本地sql像搜索csv和json文件!< / p >

https://aws.amazon.com/blogs/developer/introducing-support-for-amazon-s3-select-in-the-aws-sdk-for-javascript/

如果你在Windows上,没有时间找到一个好的grep替代方案,一个快速而肮脏的方法是:

aws s3 ls s3://your-bucket/folder/ --recursive > myfile.txt

然后在myfile.txt中快速搜索

“文件夹”位是可选的。

附注:如果你没有安装AWS CLI -这里有一个使用Chocolatey包管理器的一行程序

choco install awscli

P.P.S.如果你没有巧克力包装管理器-得到它!你在Windows上的生活将变得更好10倍。(我和Chocolatey没有任何关系,但是嘿,这是一个必须要有的,真的)。

我尝试了以下方法

aws s3 ls s3://Bucket1/folder1/2019/ --recursive |grep filename.csv

这将输出文件存在的实际路径

2019-04-05 01:18:35     111111 folder1/2019/03/20/filename.csv

这是一个有点旧的话题——但也许可以帮助那些仍然在搜索的人——我就是那个搜索了一年的人。

解决方案可能是“AWS雅典娜”,你可以像这样搜索数据

'SELECT user_name FROM S3Object WHERE cast(age as int) > 20'

https://aws.amazon.com/blogs/developer/introducing-support-for-amazon-s3-select-in-the-aws-sdk-for-javascript/

目前的定价是1TB数据5美元 -因此,例如,如果你的查询搜索超过一个1TB文件的3倍你的成本是15美元-但例如,如果只有1列的“转换柱状格式”你想读,你将支付价格的1/3,即1.67美元/TB。

我也面临同样的问题。在S3中进行搜索应该比目前的情况容易得多。这就是为什么我在S3中实现了这个用于搜索的开源工具。

SSEARCH是完全开源的S3搜索工具。它的实现始终牢记性能是关键因素,并根据基准测试在几秒钟内搜索包含~1000个文件的桶。

安装很简单。你只需要下载docker-compose文件并运行它

docker-compose up

搜索将开始,你可以在任何桶搜索任何东西。

快进到2020年,使用aws-okta作为我们的2fa,下面的命令,尽管迭代这个特定bucket(+270,000)中的所有对象和文件夹非常缓慢,但运行良好。

aws-okta exec dev -- aws s3 ls my-cool-bucket --recursive | grep needle-in-haystax.txt

使用Amazon Athena查询S3桶。另外,加载数据到Amazon Elastic搜索。希望这能有所帮助。

不是技术上的答案,但我已经构建了一个允许通配符搜索的应用程序:https://bucketsearch.net/

它将异步索引您的bucket,然后允许您搜索结果。

它是免费使用的(捐赠软件)。

虽然不是AWS本地服务,但有Mixpeek,它在您的S3文件上运行文本提取,如Tika, Tesseract和ImageAI,然后将它们放在Lucene索引中,使它们可搜索。

回顾文档在这里

积分如下:

  1. 下载模块:https://github.com/mixpeek/mixpeek-python

  2. 导入模块和API密钥:

     from mixpeek import Mixpeek, S3
    from config import mixpeek_api_key, aws
    
  3. 实例化S3类(使用boto3和请求):

     s3 = S3(
    aws_access_key_id=aws['aws_access_key_id'],
    aws_secret_access_key=aws['aws_secret_access_key'],
    region_name='us-east-2',
    mixpeek_api_key=mixpeek_api_key
    )
    
  4. 上传一个或多个现有S3文件:

         # upload all S3 files in bucket "demo"
    s3.upload_all(bucket_name="demo")
    
    
    # upload one single file called "prescription.pdf" in bucket "demo"
    s3.upload_one(s3_file_name="prescription.pdf", bucket_name="demo")
    
  5. 现在只需使用Mixpeek模块搜索:

         # mixpeek api direct
    mix = Mixpeek(
    api_key=mixpeek_api_key
    )
    # search
    result = mix.search(query="Heartgard")
    print(result)
    
  6. 结果可以是:

     [
    {
    "_id": "REDACTED",
    "api_key": "REDACTED",
    "highlights": [
    {
    "path": "document_str",
    "score": 0.8759502172470093,
    "texts": [
    {
    "type": "text",
    "value": "Vetco Prescription\nVetcoClinics.com\n\nCustomer:\n\nAddress: Canine\n\nPhone: Australian Shepherd\n\nDate of Service: 2 Years 8 Months\n\nPrescription\nExpiration Date:\n\nWeight: 41.75\n\nSex: Female\n\n℞  "
    },
    {
    "type": "hit",
    "value": "Heartgard"
    },
    {
    "type": "text",
    "value": " Plus Green 26-50 lbs (Ivermectin 135 mcg/Pyrantel 114 mg)\n\nInstructions: Give one chewable tablet by mouth once monthly for protection against heartworms, and the treatment and\ncontrol of roundworms, and hookworms. "
    }
    ]
    }
    ],
    "metadata": {
    "date_inserted": "2021-10-07 03:19:23.632000",
    "filename": "prescription.pdf"
    },
    "score": 0.13313256204128265
    }
    ]
    

然后解析结果