DynamoDB 导出为 gzipped JSON

DynamoDB export as gzipped JSON

我使用 AWS Data Pipeline 导出了一个 DynamoDB table,DataNodes > S3BackupLocation > Compression 设置为 GZIP。我希望压缩输出带有 .gz 扩展名,但我得到的是没有扩展名的未压缩输出。

Further reading 显示压缩字段 "is only supported for use with Amazon Redshift and when you use S3DataNode with CopyActivity."

如何将我的 DynamoDB table 的 gzip 备份放入 S3?我是否必须求助于下载所有文件、gzip 压缩并上传它们?有没有办法让管道与 CopyActivity 一起工作?有没有更好的方法?

我一直在尝试使用 Hive 进行导出,但我还没有找到在输出中正确设置格式的方法。它需要匹配以下格式,以便 EMR 作业可以将其与来自其他来源的数据一起读取。

{"col1":{"n":"596487.0550532"},"col2":{"s":"xxxx-xxxx-xxxx"},"col3":{"s":"xxxx-xxxx-xxxx"}}
{"col1":{"n":"234573.7390354"},"col2":{"s":"xxxx-xxxx-xxxx"},"col3":{"s":"xxxx-xxxxx-xx"}}
{"col2":{"s":"xxxx-xxxx-xxxx"},"col1":{"n":"6765424.7390354"},"col3":{"s":"xxxx-xxxxx-xx"}}

我也一直在寻找如何做到这一点。这是一个如此基本的请求,令我惊讶的是它不是基本数据管道工作流程的一部分。

经过几天的调查和实验,我发现了两种机制:

1) 使用 ShellCommandActivity 启动几个 aws cli 命令(s3 cp、gzip)从 s3 下载,本地 gzip,然后重新上传到 s3。以下是相关部分:

{
    "name": "CliActivity",
    "id": "CliActivity",
    "runsOn": {
        "ref": "Ec2Instance"
    },
    "type": "ShellCommandActivity",
    "command": "(sudo yum -y update aws-cli) && (#{myCopyS3ToLocal}) && (#{myGzip}) && (#{myCopyLocalToS3})"
},

"values": {
    "myCopyS3ToLocal": "aws s3 cp s3://your-bucket/your-folders/ --recursive",
    "myGzip": "for file in /tmp/random-date/*; do gzip \"$file\"; done",
    "myCopyLocalToS3": "aws s3 cp /tmp/random-date s3://your-bucket/your-folders-gz/ --recursive"
}

2) 创建一个单独的 EMR 集群,然后创建一个使用该 EMR 集群到 运行 S3DistCp (s3-dist-cp) 的数据管道。

{
    "name": "CliActivity",
    "id": "CliActivity",
    "runsOn": {
        "ref": "Ec2Instance"
    },
    "type": "ShellCommandActivity",
    "command": "(sudo yum -y update aws-cli) && (#{myAWSCLICmd})"
},

"values": {
    "myAWSCLICmd": "aws emr add-steps --cluster-id j-XXXXYYYYZZZZ --region us-east-1 --steps Name=\"S3DistCp command runner\",Jar=\"command-runner.jar\",Args=[\"s3-dist-cp\",\"--s3Endpoint=s3.amazonaws.com\",\"--src=s3://your-bucket/your-folders/\",\"--dest=s3://your-bucket/your-folders-gz/\",\"--outputCodec=gz\"]"
}

两者之间,我喜欢第二个,因为s3distcp可以自动删除源s3文件。但是,它需要一个单独的 EMR 集群才能 运行(成本更高)。或者您可以在 #1 中添加额外的步骤来进行删除。

另外,如果你想参数化,你可能需要直接内联这些值,这样你就可以利用像#{format(@scheduledStartTime,'YYYY-MM-dd_hh.mm')}这样的东西。