web-dev-qa-db-ja.com

SSISプロセスがより多くのリソースを消費し、より高速に実行できるようにするにはどうすればよいですか?

SSISには毎日ETLプロセスがあり、倉庫を構築して、毎日のレポートを提供できるようにしています。

2つのサーバーがあります。1つはSSIS用で、もう1つはSQLServerデータベース用です。 SSISサーバー(SSIS-Server01)は8CPU、32GB RAMボックスです。SQLServerデータベース(DB-Server)はanother8CPU、32GB RAMボックスです。どちらもVMWare仮想マシンです。

過度に単純化された形式では、SSISはDBサーバー上の単一のテーブルから1700万行(約9GB)を読み取り、それらを4億800万行にアンピボットし、数回のルックアップと大量の計算を実行してから、約800万行に集約します。毎回同じDBサーバー上の新しいテーブルに書き込まれます(このテーブルは、日ごとのレポートを提供するためにパーティションに移動されます)。

一度に18か月分のデータを処理するループがあります。これは合計10年分のデータです。 RAM SSIS-Serverでの使用量-18か月で、27GBのRAMを消費します。それ以上になると、SSISはディスクへのバッファリングを開始し、パフォーマンスが低下します。

これが私のデータフローです http://img207.imageshack.us/img207/4105/dataflow.jpg

enter image description here

MicrosoftのBalanced Data Distributor を使用して、8つの並列パスにデータを送信し、リソースの使用量を最大化します。アグリゲーションの作業を開始する前に、ユニオンを実行します。

これがSSISサーバーからのタスクマネージャーのグラフです

alt text

これは、8つの個別のCPUを示す別のグラフです。

alt text

これらの画像からわかるように、読み取られて処理される行が増えるにつれて、メモリ使用量はゆっくりと約27Gに増加します。ただし、CPU使用率は約40%で一定です。

2番目のグラフは、8個のうち4個(場合によっては5個)のCPUのみを使用していることを示しています。

プロセスをより高速に実行しようとしています(使用可能なCPUの40%しか使用していません)。

このプロセスをより効率的に実行するにはどうすればよいですか(最短時間、ほとんどのリソース)?

2
Raj More

Bilinkcによる良い提案の後、ボトルネックがどこにあるかを知らずに、私は別のいくつかのことを試みます。

すでに述べたように、同じデータフローでより多くのデータ(月)を処理するのではなく、並列処理に取り組む必要があります。変換はすでに並行して実行されていますが、ソースと宛先(および集約)は並行して実行されていません。したがって、最後まで読んで、CPUパワーを利用するには、それらも並行して実行する必要があることに注意してください。そして、あなたはメモリバウンド(1つのバッチで無限の月数を集約できない)であることを忘れないでください(「スケールアウト」)は、データのチャンクを取得することです、それを処理し、できるだけ早く宛先データベースに配置します。データの各チャンクはそれらの共通コンポーネントの速度に制限されているため、これには共通コンポーネント(1つのソース、1つのユニオンAll)を削除する必要があります。

ソース関連の最適化:

  • balanced Data Distributorの代わりに同じデータフローで複数のソース(および宛先)を試してください-データベースサーバーが日付ベースの範囲のデータをすばやく取得できるように、日付列にクラスター化インデックスを使用します。データベースが存在するサーバーとは異なるサーバーでパッケージを実行すると、ネットワークの使用率が向上します

最適化に関連する変換:

  • Aggregateの前にUnionAllを実行する必要が本当にありますか?そうでない場合は、複数の宛先に関する宛先関連の最適化を確認してください
  • 再ハッシュを回避するために、集約コンポーネントの Keys、KeyScale、およびAutoExtendFactor を設定します-これらのプロパティが正しく設定されていない場合、パッケージの実行中に警告が表示されます。最適値の予測は、無限の数よりも固定の月数のバッチの方が簡単であることに注意してください(ケース18やレイズのように)
  • SSISパッケージで行う代わりに、SQL Serverでの集約と(非)ピボットを検討してください。SQLServerは、これらのタスクでIntegrationServicesよりも優れています。もちろん、変換ロジックは、パッケージでいくつかの変換を実行する前に集約を禁止するようなものである可能性があります
  • データベース内の月次データを集約(およびピボット/アンピボット)できる場合は、SQLを使用してソースクエリまたは宛先データベースで実行してみてください。環境によっては、宛先データベースの個別のテーブルへの書き込み、インデックスの作成、SQLを使用したSELECT INTOの方が、パッケージで行うよりも高速な場合があります。このようなアクティビティを並列化すると、ストレージに大きなプレッシャーがかかることに注意してください
  • 最後にマルチキャストがあります。そこに到達する行数はわかりませんが、次のことを検討してください:右側の宛先に書き込み(スクリーンショット)、SQLクエリで左側の宛先にレコードを入力します(2番目の集計を排除してリソースを解放するため-SQL Serverおそらくはるかに速くなります)

