Armadilloフォーラム

1ディレクト配下に大量のローテーションファイルが存在したときの動作について

kimoto

2021年10月26日 11時36分

お世話になっております。
Armadillo-IoT G3Lから→USB2.0→USB-SATA変換→「SSD(ext4)」と構成した環境下で
SSD内の1つのディレクトリ内に、ローテーションされたファイル(1ファイルあたり10MB)が
SSD容量フルの39000個あるときに動作不安定になることを確認しております。

動作不安定な状況ですが
 ・syslogに、/usr/local/bin/file_rotate.sh: line 82: /bin/ls: Argument list too long のメッセージが出力
 ・ローテーションのスクリプトが正常終了できないまま次々に同じスクリプトが起動してシステムリソース(CPU、メモリ)を消費
等です。
1ファイルあたりのサイズを10MBではなく、100MBとしてSSD容量フルの3900個では
特に動作不安定な状態にはならないことから、1ディレクトリ配下のファイル数が原因
かと考えております。
そのため、1ファイルあたりのファイルサイズは100MB以上にすべきかと思いますが
適切な対処理由が判らず、ご教授頂けると助かります。
また、1ファイルあたりのサイズ上限については制限ありますでしょうか?
何卒宜しくお願い致します。

コメント

at_shinya.koga

2021年10月26日 13時30分

アットマークテクノの古賀です。

kimotoさん:
>Armadillo-IoT G3Lから→USB2.0→USB-SATA変換→「SSD(ext4)」と構成した環境下で
>SSD内の1つのディレクトリ内に、ローテーションされたファイル(1ファイルあたり10MB)が
>SSD容量フルの39000個あるときに動作不安定になることを確認しております。
>
>動作不安定な状況ですが
> ・syslogに、/usr/local/bin/file_rotate.sh: line 82: /bin/ls: Argument list too long のメッセージが出力
> ・ローテーションのスクリプトが正常終了できないまま次々に同じスクリプトが起動してシステムリソース(CPU、メモリ)を消費
>等です。
>1ファイルあたりのサイズを10MBではなく、100MBとしてSSD容量フルの3900個では
>特に動作不安定な状態にはならないことから、1ディレクトリ配下のファイル数が原因
>かと考えております。

ファイル数が要因ではありますが、直接の要因は、syslog に出ている ls のエラーメッセージの通り、ls に渡される引数の文字列合計長が長すぎることだと思います。

>/bin/ls: Argument list too long

この "Argument list too long" については、以下のページが参考になるかと思います:
 https://serverlog.jp/rm-argument-list-too-long/
 https://www.ecoop.net/memo/archives/2010-01-26-1.html
 https://www.baeldung.com/linux/argument-list-too-long-error
 https://linuxjm.osdn.jp/html/LDP_man-pages/man3/sysconf.3.html

上の二番めのページで紹介されている getconf コマンドを使って ARG_MAX の値を調べると、おそらく 2097152 ではないかと思います。
ls に渡されるファイルリストの文字列長が、ファイル数が 39000 個の場合、ARG_MAX の値を超えているのだと思います。

>そのため、1ファイルあたりのファイルサイズは100MB以上にすべきかと思いますが
>適切な対処理由が判らず、ご教授頂けると助かります。

上述しましたように、ファイルサイズが直接の要因ではなく、ファイルサイズ上限値と SSD 容量で決まるファイル個数が原因だと思いますが、いずれにせよ、解決するには、ls に渡されるファイルリストの要素数を減らすことが必要だと思います。

ls に渡されるファイルリストの要素数をj減らす方策としては、おっしゃっているように、ファイルリストのローテーション対象のファイルサイズ上限値を増やすのが簡単だと思います。ただし、今後、SSD を現在よりも大きな容量のものに変えると、それに合わせてファイルサイズ上限値を変更する必要が出るでしょう。

別の方策としては、file_rotate.sh の内容を変更し、ファイル名に対するパターンマッチを使うなどして、ローテーション対象のファイル群の名前一覧を適当なグループで区切って渡すようにすることで、全てのファイル名を ls に渡さないようにする、というのが考えられます。あるいは、ローテーション時にサブディレクトリを作ってサブディレクトリに格納する、という方策もあるでしょう。いかがでしょうか?

>また、1ファイルあたりのサイズ上限については制限ありますでしょうか?

ext4 の最大ファイルサイズは、16TiB (16 x 2^40[B]) となっています:
https://ja.wikipedia.org/wiki/Ext4

kimoto

2021年10月26日 18時52分

この度はコメント頂きまして有難う御座いました。
早速ご教授頂きました対策を行いました。
Argument list too long は出力されないようになりましたが、ファイル個数が多いせいかローテーションのスクリプトに時間がかかることでシステムが重くなる問題までは解決できませんでした。
ローテーション対象のファイルサイズ上限値を増やすか、あるいはコメント頂きましたように、サブディレクトリを作る方策を検討したいと思います。
ローテーションの条件がxxサイズがyy個のほか、サブディレクトリがある点は知りませんでしたので調べたいと思いますが、ご案内頂けるページなどあれば再度ご教授頂頂けると助かります。
何卒宜しくお願い致します。

at_shinya.koga

2021年10月27日 15時01分

アットマークテクノの古賀です。

kimotoさん:
>Argument list too long は出力されないようになりましたが、ファイル個数が多いせいかローテーションのスクリプトに時間がかかることでシステムが重くなる問題までは解決できませんでした。
>ローテーション対象のファイルサイズ上限値を増やすか、あるいはコメント頂きましたように、サブディレクトリを作る方策を検討したいと思います。
>ローテーションの条件がxxサイズがyy個のほか、サブディレクトリがある点は知りませんでしたので調べたいと思いますが、ご案内頂けるページなどあれば再度ご教授頂頂けると助かります。

こちらで提案されている方策は、いかがでしょうか?
 https://serverfault.com/a/437852