我怎样才能使我的SSIS进程消耗更多的资源,运行速度更快?

我在SSIS中有一个每天的ETL过程来build立我的仓库,所以我们可以提供日常的报告。

我有两台服务器 – 一个用于SSIS,另一个用于SQL Server数据库。 SSIS服务器(SSIS-Server01)是一个8CPU,32GB的RAM盒子。 SQL Server数据库(DB-Server)是另外一个8CPU,32GB的RAM盒子。 两者都是VMWare虚拟机。

SSIS以其简单的forms从DB-Server上的单个表中读取了1700万行(大约9GB),将其转换为408M行,执行一些查找和大量计算,然后将其聚集回到大约8M行每次写入到同一个DB-Server上的一个全新的表(这个表将被移到一个分区中以提供日常的报告)。

我有一个循环,每次处理18个月的数据 – 总共10年的数据。 根据我对SSIS服务器上RAM使用情况的观察,我select了18个月 – 在18个月时,它消耗了27GB的RAM。 任何更高的,SSIS开始缓冲到磁盘和性能提高。

这是我的数据streamhttp://img207.imageshack.us/img207/4105/dataflow.jpg

在这里输入图像说明

我正在使用微软的平衡数据分配器发送数据向下8个并行path,以最大限度地利用资源。 我在开始工作之前先做一个工会。

这是来自SSIS服务器的任务pipe理器图

替代文字

下面是另外一张显示8个CPU的图表

替代文字

从这些图像中可以看到,随着越来越多的行被读取和处理,内存使用量缓慢增加到大约27G。 但CPU使用率在40%左右。

第二张图显示我们只使用了4个(有时是5个)8个CPU。

我正在尝试使进程运行得更快(它只使用了可用CPU的40%)。

我怎样才能使这个过程更高效地运行(最less的时间,最多的资源)?

bilinkc提出了很好的build议后,不知道瓶颈在哪里,我会尝试另外几件事情。

正如您已经注意到的那样,您应该在并行性上工作,而不是在同一个数据stream中处理更多的数据(几个月)。 您已经完成了并行转换,但源和目标(以及聚合)并不是并行运行的! 因此,请仔细阅读并记住,为了充分利用您的CPU能力,您还应该让它们并行运行。 不要忘记,你是内存绑定的(不能在一个批量中累计无数个月),所以要走的路(“向外扩展”)是获取大块数据,处理它并将其放入目标数据库尽快 。 这需要消除常见的组件(一个源,一个union all),因为每个数据块都受限于这些常见组件的速度。

源相关优化:

  • 在同一个数据stream中尝试多个源(和目标),而不是平衡数据分发器 – 在date列上使用聚簇索引,以便数据库服务器能够快速检索基于date范围的数据; 如果您在不同于数据库的服务器上运行软件包,则会增加networking利用率

转化相关优化:

  • 在聚合之前你真的需要做所有的联合? 如果不是,请查看有关多个目的地的目的地相关优化
  • 为Aggregate组件设置Keys,KeyScale和AutoExtendFactor以避免重新散列 – 如果这些属性设置不正确,那么在程序包执行期间将会看到警告; 注意,预测最佳值对于固定月数的批次比对无限数量的批次更容易(如在你的情况18和提高)
  • 考虑在SQL Server中进行聚合和(取消)转移,而不是在SSIS包中执行 – SQL Server在这些任务中优于Integration Services; 当然,转换逻辑可能是这样的,在封装中执行一些转换之前禁止聚合
  • 如果您可以在数据库中汇总(并且支持/不支持)(例如)每月数据,请尝试在源查询或SQL中使用目标数据库执行此操作; 根据您的环境,写入到目标数据库中的单独表,build立索引,SE​​LECT INTO与SQL汇总可能比在包中执行更快; 请注意,将这些活动并行处理会给存储带来很大的压力
  • 你最后有一个组播; 我不知道有多less行到达那里,但考虑以下内容:写入到目的地(在屏幕截图上),然后填充logging到SQL查询中的左侧目的地(以消除第二个聚合和释放资源 – SQL Server可能会做得更快)

