ローカル環境でperlを動かし、毎日少しずつネット上から情報を取得し保存しているのですが、HDD中の断片化率が酷いような気がします。

そこで、なるべく断片化させること無くHDDへ情報を保存させる方法は無いものでしょうか?
宜しくお願い致します。

回答の条件
  • 1人2回まで
  • 登録:2009/11/20 17:10:03
  • 終了:2009/11/21 05:00:14

ベストアンサー

id:decoy2004 No.3

decoy2004回答回数20ベストアンサー獲得回数22009/11/20 23:28:01

ポイント38pt

Aについて

Perlで実現する場合は、fileをopenしてread/writeすることになります。

初回ファイル作成はHDDフォーマット直後 or HDDデフラグ直後にダミーデータを書きこんでおきます。

本物のデータを書く際は、断片化を防ぐためファイルサイズを増減させないよう書き換えます。

サンプルコード

ランダムアクセスを使って読み書きする - Perl入門~サンプルコードによるPerl入門~ -

http://d.hatena.ne.jp/perlcodesample/20080810/1218332357

Bについて

元記事には「ファイルの断片化を最大85%、*未然*に防ぐ機能」「ほかの作業に影響を与えることなく

デフラグ処理を行う。 」とあるので、おそらくダウンタイムにはならないと自分は解釈しました。

元記事だけではこれ以上は分からないので、詳しく知りたい場合はこのソフトの販売元に問い合わせる

と良いと思います。

Cについて

データ保存用ドライブではファイルを追加だけにして削除/サイズ増減をしなければ、

理論上は断片化を防げると思います。

複数プロセスでデータ保存用ドライブへのファイル書き込みすると断片化が発生し

うるので、書き込みは1プロセスだけに限定した方がいいですね。

実装例:外部から受け取ったデータは一旦作業用ドライブに格納しておきデータ保存用ドライブ

への転記は1ファイルずつにする。

id:TREEG

回答いただきありがとうございます。

A.ちょっと今回の私の用途ではそのまま使えない気もしますが、とても興味深いコードでした。

B.できれば、これ以上外部のソフトを入れたくないため、こちらについてはどうしても必要になった時、本格的に調べてみようと思います。

C.この方法はなかなか良いかもしれません。ただ、欲を言えば、今あるPerlコードを少しだけ書き換える程度できればと思っていましたので、なかなか興味深くはあるのですが残念なところですが、新しく作るプログラムについてはこの方法を採用するのもありですね!

2009/11/21 00:19:01

その他の回答(2件)

id:sirotugu40 No.1

sirotugu40回答回数449ベストアンサー獲得回数142009/11/20 18:40:06

ポイント15pt

仮想ディスクを作ってそこに保存すれば断片化を防げます。

http://www.forest.impress.co.jp/docs/review/20091105_326376.html

id:TREEG

回答いただきありがとうございます。

面白いアイディアですが、物理的には1つのファイルですが、

VirtualPCの様な仮想HDを作った場合、その仮想HDの中が断片化してしまいそうですがどうでしょうかね?

結局は、断片化によるHDDの速度低下や壊れやすさの低減には役に立たないような気がします。

2009/11/20 19:21:16
id:decoy2004 No.2

decoy2004回答回数20ベストアンサー獲得回数22009/11/20 20:02:18

ポイント27pt

3つ方法をあげます。

A. あらかじめファイルを用意する

あらかじめ大きめのファイルを用意しておき、後から上書きすれば断片化を防げます。

B. ファイルの断片化を防ぐユーティリティを使う

相栄電器、ファイルの断片化を防止するデフラグソフト「Diskeeper 2010」 - http://www.asahi.com/digital/bcnnews/BCN200911190014.html

ファイルの断片化を最大85%、未然に防ぐ機能「IntelliWrite(インテリライト)」を搭載。

C. 頻繁に書き換えるドライブと保存するドライブを分ける。

ファイル断片化を未然に防ぐ - http://www6.airnet.ne.jp/~shiyou/cgi-bin/weblog/logwing.cgi?comm...

id:TREEG

回答いただきありがとうございます。

