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

mcdcgff0  于 2023-05-06  发布在  PostgreSQL
关注(0)|答案(4)|浏览(255)

背景:

我有一个PostgreSQL(v8.3)数据库,它针对OLTP进行了大量优化。
我需要在半实时的基础上从中提取数据(有人一定会问半实时意味着什么,答案是尽可能频繁,但我会很务实,作为一个基准,让我们说我们希望每15分钟)并将其馈送到数据仓库中。
有多少数据?在高峰期,我们谈论的是每分钟大约80- 100 k行访问OLTP端,在非高峰期,这将显著下降到15- 20 k。最频繁更新的行是每个~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)。这样做的问题是,相对于我所需要的,它看起来非常冗长,并且解析和转换起来有点棘手。然而,它可以更快,因为我认为有更少的开销相比,触发器。当然,这将使管理更容易,因为它是系统范围内的,但同样,我不需要一些表(一些用于持久存储JMS消息,我不想记录)
  • 直接通过ETL工具(如Talend)查询数据并将其泵入DW……问题是需要调整OLTP模式以支持此功能,这会产生许多负面影响
  • 使用经过调整/修改的SLONY - SLONY可以很好地记录和迁移更改到从属设备,因此概念框架已经存在,但建议的解决方案似乎更容易和更清晰
  • 使用WAL

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

pn9klfpd

pn9klfpd1#

假设你感兴趣的表有(或可以用)一个唯一的、索引的、顺序的键,那么你将通过简单地发出SELECT ... FROM table ... WHERE key > :last_max_key并输出到一个文件来获得更好的价值,其中last_max_key是最后一次提取的最后一个键值(如果是第一次提取,则为0)。这种增量、解耦的方法避免了在插入数据路径中引入触发器延迟(无论是自定义触发器还是修改的Slony),并且根据你的设置,可以随着CPU数量等的增加而更好地扩展。(但是,如果您还必须跟踪UPDATE s,并且顺序键是由您添加的,那么您的UPDATE语句应该将键列SET转换为NULL,以便它获得新值并由下一次提取选择。如果没有触发器,你将无法跟踪DELETE s。)这是你提到Talend时的想法吗?
我不会使用日志工具,除非你不能实现上面的解决方案;日志记录很可能涉及锁定开销,以确保日志行按顺序写入,并且在多个后端写入日志时不会相互重叠/覆盖(检查Postgres源代码)。锁定开销可能不是灾难性的,但如果您可以使用增量SELECT替代方案,则可以不使用它。此外,语句日志记录会淹没任何有用的WARNING或ERROR消息,并且解析本身不会是即时的
除非您愿意解析WAL(包括事务状态跟踪,以及每次升级Postgres时准备重写代码)我也不一定会使用WAL--也就是说,除非你有额外的硬件可用,在这种情况下,您可以将WAL发送到另一台计算机进行提取(在第二台机器上,您可以无耻地使用触发器-甚至是语句日志记录--因为无论发生什么都不会影响主机器上的INSERT/UPDATE/DELETE性能。)请注意,从性能方面(在主机器上),除非您可以将日志写入SAN,否则将WAL运送到不同的机器与运行增量SELECT会对性能造成相当的影响(主要是在文件系统缓存抖动方面)。

w51jfk4q

w51jfk4q2#

如果你能想到一个只包含id和校验和的校验和表,你不仅可以快速选择新的记录,还可以快速选择更改和删除的记录。
校验和可以是你喜欢的CRC32校验和函数。

iyfamqjs

iyfamqjs3#

PostgreSQL中新的ON CONFLICT子句改变了我做很多更新的方式。我将新数据(基于row_update_timestamp)拉入临时表,然后在一个SQL语句中使用ON CONFLICT UPDATE将INSERT插入目标表。如果你的目标表是分区的,那么你需要跳过几个环(即直接命中分区表)。ETL可以在您加载Temp表时发生(最有可能),也可以在ON CONFLICT SQL中发生(如果不重要)。与其他“UPSERT”系统(更新,如果零行插入等)相比,这显示了巨大的速度改进。在我们特定的DW环境中,我们不需要/不想容纳DELETE。看看关于冲突的文档--它给了甲骨文的合并一个机会!

osh3o9ms

osh3o9ms4#

我对2023年这个主题的看法...
选项1(批处理方法):

  • 通过使用整数或时间戳来保持每次迭代中每个表传输的最大行,从而使用增量提取进行分段。我们可以使用always ONCONFLICT语句来避免由于意外的迭代崩溃而导致的任何意外的键冲突。这种方式不能跟踪行删除,但我们可以使用删除标志作为一列过滤到数据仓库。
  • DataWarehouse使用Calculated Tables通过创建存储过程来进行复杂的连接/计算,并将结果插入到新的预先计算的表中。
  • 选项2(管道方法)
  • 使用逻辑复制进行转移以进行实时数据提取。逻辑复制可以捕获更改并将其复制到发生的相同序列中,因此目标数据库将始终保持一致。这种方式也可以跟踪删除。
  • DataWarehouse使用增量物化视图进行实时预计算的轻量级连接/计算,计算表使用存储过程进行更繁重的连接/计算,因为IVM目前不支持输出连接和所有类型的聚合。

相关问题