仅将新文件从 S3 加载到 Redshift 的简单方法?
Posted
技术标签:
【中文标题】仅将新文件从 S3 加载到 Redshift 的简单方法?【英文标题】:Simple way to load new files only into Redshift from S3? 【发布时间】:2015-05-14 15:03:31 【问题描述】:Redshift COPY 命令的文档指定了两种选择要从 S3 加载的文件的方法,您可以提供一个基本路径并加载该路径下的所有文件,或者您指定一个包含要加载的特定文件的清单文件。
但是,在我们的案例中,我认为这很常见,S3 存储桶会定期接收包含更新数据的新文件。我们希望能够仅加载尚未加载的文件。
鉴于有一个表 stl_file_scan 记录了从 S3 加载的所有文件,最好以某种方式排除那些已成功加载的文件。这似乎是一个相当明显的功能,但我在文档或网上找不到有关如何执行此操作的任何内容。
甚至 AWS Data Pipeline 中的 Redshift S3 加载模板似乎也通过将所有数据(新旧数据)加载到暂存表,然后与目标表进行比较/更新来管理此场景。当我们可以从文件名中预先知道一个文件已经被加载时,这似乎是一个疯狂的开销。
我知道我们可能会将已经加载的文件移出存储桶,但是我们不能这样做,这个存储桶是另一个不属于我们自己的进程的最终存储位置。
我能想到的唯一替代方法是运行一些其他进程来跟踪已成功加载到 redshift 的文件,然后定期将其与 s3 存储桶进行比较以确定差异,然后将清单文件写入之前的某处触发复制过程。但是多么痛苦啊!我们需要一个单独的 ec2 实例来运行该进程,这将有自己的管理和运营开销。
一定有更好的办法!
【问题讨论】:
【参考方案1】:这就是我解决问题的方法,
S3 --(新创建的日志上的 Lambda 触发器)-- Lambda -- Firehose -- Redshift
它适用于任何规模。随着负载的增加、对 Lambda 的更多调用、对 firehose 的更多数据以及所有事情的自动处理。
如果文件格式有问题,您可以配置死信队列,事件将被发送到那里,您可以在修复 lambda 后重新处理。
【讨论】:
谢谢!这无疑是当今最好的方法。自从我最初提出这个问题(在 lambda 或 firehose 存在之前)以来,情况已经好很多了。【参考方案2】:这里我想提一些步骤,包括如何在 redshift 中加载数据的过程。
-
将本地 RDBMS 数据导出到平面文件(确保删除无效的
字符,在导出期间应用转义序列)。
将文件拆分为每个 10-15 MB 以获得最佳性能
上传和最终数据加载。
将文件压缩为
*.gz
格式,这样您就不会得到 1000 美元
惊喜账单:) .. 在我的情况下,文本文件被压缩 10-20
次。
列出清单文件中的所有文件名,以便在您发出 COPY 命令时
将 Redshift 视为一个负载单位。
将清单文件上传到 Amazon S3 存储桶。
将本地 *.gz
文件上传到 Amazon S3 存储桶。
使用不同的选项发出 Redshift COPY 命令。
计划从 AWS 上的本地和 S3 暂存区域归档文件。
捕获错误,设置失败时重新启动的能力
操作简单,您可以点击此链接。
【讨论】:
【参考方案3】:一般来说,将加载的文件与现有的 S3 文件进行比较是一种不好但可能的做法。常见的“工业”实践是在数据生产者和实际加载数据的数据消费者之间使用消息队列。看看 RabbitMQ 与 Amazon SQS 等。
【讨论】:
我很好奇为什么你会认为这是一种不好的做法。当然,如果您有大量文件以高频率到达,那么比较方法可能不可行。但是,很少有少量文件应该可以正常工作。维护另外 2 个软件/基础设施(消息队列和消费者/协调器),更不用说要求生产者将消息提交到队列,当您的流量很低时,这似乎是一个非常大的开销。以上是关于仅将新文件从 S3 加载到 Redshift 的简单方法?的主要内容,如果未能解决你的问题,请参考以下文章
无法将制表符分隔的 Txt 文件从 S3 加载到 Redshift
用于将数据从AWS S3加载到Redshift的Python脚本
在不使用 S3 存储桶的情况下将数据从远程服务器的 .gz 文件加载到 redshift 的 postgresql 实例?