【问题标题】:Efficient ETL Upsert in RedshiftRedshift 中的高效 ETL Upsert
【发布时间】:2018-02-09 23:21:58
【问题描述】:

我在将可更新表从 ​​OLTP 环境迁移到 Redshift 时遇到性能问题。我们的基本工作流程是典型的 OLTP->S3->Redshift 数据流。假设我想对这样的表进行 ETL 处理

create table source_data (
id int primary key,
status varchar,
value decimal(10,4),
dateLastTouched datetime,
dateCreated datetime,
index datelasttouched_index (dateLastTouched));

到 Redshift 中的类似表。为了准备 ETL,我创建了排序键 dateLastTouched 和 dist 键 id。我们对 dateLastTouched 的任何记录进行 ETL 处理,该记录位于上一个作业的最大 dateLastTouched ETLd 之后。

此设置非常适用于没有更新旧记录的表(例如,去年的记录更改了其状态),但是当您添加该功能时,无论如何我都无法有效地看到 ETL。我们目前的做法是:

  1. 使用 dateLastTouched 将所有新的或更新的记录发送到 S3。
  2. 将 S3 中的数据复制到临时表中。
  3. 从目标表中删除与新数据具有相同主键的所有记录。
  4. 插入暂存表中的所有记录。

鉴于我们使用 dateLastTouched 作为排序键的设置,第 3 步非常慢。通常需要 1-2 分钟,很明显随着时间的推移需要更长的时间。我们不能将排序键更改为主键,因为我们需要 dateLastTouched 来报告在表上运行相当频繁的查询。 我们考虑过的一些想法:

  1. id 和 dateLastTouched 的交错排序键。我们在另一张桌子上尝试了这个,性能提升并不显着。真空重新索引时间也很糟糕。
  2. 不要删除,只需插入并让定期作业将“每个 id 的最新记录”具体化到另一个表。这并不理想,因为它实际上将大表占用的空间翻了一番,而且更新并不频繁。

对于从 S3 到 Redshift 的高效 upsert,是否有更好的范例?还是我只需要吃 ETL/物化视图的成本?

【问题讨论】:

  • "..第 3 步非常慢。通常需要 1-2 分钟.." - 这实际上听起来并不特别慢!您预计这一步需要多长时间?

标签: database amazon-web-services amazon-redshift etl upsert


【解决方案1】:

另一种选择是使用 2 个版本的表格,一个按 id 排序用于 ETL,另一个按 dateLastTouched 排序用于报告。当 ETL 过程在第一个上完成时,您只需重新创建第二个(不使用 order by,而只是使用 truncate t2insert into t2 select * from t1vacuum reindex t2

此外,根据集群的表大小和配置,在不考虑 upsert 的情况下重新加载表的整个主体实际上可能会更快

【讨论】:

  • 感谢您的建议!我可以看到的一个问题是将数据复制到第二个表中所需的时间。我之前在这张表上做过深拷贝,大概用了45分钟。作为参考,该表有大约 5 亿条记录,磁盘上大约有 19GB。也许我可以将表的“有用的报告”子集加载到第二个,。然后再次需要使用 lastTouchedTime... 我不确定您的第二个建议是什么,但是重新加载整个表是不可能的,因为我们需要读取 19+GB 的 S3 文件。
  • @BatMasterson 你到底是怎么做深拷贝的,所以它运行了 45 分钟?你的集群的配置是什么?另外,如果在这么大的桌子上第 3 步需要 1-2 分钟,我认为你完全没问题,那应该是负担得起的
  • 我正在做通常的深拷贝过程。创建新表,然后插入新表 select * from old table。相当简单,但使用更大的数据集需要一段时间。我有一个 600GB 的表,花了 6 个小时!我的集群是单个 ds2.xlarge 节点,但我正在考虑在我们可以安排停机时间时调整大小。步骤 3 需要一分钟的事实还不是问题,但我希望该时间会随着表格的大小而扩展,表格的大小会继续增长。例如,当执行需要 7 分钟时,每 5 分钟运行一次 ETL 是不切实际的。
  • 您的实体的创建和更新时间是否存在最大差异?如果有一段时间之后更改极不可能(例如,90% 的实体在创建后的一个月内更新,99% 的实体在 6 个月内更新),您可以经常更新表的最后一部分,然后运行整个 -表更新频率较低以捕获其余的 10% 或 1%。您会错过稍后更新的几行的一些更新,但如果您跳过旧块(因为表按更新时间排序),您将节省大量资源。这对你有什么作用?
  • 此外,如果您有这么大的表并且希望每 5 分钟执行一次 ETL,那么至少移动到两个节点设置以并行化可能是有意义的
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-12-22
  • 2017-11-05
  • 2015-08-18
  • 1970-01-01
  • 2021-07-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多