- PR -

IISで大量データを更新する場合の対策

1
投稿者投稿内容
インスパ
大ベテラン
会議室デビュー日: 2002/08/30
投稿数: 125
投稿日時: 2007-02-01 09:44
いつもお世話になっています
IIS6とc#でWebの開発を行っているのですが、教えて欲しいことがございます

郵便番号の入ったテキストファイル(1行に1つの郵便番号で1万件ぐらい)を読み込んで
DBへ追加するプログラムを作っています。
プログラムではテキストファイルをループしながら1件づつ読んでDBへ書き込みを行っており
書き込みが終わったものをログファイルに出力しているのですがある時点まで処理すると
処理が止まってしまいます(ログファイルに書き込みがされなくなり、DBも途中まで追加された状態で止まっています)

そこで実行中のWebサーバを調べてみたところ2点気になることが有りました
・ワーカプロセス(w3wp.exe)のメモリサイズが増えつづけてある時点まで来ると横ばいになる
・ページファイルもワーカプロセスと同じく増えつづけてある時点まで来ると横ばいになる
横ばいになったあたりで処理は止まっているようです

ここからが質問なんですが
このように大量のデータを更新する場合はワーカプロセスやページファイルは
増えつづけるものなのでしょうか?
もしそうだとすれば、どのような対応策があるのでしょうか?
考えられるのは、一度に更新するデータ量を減らすことですが、これは運用的に見て
難しそうなので、何か他に対応することがあるようでしたらお教えいただきたいです
よろしくお願いいたします
burton999
ぬし
会議室デビュー日: 2003/10/06
投稿数: 898
お住まい・勤務地: 東京
投稿日時: 2007-02-01 10:30
郵便番号のテキストファイルをWebからアップロードして処理しているのですか?
データは1件づつコミットしているのですか?
再現するミニマムコードを書いていただけると、回答しやすいと思います。
甕星
ぬし
会議室デビュー日: 2003/03/07
投稿数: 1185
お住まい・勤務地: 湖の見える丘の上
投稿日時: 2007-02-01 12:01
引用:

Natsumeさんの書き込み (2007-02-01 09:44) より:
ここからが質問なんですが
このように大量のデータを更新する場合はワーカプロセスやページファイルは
増えつづけるものなのでしょうか?
もしそうだとすれば、どのような対応策があるのでしょうか?


本来はガベージコレクションがメモリを開放してくれる筈です。まずは使わないのに到達可能なままになっている変数や、開放していないアンマネージドリソースが無いか確認してください。それでも駄目ならGC.Collectとか呼び出すことになります。でもあまり神経質に気にしない方が良いですよ。

引用:

考えられるのは、一度に更新するデータ量を減らすことですが、これは運用的に見て
難しそうなので、何か他に対応することがあるようでしたらお教えいただきたいです
よろしくお願いいたします


でも問題はメモリ使用量云々じゃなくて、アプリケーションプールのリサイクルとの兼ね合いにあります。メモリの使用量が一定に達した場合や、一定時間の経過により、ASP.NETのワーカープロセスを終了します。たぶんメモリ使用量が増加したことにより、リサイクルされたのだと思います。

どの程度時間がかかるかにもよりますが、数十秒以上かかることが分かっているなら、ASP.NETでの記述はやめた方が良いと思います。ASP.NETはファイルを受け取って保存するだけにとどめて直ちに応答を返し、実際の登録処理は別のプロセスにゆだねた方が良いでしょう。

あまり長時間待たせるとWEBブラウザがタイムアウトを起こす可能性もありますし、痺れを切らしたユーザーが更新ボタンを連打するかもしれません。
インスパ
大ベテラン
会議室デビュー日: 2002/08/30
投稿数: 125
投稿日時: 2007-02-01 14:22
甕星さんどうもありがとうございます。
その後何度かテストを行っているのですが、メモリ使用量が増えてもガベージコレクションが働いて(たぶん)減っている場合も有ります(この場合は最後まで更新できます)
それと、アプロケーションプールの設定でメモリのリサイクルという項目があり
デフォルトではチェックがついていなかったので試しにチェックをつけてみました
値はデフォルトのまま(最大仮想メモリ:500MB、最大使用メモリ:192MB)
そうすると、メモリは増減を繰り返しながら最後まで実行することが出来ました
(この設定で何度か実行しましたが全て最後まで実行できています)
根本的な解決ではないと思うので、プログラムコードで開放していないものが無いか再度確認いたしますが
このメモリのリサイクルというのは有効なような気がするのですがいかがでしょうか?
あと、burton999さんから確認のありました項目
・郵便番号のファイルはWebでファイル名を設定して以下のようにしてサーバ側で読み込んでいます
protected System.Web.UI.HtmlControls.HtmlInputFile filUpload;
Encoding encode = Encoding.GetEncoding(932);
System.IO.Stream strm = this.filUpload.PostedFile.InputStream;
sReader = new StreamReader(strm, encode);
while (srCSV.Peek() != -1) {
//このループ内で処理を実行
}

・コミットは全件正常終了後に行っています


1

スキルアップ/キャリアアップ(JOB@IT)