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

bel*_*oir 14 postgresql etl near-real-time data-warehouse data-extraction

背景:

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

我需要半实时地从中提取数据(有些人必然要问半实时意味着什么,答案是我合理的频率但是我会务实,因为基准可以说我们希望每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

有没有人这样做过?想分享你的想法?

vla*_*adr 11

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

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

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

  • 主键阈值思想的一个潜在问题是postgres序列是非事务性的.也就是说,插入较低PK的事务可以在*插入较高PK的事务之后提交.因此,您的ETL策略可能会"错过"插入(假设"读取已提交"隔离级别).这很少会出现问题(除非您有大量的插入量或长事务),但如果您无法容忍ETL期间的数据丢失,则需要考虑这一问题. (2认同)