不安定な回線を介してSSISパッケージで約10億行を転送しようとしています。このように、それは途中で失敗し続けます。再起動可能にする方法が欲しいのですが。ソースと宛先の間にルックアップ変換を入れようとしましたが、それでは遅すぎます。そのようなパフォーマンスヒットをとらずに、私がやろうとしていることを行う別の方法はありますか?
2 に答える
私の最初のアプローチは、起動時に転送されるデータのサブセットを識別し、作業中のサブセットを記録し、そのデータの転送を試みるパッケージを作成することです。完了すると、そのデータが転送されたものとしてマークされ、終了します。そうでなければ、それはすでに爆破されており、そのパッケージが行うことは何もありません。
別のプロセスはX時間枠を実行し、失敗した転送(処理中であるとマークされているが、Y期間より古いサブセット)を見つけようとします。次に、それらの行を転送テーブルから削除するか、転送の対象としてマークします。一般的な考え方は、壊れたものにはやり直しのフラグが立てられるというものです。
これは非常にシンプルな設計であり、最も難しい部分は、転送されたものと転送されなかったものをセグメント化して追跡し、N時間枠ごとにパッケージを起動するSQLエージェントジョブを設定することです。障害が発生したのがネットワークではなかった場合、このようなデータ転送を行うことの良い点は、実行を並列化して最大のスループットを得ることができることです。SSISチームは、データをロードするための記録を設定するときに同様のアプローチを取りました。彼らはまた、システムから地獄を追い出しましたが、それはあまりにも予想されています。
1B行システムで多くの更新が行われている場合、データセグメント化ロジックには、変更を識別し、それらのレコードがシステムにフィードバックされるようにするためのメカニズムが必要になりますが、必要として指定しなかったため、無視します。今のところそれ。
ルックアップを使用しようとしている場合は、絶対に必要なものだけをプルバックしていることを確認してください。この場合、それが非常に狭いキーであることを願っています。セグメント化されたデータロードアプローチを採用している場合は、ルックアップトランスフォーメーションで同じパーティショニングロジックを使用していることを確認してください。それ以外の場合は、最終実行時にデータの(1B -1 * transferSize)行をプルバックします。これにより、見苦しいネットワークで大混乱が発生することは間違いありません。
一般性はたくさんありますが、ファセットの詳細が必要な場合は歌ってください。
一度に100万行でこのようなことをする価値はありますか
DECLARE @Counter Int, @ReturnCode Int
DECLARE @Rows INT = 1000000, @Goal INT = 1000000000
WHILE (@Counter * @Rows < @Goal)
BEGIN
EXEC @returncode = xp_cmdshell 'dtexec /f "C:\\path\\package.dtsx" /SET \\package.variables [User::Counter].Value;"' + CONVERT(VARCHAR(10), @Counter) + '"'
IF (@returncode = 0)
BEGIN
@Counter = @Counter + 1
PRINT 'Failed this at this time dude: ' + CONVERT(VARCHAR(30), GETDATE())
END
END
次に、クエリのoledbソースコンポーネント内に、次のようなwhere句があります。
WHERE TableID BETWEEN (SELECT MIN(TableID) FROM Table) + ((? - 1) * 1000000))
AND (SELECT MIN(TableID) FROM Table) + (? * 1000000))
ただし、いくつかのことがあります-SSIS変数の式でクエリを作成する必要があると思います(これまでに作成したことがありますか?簡単です。サブクエリのパラメータを使用するとエラーが発生することがあります)。おそらくMINを取得する必要があります。 (TableID)最初に一度だけ、変数にも格納します。
これだけのトラブルの価値はありますか?これが役立つと思いますか?