宛先関連の最適化:

  • 使用 SQL Server宛先 可能であれば(パッケージはデータベースと同じサーバーで実行する必要があり、宛先データベースはSQL Serverである必要があります);正確な列のデータ型が一致する必要があることに注意してください(パイプライン->テーブル列)
  • 宛先(データウェアハウス)データベースで リカバリモデル をシンプルに設定することを検討してください
  • 宛先を並列化する-すべての+集計+宛先を結合する代わりに、(同じテーブルに対して)個別の集計と個別の宛先を使用します。ここでは、 partitioning 宛先テーブルとパーティションを別々のファイルグループに配置することを検討する必要があります。月ごとにデータを処理する場合は、月ごとにパーティションを作成し、 パーティション切り替え を使用します。

並列処理をどのように進めるかについて、私は不明確なままだったようです。あなたが試すことができます:

  • 複数のソースを単一のデータフローに配置するには、各ソースの変換ロジックと宛先をコピーして貼り付ける必要があります
  • 複数のデータフローを並行して実行し、各データフローは1か月のみを処理します
  • 複数のパッケージを並行して実行し、各パッケージには1か月のみを処理する1つのデータフローがあります。各(月)パッケージの実行を制御する1つのマスターパッケージ-これは、本番環境に入るとおそらく1か月間だけパッケージを実行するため、推奨される方法です。
  • または以前と同じですが、Balanced DataDistributorとUnionAll andAggregateを使用します

他のことをする前に、簡単なテストを行うことをお勧めします。元のパッケージを取得し、1か月を使用するように変更し、別の月を処理する正確なコピーを作成して、それらのパッケージを並行して実行します。 2ヶ月の元のパッケージ処理と比較してください。一度に2つの別々の6か月パッケージと1つの12か月パッケージについても同じことを行います。完全なCPU使用率でサーバーを実行する必要があります。

宛先への書き込みが複数あるため、過度に並列化しないようにしてください。したがって、18の並列月次パッケージを開始するのではなく、3つまたは4つの開始パッケージを開始します。

そして最後に、私は記憶と破壊のI/O圧力が排除されるべきものであると強く信じています。

進捗状況をお知らせください。

2
Filip Popović

Process Explorer を使用して、リソース使用量(メモリとIO)をさらに明らかにします。 Disk-IOグラフは、グラフのピークがハードドライブのキャッシュ機能に起因することが多いため、少し誤解を招く可能性があることに注意してください。したがって、disk IOがボトルネックである場合、常に明らかになるとは限りません。グラフにすぐに表示されます。

場合によっては、RAMドライブをインストールし、そこに一時ディレクトリを配置することでメリットが得られます。 this one を使用して、ビルドマシンが毎晩完全なビルドとテストを実行するために使用する時間を短縮しました。ただし、SSISが役立つかどうかはわかりません。

1
Louis Somers

(私の最初の応答を再投稿し、BDDを考慮していません)

結局のところ、すべての処理は4つの要因のいずれかに拘束されます

  • 記憶
  • CPU
  • ディスク
  • 通信網

最初のステップは、制限要因が何であるかを特定し、それに影響を与えることができるかどうかを判断することです(より多くを取得するか、使用量を減らす)

コンポーネントの選択

18か月以上実行するとサーバーのメモリが不足する理由は、サーバーの処理に非常に時間がかかる理由に関連しています。 ピボット変換と集約変換 は非同期コンポーネントです。ソースコンポーネントからのすべての行には、Nバイトのメモリが割り当てられています。その同じデータバケットがすべての変換にアクセスし、それらの操作が適用され、宛先で空になります。そのメモリバケットは何度も再利用されます。

非同期コンポーネントがアリーナに入ると、パイプラインが分割されます。そのデータ行を転送していたバケットは、パイプラインを完了するために新しいバケットに空にする必要があります。実行ツリー間でのデータのコピーは、実行時間とメモリの点でコストのかかる操作です(2倍になる可能性があります)。これにより、非同期操作の完了を待機しているときに、エンジンが実行機会の一部を並列化する機会も減少します。変換の性質から、操作の速度がさらに低下します。 Aggregateは完全にブロックするコンポーネントであるため、allデータが到着して処理されてからでないと、変換によって1行がダウンストリーム変換に解放されません。

可能であれば、ピボットやアグリゲートをサーバーにプッシュできますか?これにより、データフローに費やされる時間と消費されるリソースが削減されます。

エンジンが選択できる並列操作の量を増やしてみることができます。 ジェイミーの記事SQL CATの記事

データフローのどこで時間を費やしているかを本当に知りたい場合は、OnPipelineRowsSentをログに記録して実行してください。次に、これを使用して query をリッピングできます(sysdtslog90をsysssislogに置き換えた後)

ネットワーク転送

グラフに基づくと、CPUまたはメモリがどちらのボックスにも課税されていないようです。ソースサーバーと宛先サーバーが1つのボックスにあることを示したと思いますが、SSISパッケージは別のボックスでホストおよび処理されます。そのデータをネットワーク経由で転送して再度戻すために、重要ではないコストを支払っています。ソースサーバーでデータを処理することは可能ですか?そのボックスにより多くのリソースを割り当てる必要があり、私は指を交差させています。これは非常に強力ですVM、それは問題ではありません。

それが不可能な場合は、接続マネージャーの パケットサイズ プロパティを32767に設定し、ジャンボフレームが適切かどうかについてネットワーク運用担当者に相談してください。これらのヒントは両方とも、[ネットワークの調整]セクションにあります。

私はディスクカウンターを吸いますが、待機タイプがディスクに関連しているかどうかを確認できるはずです。

1
billinkc