目的地相关优化:

  • 如果可能,使用SQL Server目标 (包必须与数据库运行在同一台服务器上,而目标数据库必须是SQL Server); 请注意,它需要精确的列数据types匹配(pipe道 – >表列)
  • 考虑在目标(数据仓库)数据库上将恢复模式设置为简单
  • 平行目的地 – 而不是工会所有+总目标+目的地使用单独的总量和单独的目的地(到同一张表); 在这里你应该考虑分区你的目标表,并把分区放在不同的文件组上; 如果您逐月处理数据,则按月份分区并使用分区切换

似乎我一直不清楚哪个方向与并行。 你可以试试:

  • 将多个源放在单个数据stream中需要您复制和粘贴每个源的转换逻辑和目标
  • 并行运行多个数据stream,每个数据stream只处理一个月
  • 并行运行多个程序包,每个程序包有一个仅处理一个月的数据stream; 和一个主包来控制每个(月)包的执行 – 这是首选的方式,因为一旦你投入生产,你可能只运行包一个月
  • 或者与之前一样,但使用Balanced Data Distributor和Union All和Aggregate

在做其他事情之前,您可能需要做一个快速testing:获取原始软件包,将其更改为使用1个月,并进行另一个月的精确复制,并行运行这些软件包。 将其与原始包裹处理2个月进行比较。 对于2个独立的6个月套餐和单个12个月套餐,请按照同样的方法进行。 它应该以完整的CPU使用率运行你的服务器。

尽量不要超载,因为你将有多个写到目的地,所以你不想开始18个并行的月包,而是3或4开始。

最后,我坚信记忆和destionation I / O压力是要消除的。

请告知我们您的进展。

使用Process Explorer来显示更多的资源使用情况(内存和IO)。 请注意,Disk-IO图表可能有点让人误解,因为图表中的峰值通常是由于硬盘驱动器cachingfunction所致,所以当磁盘IO成为瓶颈时,它并不总是立即显示在graphics中。

在某些情况下,您可以从安装ram-drive并将临时目录放在那里获益。 我已经成功地使用这个来减less我们的构build机器用来完成每晚构build和运行testing的时间。 我不确定SSIS是否会受益。

(重新发布我的初步答复,没有考虑BDD)

在一天结束时,所有的处理都受到四个因素之一的约束

  • 记忆
  • 中央处理器
  • 磁盘
  • networking

第一步是确定限制因素是什么,然后确定你是否可以影响它(获取更多或减less使用)

组件select

当你的服务器超过18个月时,内存耗尽的原因与为何需要处理这么长的时间有关。 透视和聚合转换是asynchronous组件。 来自源组件的每一行都有N个字节的内存分配给它。 同一桶数据访问所有的转换,已经应用了它们的操作,并在目的地清空。 那个内存桶一遍又一遍的重复使用。

当一个asynchronous组件进入竞技场时,pipe道被拆分。 现在运送那一行数据的桶必须被清空到一个新的桶中来完成pipe道。 执行树之间的数据复制在执行时间和内存方面是一个代价高昂的操作(可以使其翻倍)。 这也减less了引擎在等待asynchronous操作完成时平行化一些执行机会的机会。 从转换的性质来看,操作进一步减慢。 Aggregate是一个完全阻塞的组件,所以所有的数据都必须到达并在转换之前进行处理,将一行发布到下游转换。

如果可能的话,你可以将枢轴和/或集合体推到服务器上吗? 这应该减less在数据stream中花费的时间以及消耗的资源。

您可以尝试增加引擎可以select的并行操作的数量。 杰米的文章 , SQL CAT的文章

如果您确实想知道在数据stream中花费的时间,请loggingOnPipelineRowsSent以执行。 然后你可以使用这个查询把它拆开(用sysssislog代替sysdtslog90)

networking传输

根据你的图表,CPU和内存都不会出现在任何一个盒子上。 我相信你已经指出源服务器和目标服务器在一个盒子里,但是SSIS包装是在另一个盒子上托pipe和处理的。 您将花费不小的成本通过networking传输数据,然后再返回。 是否有可能在源服务器上处理数据? 你需要为这个盒子分配更多的资源,而我越过我的手指,这是一个很大的虚拟机,这不是一个问题。

如果这不是一个选项,请尝试将连接pipe理器的“ 数据包大小”属性设置为32767,并与networking运营商讨论巨型帧是否适合您。 这两个提示都在调整您的networking部分。

我吮吸磁盘计数器,但你应该能够看到,等待types是否与磁盘有关。