Aについて、これは、Perlでも有効でしょうか?もし分かりましたらコードとともに教えていただけると助かります。

Bについては、ダウンタイムの発生はあまり好ましくありませんので難しいです。

Cについては、すでに、HDD1台丸ごと、データ保存用にしています。

2009/11/20 20:17:28
id:decoy2004 No.3

decoy2004回答回数20ベストアンサー獲得回数22009/11/20 23:28:01ここでベストアンサー

ポイント38pt

Aについて

Perlで実現する場合は、fileをopenしてread/writeすることになります。

初回ファイル作成はHDDフォーマット直後 or HDDデフラグ直後にダミーデータを書きこんでおきます。

本物のデータを書く際は、断片化を防ぐためファイルサイズを増減させないよう書き換えます。

サンプルコード

ランダムアクセスを使って読み書きする - Perl入門~サンプルコードによるPerl入門~ -

http://d.hatena.ne.jp/perlcodesample/20080810/1218332357

Bについて

元記事には「ファイルの断片化を最大85%、*未然*に防ぐ機能」「ほかの作業に影響を与えることなく

デフラグ処理を行う。 」とあるので、おそらくダウンタイムにはならないと自分は解釈しました。

元記事だけではこれ以上は分からないので、詳しく知りたい場合はこのソフトの販売元に問い合わせる

と良いと思います。

Cについて

データ保存用ドライブではファイルを追加だけにして削除/サイズ増減をしなければ、

理論上は断片化を防げると思います。

複数プロセスでデータ保存用ドライブへのファイル書き込みすると断片化が発生し

うるので、書き込みは1プロセスだけに限定した方がいいですね。

実装例:外部から受け取ったデータは一旦作業用ドライブに格納しておきデータ保存用ドライブ

への転記は1ファイルずつにする。

id:TREEG

回答いただきありがとうございます。

A.ちょっと今回の私の用途ではそのまま使えない気もしますが、とても興味深いコードでした。

B.できれば、これ以上外部のソフトを入れたくないため、こちらについてはどうしても必要になった時、本格的に調べてみようと思います。

C.この方法はなかなか良いかもしれません。ただ、欲を言えば、今あるPerlコードを少しだけ書き換える程度できればと思っていましたので、なかなか興味深くはあるのですが残念なところですが、新しく作るプログラムについてはこの方法を採用するのもありですね!

