2

我在存储在 S3 上的文件中有一组 JSON 消息(每行一条消息)。每条消息都有一个唯一的密钥作为消息的一部分。我还有一个简单的 DynamoDB 表,其中该键用作主键。该表包含相应 JSON 消息所在的 S3 文件的名称。

我的目标是从给定密钥的文件中提取 JSON 消息。当然,最坏的情况是消息是文件中的最后一行。

boto使用库从文件中提取消息的最快方法是什么?特别是,是否有可能以某种方式直接逐行读取文件?当然,我可以将整个内容读取到本地文件,boto.s3.key.get_file()然后打开文件并逐行读取并检查 id 是否匹配。但是有没有更有效的方法?

非常感谢!

4

3 回答 3

3

S3 无法做到这一点。也就是说,您还有其他一些选择:

  1. 在 DynamoDB 中存储记录的长度和位置(字节偏移)而不是行号。这将允许您使用header仅检索Range:记录。
  2. 使用缓存层来存储{ S3 object key, line number } => { position, length }元组。当您想通过 查找记录时{ S3 object key, line number },请参考缓存。如果您还没有这些数据,则必须像现在一样获取整个文件——但是在获取文件后,您可以计算其中每一行的偏移量,并节省自己的工作量。
  3. 将 JSON 记录直接存储在 DynamoDB 中。考虑到 64 KB 的项目限制,这可能可行,也可能不可行。
  4. 将每条 JSON 记录分别存储在 S3 中。然后,您可以消除 DynamoDB 键查找,并直接转到 S3 以获取给定记录。

哪个最适合您取决于您​​的应用程序架构、访问此数据的方式、并发问题(考虑到您当前的解决方案,可能并不重要)以及您对延迟和成本的敏感性。

于 2012-10-02T19:26:15.307 回答
1

您可以将内置的 readline 与流一起使用:

const readline = require('readline');
const AWS = require('aws-sdk');
const s3 = new AWS.S3();
const params = {Bucket: 'yourbucket', Key: 'somefile.txt'};
const readStream = s3.getObject(params).createReadStream();
const lineReader = readline.createInterface({
  input: readStream,
});
lineReader.on('line', (line) => console.log(line));
于 2016-08-10T15:40:01.510 回答
0

您可以使用 S3 SELECT 来完成此操作。也适用于镶木地板文件。

https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-glacier-select-sql-reference-select.html

于 2021-04-06T18:57:54.907 回答