每天将大约 200 个 SQL Server 2005 源数据库(相同架构)加载到暂存区域以准备数据仓库清理、重复数据删除和转换的最佳提取策略是什么?
到目前为止,我已经设想了以下可能性:
- 事务复制:在 2005 年创建 200 个 SQL Server 2008 R2 订阅者从各自的发布者提取数据。在订阅者和影子表中的所需表上启用更改数据捕获,以便对我们的临时数据库执行增量加载。
- Rowversion:在每个所需的源表上添加一个 rowversion 列,并将其与 SSIS 进程结合使用,以将更改数据直接提取到暂存数据库。
- BCP 文件:创建一个自动化任务,每晚从所有源表中转储 BCP 文件。使用 SSIS 将这些表作为完全加载(而不是增量)的一部分加载到临时数据库中。
额外的想法:
- 我对在 200 个数据库上支持全新事务复制拓扑所需的管理和硬件开销感到紧张。
- 数据库的总组合大小约为 100GB。但其中大部分是事务日志和其他表的一部分,不会在任何事实或维度中使用。换句话说,BCP 文件不会很大,这就是为什么我正在考虑一个完整的提取策略,即使我读过的所有内容都反对它。
- 我愿意接受建议、文件等。
如果您有 200 个相同的源,那么您可以使用数据源参数化 SSIS 包并启动多个线程。这些可以通过 foreach 循环或从使用参数启动提取器的外部源在包内进行控制。
您可以考虑对相对较小的维度源进行完全加载,对事务数据进行增量加载。这将要求您具有持久的维度,但这对于 MERGE 操作或预加载区域和维度处理程序来说非常简单,如果您需要缓慢变化的维度。
您可能希望考虑为每个源提供自己的暂存区域(可能是暂存数据库中每个源的模式)。这消除了临时表上的锁定问题。在包含数据源信息的暂存表(基本上只是对应于每个源表的联合集)上构建一组视图。这些可以很容易地生成,因此您不必手动将 200 个不同的查询剪切并粘贴到联合中。暂存数据后,ETL 过程可以从视图中读取全部内容。
这允许 ETL 一次性运行,尽管您必须想出一个策略来处理来自单个系统的提取故障。为此,您可能希望研究一种能够优雅地处理迟到数据的架构,以便您可以赶上存在临时问题的单个提要。
BCP
对于 200 个简单的提取,BCP 可能是一个不错的选择。源都是相同的,因此 BCP 文件在不同源中是相同的。您可以使用 SSIS 构建负载控制器。让多个线程读取公共列表的顶部将需要您实现对列表的同步访问。SSIS 进程有一堆在序列容器中并行运行的循环,这些循环弹出下一个项目,执行它并更新相应的状态。
实现“下一个”函数使用在可序列化事务中运行的存储过程,该存储过程将“下一个”合格源从列表中弹出,并将其标记为事务中的“进行中”。这是一个“作为队列的表”问题,但您不必实现同步插入 - 可以在运行开始时将整个批次推入表中。
构建单个提取过程,以便在第一次尝试失败时再尝试一次或两次。这将减轻许多由瞬态错误引起的故障。如果任务失败两次,则使任务失败,并构建 ETL,使其能够适应单独的提取失败。
增量负载
除非您有一个非常大的维度来显示真正的性能问题,否则增量加载器可能不值得为维度表烦恼。对于事实表数据源,这可能是值得的。如果您可以使用时间戳列等向应用程序表添加行版本,则可以获取新的内容。但是,您需要在本地跟踪它以记录最后一个时间戳。如果数据上有插入或更新日期,您可以使用它来代替。
满载
什么可能出错?
启动 200 个进程以执行完整负载会在网络和可能的暂存数据库上造成负载峰值。这可能会导致各种瞬态问题,例如超时。对于小维度表,这可能不是什么大问题。然而,对于 100GB 来说,存在各种各样的问题 - WAN 饱和、锁定(尽管正确的分段架构会缓解这种情况)、资源的可用性。提取过程运行的时间越长,环境因素对过程可靠性的影响就越大。
这里有很多不可估量的东西,所以 YMMV。如果可能,我建议对较大的表进行增量加载。
您可以使用 SSIS 包,它循环通过源数据库将所需数据导出到目标数据库。通过一些工作,您可以使这个多线程并一次执行多个数据库。
IRI Workbench (Eclipse GUI) 支持批量(多表)提取、映射(转换,如果需要,带有规则)和 bcp 加载;具体来说,这里提到了它的重组向导。我不会一次从 200 个源开始,但看看前 10 个如何确定它的多脚本方法(我喜欢它的可移植性和易于修改)是否在那里工作。然后以这种方法为基础,看看它是如何进行的;IRI 工具用于批量数据移动;GUI 是为了方便指定它们在多源情况下的使用