2009/11/21 00:19:01
  • id:kn1967
    ハードディスクの持ってる物理的ファイルキャッシュや
    OSのファイルキャッシュなどもあるから、よほどの事がなければ、
    パフォーマンス的に影響が出るようなものにはならず、
    あまり気にしなくて良いと思うのだが?

    通常作業の裏でデフラグ見たいな事を実行する手もあると思うけど、
    HDDへの負担を考えたら、もっと単純にOSやソフト用のパーティションと、
    テンポラリ用のパーティション、データ専用のパーティションといった具合に、
    個別に用意するとかで対処するしかないと思うよ。

    何を求めているのか良くわからないので以上、コメント欄。
  • id:b-wind
    > ネット上から情報を取得し保存 -> HDD中の断片化率が酷い
    こう判断した理由をまず聞きたいな。
  • id:TREEG
    kn1967さま
    コメントありがとうございます。
    Cドライブなど1-2年に1回リカバリするので正直あまり気にならないのですが、b-windさまの説明にも書いた通り、明らかに差が出ています。
    例えば、FileFireCopyで他のHDDへバックアップしたのですが、USB2.0で動作しているにもかかわらず、転送速度が4MB/sも出ていません。
    フォルダ訳については、HDDが一杯になったら新しいHDDにログを保存しようと考えているため、パーテンション分けせず、外付けのHDD1台丸ごと使っています。
    FireFileCopyなど断片化を抑えコピーする機能が付いているため、何か、良い方法が無いものかと質問した次第です。


    b-windさま
    コメントありがとうございます。掲示板のログなど比較的小さいファイルと、ホームページのログを膨大な数無圧縮で保存しているのですが、これに使っているHDDの断片化率が余りに酷く50%以上のファイルが断片化しています。1ファイルが数万に断片化しているものもあり、明らかに体感できるくらい落ちているためです。比較については、通常使っているパソコンのCドライブです。保存させているファイル数に比較にならない差がありますが、FireFileCopyなど断片化を抑えコピーする機能が付いているため、何か、良い方法が無いものかと質問した次第です。
  • id:TREEG
    本来であれば、SQLソフトの様な物を使う様な内容かもしれませんが、バックアップや環境のセットアップが手間なため見送っています。
  • id:kn1967
    内蔵HDDとの速度比較は置くとしてUSB-HDD同士のコピーにしても遅いよね。

    遅いUSB機器がぶら下ってるとか、そのUSB-HDD自体が遅いんじゃないかな?
    (USB2.0対応だからといって全ての機器がHiSpeed対応とは限らない)
    USBハブ経由とかが原因の可能性も視野にいれたほうがいいのかな?

    なんにせよ、断片化が本当の原因かどうか考えてみたほうがいいと思うよ。
  • id:TREEG
    kn1967さま
    ほぼ確実に断片化が原因だと思います。と申しますのも、コピーする時やフォルダを開くだけにも関わらずHDDへのアクセス音が派手にしますので・・・
    また、デフラグの分析でも、青い部分は殆どありません。見事なほどに真っ赤です。
    分析結果で簡易表示できる範囲内ですと、最も断片化の小さいものでも、1500以上になっています。
  • id:Reiaru
    理論的には同名ファイルで上書きしてサイズが増大するか、ファイルの削除を行わない限りは断片化は発生しない筈です。
    (RAID とか入ってると話が変わってきますけれども)

    そもそも、Perl はローカルで扱うべき様な言語では無いと (私は) 思いますが、
    逆説的に言ったらデフラグなんてかけないレンタルサーバーでは断片化しまくってお話にならない状態になっているのでは。
    や、だからと言ってそんなにアクセス速度が低下しますかね…? (理論的にはそうですが、体感で分かるかと言いますと?)

    2 番目の回答者である decoy2004 様の提案は面白いと思いました。
    > A. あらかじめファイルを用意する
    ファイルサイズが完全に固定されており、かつそのファイルをオープンしている間に他の書き込みが行われない事を保証できれば、
    確かにその手法でいけそうな気がします。

    ローカルでどうこうする場合の手っ取り早い手段は、その断片化しているらしきデータを一度別ドライブに退避 (移動) させ、
    その元ドライブにデフラグをかけた上で退避させたデータを書き戻す事だと思います。
    そうする事で完全に詰まった状態でデータが書かれますからね。
    但し、同名ファイルのサイズが変わる様な事があれば再び断片化してしまいます。
  • id:TREEG
    Reiaru さま

    コメントいただきありがとうございます。

    >理論的には同名ファイルで上書きしてサイズが増大するか、ファイルの削除を行わない限りは断片化は発生しない筈です。
    いくつかのファイルを、別々のサーバから同時に保存しているため、これが最も大きな原因かと思います。例えば、10MBのログファイルをダウンロードしつつ、1KBのHTMLをいくつも書き込むという使い方です。ただ、保存だけで、呼び出すことが殆どありませんので通常の利用ではあまり障害を感じず、ここまでのフラグメーションになってしまったのかもしれません。ここ半年くらい殆ど自動化して、HDDの残り容量もPerlを常駐させチェックするだけで殆ど管理していませんでしたので、どの様な動作をさせていたか自信がありません。

    わたしも、この質問をして考えている時、画像掲示板やアップローダ、メールサーバやそのログなど、頻繁に書き換えが発生する場合、かなり酷い事になっているのではないかと思っています。ただ、実際はそこまで遅くなりませんのでフラグメーションは起こっていないのかもしれません。

    >ファイルサイズが完全に固定されており、かつそのファイルをオープンしている間に他の書き込みが行われない事を保証できれば、確かにその手法でいけそうな気がします。
    FileFireCopyがそのような感じです。データを移し替える前に、一度、同じサイズの容量を確保しています。
    Perlで尚且つ、同じ時間に、いくつかのデータが書き込まれるという条件下で、これは可能でしょうかね?
    Perlは何でもできる言語だと思っていますが、いまいち、このコードが思いつきません。


    >そもそも、Perl はローカルで扱うべき様な言語では無いと (私は) 思いますが、
    Perlしかまともに使えませんが、Perlはローカルでもバリバリ動きますし、特に、自動で文字列やデータの整理(バッチ処理?)をさせる場合、原因不明のフリーズも起こらずローカルでもかなり良い言語のように感じています。もしよろしければ、更にローカルに強い言語を教えていただけると幸いです。

    >ローカルでどうこうする場合の手っ取り早い手段は、その断片化しているらしきデータを一度別ドライブに退避 (移動) させ、
    そうですね。私の場合、余ったHDDがあったため、FileFireCopyでそのままコピーしました。フラグメーションは解消されていますね。
  • id:b-wind
    定期的なデフラグでは何か問題があるのか?

    いっそファイルシステムごと変えた方がよくね?
    FAT/NTFS はかなり断片化に弱いし。
    まぁ Windows のままじゃ難しいか。

    >ほぼ確実に断片化が原因だと思います。と申しますのも、コピーする時やフォルダを開くだけにも関わらずHDDへのアクセス音が派手にしますので・・・
    あとこれで結論を出すのはまだ早いな。
    断片化して無くてもファイル数が多ければそれなりにアクセスは遅くなる。
    本当に「断片化だけ」が問題かは確認する方がいい。

    > 分析結果で簡易表示できる範囲内ですと、最も断片化の小さいものでも、1500以上になっています。
    アプリケーションのデータの持ち方自体を考えた方が良さそうではある。

    > そもそも、Perl はローカルで扱うべき様な言語では無いと (私は) 思いますが、
    > 逆説的に言ったらデフラグなんてかけないレンタルサーバーでは断片化しまくってお話にならない状態になっているのでは。
    思うのは自由だけどある程度理由を述べないと話にならないな。
    ちなみにレンタルサーバーでよく使われる Linux/BSD 系のファイルシステムは
    FAT/NTFS 系に比べれば圧倒的に断片化しにくい特性を持ってる。
    もっともデフラグが不要なわけではないがね。


  • id:kn1967
    TREEG さん>10MBのログファイルをダウンロードしつつ、1KBのHTMLをいくつも書き込むという使い方です。

    データベースだって、そのような使い方だと断片化するかもね。
    そう、させないようにしたければ書き込み時に気をつけるしかないって事なんだよね。
    容量的にも小さいものばかりだし、Perl使ってるんだったら、
    内蔵ドライブ上でもメモリ上でもいいから、読み込みバッファを用意して、
    一旦、バッファに読み込んでから、HDDに書き込むようにすればいいだけじゃないの?


    id:Reiaru さん>Perl はローカルで扱うべき様な言語では無い

    cgiからPerlを知った人に取ってはサーバ色が濃いのかもしれませんね。
    でも、Perlはテキスト処理用として生まれ育ってきたものなので、
    どちらかっていうとローカル色のほうが濃かったりもしますよ。
    まぁ、なんにせよ、使えるものならローカルでもサーバでも、
    どちらでも構わないって事なんですけどね。
    (逆にphpは最初からサーバで動かす用途で生まれ育ってきたものですが、
     これまたローカルでも使えるので、慣れている人ならローカルでもOKです。
     私も普段のちょっとした確認はphpでもRubyでもjavaでもコマンドラインで済ませちゃいます)
  • id:TREEG
    b-windさま

    >あとこれで結論を出すのはまだ早いな。
    >断片化して無くてもファイル数が多ければそれなりにアクセスは遅くなる。
    そうですね。細かいデータも膨大な数ありますのでこちらも(が)原因かもしれません。

    FATよりもNTFSが断片化しにくいとは聞きます。
    サーバは圧倒的なまでに断片化しにくいのですか・・・
    LANなどでファイルサーバを作りそこに保存するのも一つかもしれませんね。


    kan1967さま

    欲しいと思った機能をPerlで作り、どんどん追加して、24時間動かしていますので、それぞれが、同期をとらず、好きな時に好きなだけ書き込んでいます。そのため、1つのプログラムにまとめて動作させることは難しいです。また、プログラマーの方はしないと思います(?)が、スレッドを作成するのは、私の技量的に辛いですし、後からプログラムを追加するのが面倒です。同じプログラムでも単純にフォルダ分けして10個立ち上げて実質の並列処理させたりしていますので、プログラムを1つにまとめ、バッファに溜めて適切な時に書き込むというのは難しいです。

    また、もしそれをするなら、ある意味、毎日デフラグ?ですが、1日1時間程度、全てのプログラムを止めて、23時間以内に書き込んだものを検索して、全てリネームし、リネーム前の名前で書き込み、元ファイルを削除するのもありかも知れませんね。

  • id:b-wind
    > Perlはテキスト処理用として生まれ育ってきたもの
    正確には sed/awk/sh の代替として生まれた物って所だね。
    おかげで unix コマンドのいくつかは中身は Perl 製って事も多々ある。

    > データベースだって、そのような使い方だと断片化するかもね。
    RDBMS は書き込みに関してはあんまり極端なメリットは無いからそうなる可能性大。

    >10MBのログファイルをダウンロードしつつ、1KBのHTMLをいくつも書き込むという使い方です。
    少なくともログファイルのダウンロードと HTML の書き込み処理は分けた方が無難っぽい。
    保存場所を物理的に変えるだけでもそれなりに効果はあるはず。

    > 内蔵ドライブ上でもメモリ上でもいいから、読み込みバッファを用意して、
    > 一旦、バッファに読み込んでから、HDDに書き込むようにすればいいだけじゃないの?
    現在の情報だけから判断するとこの案に同意。
    バッファが面倒なら RAM ディスクでも作ってそこに保存->あとでまとめて移動でいいんじゃない?


  • id:TREEG
    古いノートPCを使っているため、これ以上メモリを積むことができませんので、とりあえず、今回の件ではRAM-Diskは無理ですがとても参考になりました。ありがとうございます。


    皆様へ
    沢山のコメントいただきありがとうございました!
    とても参考になりました。
  • id:b-wind
    >今回の件ではRAM-Diskは無理
    RAM ディスクって言っても数メガ程度でよさそうだけどね。

    >古いノートPCを使っているため
    一番のネックはこれじゃないの?
  • id:TREEG
    コメントありがとうございます。
    1日に1GB近くは新規にデータを保存していると思いますので、1.5GBくらいはRAMを作成したく思っています。また、プログラムが増えると、それに伴って保存すべきデータも増えるため、パーテンション分けしたHDDの方が良いかもしれません。
    なお、現在のノートPCの最大メモリがM/Bの都合で1.5GBのようでメモリのこれ以上の搭載は無理という感じです。また、Perlプログラムがメモリを常に500MB~1GB程度は利用していますので厳しいところがあります。
    古いノートPCは、24時間付けっぱなしのため節電を考えて、PenM1.4Gの中古で買ったDell製のノートです。本当はCore2Duoにしたかったのですが・・・

    更新のあったファイルだけ探し出して、コピーし直す、
    もしくは毎日、断片化したファイルのみ選び出しデフラグをする、
    もしくは、今回、極端に遅くなることはあっても、HDDが壊れたわけではないので、現状のまま様子を見る方向でいます。
  • id:kn1967
    >1日に1GB近く

    RAMディスクに一日分ためようと考えると無理があるけど、
    あくまで一時利用なんだから100-200MBもあれば十分だと思うよ。

    RAMディスクを監視してファイルロックが解除されているものを見つけたら、
    順次USB-HDDにコピーするというようなスクリプトを新たに準備して、
    各スクリプトを順次、RAMディスクへ書き込むように書き換えて様子をみるって
    流れになるかな。
    (Windowsでファイルロックは一工夫が必要だけど、それはまた別の話だね)


    >Perlプログラムがメモリを常に500MB~1GB程度は利用

    それも遅い原因じゃないのかな?
    Perlに限った事じゃないけど、
    スクリプトの組み方ひとつでメモリ利用量は桁が違ってくるんだよね。
    でも、これはスクリプト1つ1つをつぶしていかないといけないから、
    決定打がないのよね・・・。

    特にリソース(メモリやCPU時間などね)を食ってるスクリプトだけでも、
    チューニングできたら違うんだろうけど・・・。
  • id:b-wind
    > >1日に1GB近く
    > RAMディスクに一日分ためようと考えると無理があるけど、
    > あくまで一時利用なんだから100-200MBもあれば十分だと思うよ。
    先に言われちゃったけどこのとおりだな。トータル1.5GBで足りなくなるような処理とは考えにくい。
    どうしてもメモリに抵抗あるならテンポラリ用のディスク追加すれば済む話だろ?
    単にばらばらに書き込むから断片化するだけなんだから。

    > >Perlプログラムがメモリを常に500MB~1GB程度は利用
    > それも遅い原因じゃないのかな?
    まぁディスクの断片化とは直接関係無いがディスクバッファに回せる分が減るから
    トータルの性能劣化の原因としてはありうる。
    処理内容によるけどそのスペックでそのメモリ使用量はきついだろ。
    世代的にメモリのスピードも今とはかなり違うしね。

    どの程度の手間をかけてる(かけていい)ものか分からないけど、
    ここらで一度全体の構成を見直すべきなんじゃないかな?
    個別の問題への場当たり的な対処じゃなくね。

    もっとも Perl に限定していえば open/read といった標準関数すら
    上書きできるので、暫定的でも十分な有効手段も取りようはあるけどね…。
    魔の道に進む覚悟があるなら、だけど。

    どっちにしろもっと全体的な構成をさらして(処理の概要も)質問しなおすことをお勧めするが。
    興味が引ければ丸ごとコード書くような回答もあるかもしれないしね・・・。
  • id:TREEG
    kn1967 さま b-wind さま
    何度もコメントいただき本当にありがとうございます!

    >> あくまで一時利用なんだから100-200MBもあれば十分だと思うよ。
    この意味がようやく理解できました。なるほど!確かに、それであれば、可能ですね。
    ただ、ロックはややこしく膨大なファイル数を長期間処理していると1回くらい外し忘れたりとトラブルが出そうですので怖いです。
    ちなみに、現在の書き込みはこのトラブルが怖いため、ロック制御は一切使っていません。

    >>ここらで一度全体の構成を見直すべきなんじゃないかな?
    >>個別の問題への場当たり的な対処じゃなくね。
    ですよね・・・とりあえず、次、HDDが一杯になるか、システムが止まった時には考えようと思います。
    もしくは、本当に大切なデータを扱う様になった時、全体的な問題に取り組みたいと思います。
    適当なプログラムでも最近のハードは凄いですから何とかなるが持論です。プログラマの方から見るとダメダメですよね。
    また、とりあえず、役に立ってくれれば良いと思って作っていますので、二度と読めないような書き方をしているので本当に大変です。
    また、こちらで余り詳しく書いていないのは、兎に角、色々なプログラムを追加してしまい、何がどう作動しているのか忘れているところがあります。

    Perlの書き込み方法をちょっと工夫するだけで簡単にできるかと淡い期待をしていましたが、甘くはなさそうですね・・・


    >もっとも Perl に限定していえば open/read といった標準関数すら
    >上書きできるので、暫定的でも十分な有効手段も取りようはあるけどね…。
    >魔の道に進む覚悟があるなら、だけど。
    そんな方法があるのですか?
    気楽に好きなプログラムを場当たり的、思いつきで書いているだけですのでこれ以上の深入りは辛いです。
    また、安定動作させるには、複雑な書き込み方式を用いない方が良いのではとも思っています。
    例えば、これから書く容量が10Mくらいだと想定する場合、とりあえず、10MB確保して、内容を書き換えて、余った所は空き領域に戻して、足りなかったところは追加で書き込むという感じでしょうか?
    ただ、HDDの動作がいまいち良く分かりませんので、これが断片化にどの程度影響するか分からないというのが私の考えです。
    もし、どんな処理でも、断片化させ難いような、安定した汎用的な記録方式があれば、Perl標準の書き込み方式として欲しいくらい便利ですね。
    ただ、「魔の道」と仰られているという事は、ここまでは甘いことは無いですよね。

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません