4

我正在关注Rainer Stropek在 1. 创建自定义 SSIS 数据流项和 2. 从 Azure 表存储中提取数据的这篇出色的帖子。 http://www.software-architects.com/devblog/2010/11/12/Custom-SSIS-Data-Source-For-Loading-Azure-Tables-Into-SQL-Server

我将粘贴任何试图回答我的问题的人都会感兴趣的代码:

GenericTableContext context = new GenericTableContext(cloudStorageAccount.TableEndpoint.AbsoluteUri, cloudStorageAccount.Credentials);

public override void PrimeOutput(int outputs, int[] outputIDs, PipelineBuffer[] buffers) {
  IDTSOutput100 output = ComponentMetaData.OutputCollection[0];
  PipelineBuffer buffer = buffers[0];
  foreach(var item in this.context.CreateQuery<GenericEntity>("SomeTable") {
    buffer.AddRow();
    for (int x = 0; x < columnInformation.Count; x++) {
      var ci = (ColumnInfo) columnInformation[x];
      var value = item[ci.ColumnName].Value;
      if (value != null) {
        buffer[ci.BufferColumnIndex] = value;
      } else {
        buffer.SetNull(ci.BufferColumnIndex);
      }
    }
  }

现在的问题:

我的数据集非常大;假设有一百万条记录。我有一个最简单形式的 SSIS 包,即我的自定义数据源将数据写入平面文件目标。它没有任何转换。

当我运行我的包时,我可以看到记录以大约 10,000 条记录 (DefaultBufferMaxRows) 的形式写入 CSV 文件。

我的问题是,虽然这些记录是写出来的,但它似乎仍然留在记忆中。这最终导致我的包裹减速并停止。我服务器中的所有内存都用完了。

现在我不是 SSIS 专家,但我假设我写入 PipelineBuffer 的记录在使用后没有被释放。“缓冲区”这个词对我来说意味着它可以被“冲洗”。但我找不到任何 API 来做到这一点。

所以我想我的问题是,如何释放分配给已写入平面文件的记录的内存,以便我有足够的内存用于剩余记录?

谢谢你,南顿

4

1 回答 1

0

每个缓冲区都将刷新,更准确地说,一旦它完成了通过管道的旅程,就会被重用。因此,在这种情况下,SSIS 会为您管理内存,尽管您必须确保分配了正确的行和内存大小(您可以在日志记录中打开缓冲区调整事件以查看您的包是否发生这种情况)。通常,人们调整内存并没有意识到它是数据流中的每个组件,因此包会花费大量时间来尝试过度分配大量内存。

如果您的组件是目标,您也可能没有释放连接,您需要使用连接管理器或实现资源管理代码以在脚本组件中进行清理。

于 2015-02-01T06:35:41.120 回答