PostgreSQL到数据仓库:近实时ETL /数据提取的最佳方法

时间:2010-03-25 22:45:21

标签: postgresql data-warehouse etl near-real-time data-extraction

背景

我有一个针对OLTP进行了大量优化的PostgreSQL(v8.3)数据库。

我需要半实时地从中提取数据(有些人必须询问半实时意味着什么,答案和我合理的一样频繁,但我会务实,作为基准假设我们希望每15分钟一次,并将其提供给数据仓库。

多少数据?在高峰时段,我们正在谈论每分钟大约80-100k行击中OLTP侧,非高峰时这将大幅下降到15-20k。最频繁更新的行每个约64个字节,但有各种表等,因此数据非常多样化,每行最多可达4000个字节。 OLTP处于活动状态24x5.5。

最佳解决方案?

从我可以拼凑起来的最实用的解决方案如下:

  • 创建TRIGGER以将所有DML活动写入旋转的CSV日志文件
  • 执行所需的任何转换
  • 使用原生DW数据泵工具将转换后的CSV高效泵入DW

为何选择此方法?

  • TRIGGERS允许选择性表格成为目标而不是系统范围+输出是可配置的(即成为CSV),并且相对容易编写和部署。 SLONY使用类似的方法,并且开销是可以接受的
  • CSV简单快速转换
  • 易于将CSV泵入DW

考虑的替代方案......

  • 使用本机日志记录(http://www.postgresql.org/docs/8.3/static/runtime-config-logging.html)。问题是它相对于我需要的看起来非常冗长,并且解析和转换有点棘手。然而,它可能更快,因为我认为与TRIGGER相比,开销更少。当然它会使管理员更容易,因为它是系统范围的,但同样,我不需要一些表(一些用于持久存储我不想记录的JMS消息)
  • 直接通过ETL工具(如Talend)查询数据并将其泵入DW ...问题是OLTP架构需要调整以支持这一点并且有很多负面的副作用
  • 使用经过调整/攻击的SLONY - SLONY可以很好地记录并将更改迁移到从属设备,因此概念框架就在那里,但建议的解决方案似乎更简单,更清晰
  • 使用WAL

以前有人这样做过吗?想分享你的想法吗?

3 个答案:

答案 0 :(得分:11)

假设您的感兴趣的表具有(或可以使用增强的)唯一的,索引的顺序键,那么只需将SELECT ... FROM table ... WHERE key > :last_max_key与输出一起发布到文件中,您将获得更好的价值,其中{ {1}}是上次提取的最后一个键值(如果是第一次提取,则为0)。这种增量,解耦方法避免在插入数据路径中引入触发延迟(无论如何)自定义触发器或修改后的Slony),并且根据您的设置可以更好地扩展CPU数量等(但是,如果您还必须跟踪last_max_key s ,并且添加了顺序键根据您的要求,您的UPDATE语句应该UPDATESET的关键列,以便它获得新值并被下次提取选中。您将无法跟踪NULL s 没有触发器。)这是您提到Talend时的想法吗?

除非您无法实施上述解决方案,否则我不会使用日志工具;日志记录很可能涉及锁定开销以确保日志行按顺序写入,并且当多个后端写入日志时不会相互重叠/覆盖(检查Postgres源。)锁定开销可能不是灾难性的,但如果可以使用增量DELETE替代方案,则可以不使用它。此外,语句记录会淹没任何有用的WARNING或ERROR消息,而解析本身不会是瞬时的

除非您愿意解析WAL(包括事务状态跟踪,并且每次升级Postgres时都准备重写代码),否则我不一定会使用WAL - 也就是说,除非您拥有额外的硬件可用,在这种情况下你可以将WALs发送到另一台机器进行提取(在第二台机器上你可以无耻地使用触发器 - 甚至是语句记录 - 因为无论发生什么,都不会影响主机上的SELECT / INSERT / UPDATE性能。)注意性能方面(在主机上),除非您可以将日志写入在运行增量DELETE时,从运送WAL到另一台机器,你可以获得相当大的性能(主要是在文件系统高速缓存方面)。

答案 1 :(得分:2)

如果你能想到一个只包含id和'checksum'的'校验和表',你不仅可以快速选择新记录,还可以快速选择已更改和删除的记录。

校验和可能是你喜欢的crc32校验和函数。

答案 2 :(得分:0)

PostgreSQL中新的ON CONFLICT子句改变了我做许多更新的方式。我将新数据(基于row_update_timestamp)拉入临时表,然后在一个SQL语句中使用ON CONFLICT UPDATE INSERT到目标表中。如果你的目标表是分区的,那么你需要跳过几个环(即直接点击分区表)。 ETL可以在加载Temp表(最有可能)或ON CONFLICT SQL(如果是无关紧要的)时发生。与其他“UPSERT”系统(更新,插入零行等)相比,这显示出巨大的速度提升。在我们特定的DW环境中,我们不需要/想要容纳DELETE。查看ON CONFLICT文档 - 它为甲骨文的MERGE提供了运行资金!