差分
このページの2つのバージョン間の差分を表示します。
次のリビジョン | 前のリビジョン | ||
blog:2018:2018-07-03 [2018-07-03 11:53] Decomo 作成 |
blog:2018:2018-07-03 [2021-05-17 09:45] Decomo |
||
---|---|---|---|
行 1: | 行 1: | ||
- | ====== ZFSとSambaで大量のファイルを扱う時はcase-sensitiveの組み合わせを最適化する ====== | + | ====== |
- | 同一フォルダに大量のファイルがあるとSambaが超遅くなる問題、自分なりの知見が得られたのでメモ。結果だけ知りたい人は最後までスクロールしてくだしあ。 | + | [[blog: |
- | まずはおさらい。 | + | ===== おさらい |
- | ことの発端は、数万個のファイルがあるフォルダをSambaのファイルサーバにコピーすると、速度が10kB/ | + | ことの発端は、数万個のファイルがあるフォルダをSambaのファイルサーバにコピーすると、速度が10kB/ |
- | 調べてみると、Sambaはファイル作成時、ファイル名の重複チェックのため作成先フォルダ内の全ファイル名を検査することが分かった。この時に行われる、Windowsのファイル名規則(FS上は大文字小文字を区別するが、OSの表面上は区別しないナンチャッテcase-preserving。この差はOSが吸収する。)と合わせるための、ファイル名を大文字ないし小文字に変換する処理がボトルネックのようだ。 | + | 調査を進めると、Sambaはファイル名の重複チェックのため、ファイル作成時に作成先フォルダ内の全ファイル名を検査することが分かった。この時に行われる、ファイル名の大文字/小文字変換と比較処理がボトルネックとなっているようだ。Windowsでは歴史的にファイル名の大文字/小文字を区別しない((ファイルシステム上は区別して保存されている。この差はAPIで吸収され傍目からはcase-preservingのように見える))が、UNIX系ではOS/ファイルシステム共に大文字/小文字を区別することが多い。このWindowsとUNIXの違いをSambaで吸収してやる必要があるわけだ。 |
- | プロファイルしたわけでもソースコードを見たわけでもないので確証はないが、公式ドキュメントに「ディレクトリに大量のファイルがある特殊なケースでは、case sensitiveをyesにせよ」(抄訳)と書かれており、ファイルコピーの進捗にあわせ指数関数的に速度が落ちる(CPU負荷が上がる)という挙動から、たぶん当たってると思う。 | + | プロファイルしたわけでもソースコードを見たわけでもないので確証はないが、Sambaのドキュメントに「ディレクトリに大量のファイルがある特殊なケースでは、case sensitiveをyesにせよ」(抄訳)と書かれており、ファイルコピーの進捗にあわせ指数関数的に速度が落ちる(CPU負荷が上がる)という挙動から、当たらずとも遠からずだと思う。 |
- | '' | + | では'' |
- | 前述の通りWindowsはFS的にはcase-sensitiveだが、歴史的理由で表面上はcase-insensitiveとして振る舞う。この仕様に胡坐をかき、ファイルパスを全部大文字or小文字に変換して扱うアプリケーションが少なくない。つまり、本来のファイルパスは'' | + | 前述の通りWindowsはFS的にはcase-sensitiveないしcase-preservingだが、表面的にはcase-insensitiveとして振る舞う。この仕様に胡坐をかき、ファイルパスを内部的に大文字または小文字に変換して扱うアプリケーションが少なくない。例えば、本来のファイルパスは'' |
- | '' | + | |
- | で、ローカルのファイルシステムに対してならWindowsがよしなに取り計らってくれるのだが、サーバの共有フォルダに対しては何の処理も行わず、アプリから渡されたファイルパスをそのまま渡しているようだ。アプリが'' | + | ローカルのファイルに対してなら、Windowsがよしなに取り計らってくれるので問題にはならない。 |
- | では、この差をどこで吸収させるかと言ったら、もうファイルシステムしかない。 | + | しかし、共有フォルダのアクセスに関しては、忖度することなくリクエストされたファイルパスをそのままサーバに渡しているようだ。ゆえにサーバ側でそのあたりが考慮されてないと、意図したファイルが見つからないという事になる。Sambaの'' |
- | 幸いにしてZFSには'' | + | '' |
- | Windowsとの共有は'' | + | ===== ではどうするか |
- | そもそもSambaがファイル名をキャッシュせずファイル作成毎に全舐めしてしているのは、恐らく対象フォルダに対する変更をSamba側で検知する仕組みがないからだと思う。Sambaがファイルを作成しようとしたまさにその時、同名のファイルがサーバのローカルで作られたり、別のファイルがリネームされたりする可能性があるため、キャッシュではファイル名のユニーク性を担保できないという判断だと思われる。 | + | そこでZFSの'' |
- | 一方、ファイルシステムレベルなら、そのような変更の検出とアトミック性・ユニーク性が保証された素敵な仕組みがあるハズだから、アプリ側でファイル名の全比較を行うより効率的なんじゃねっていう目論見。 | + | その名の通り、ファイル名の大文字/小文字の取り扱いに関するプロパティで、デフォルト値は'' |
- | 結論としてはSambaとZFSで以下の設定を行う。 | + | これを'' |
+ | |||
+ | 残念ながら、というか性質を考えたら仕方ないけど、本プロパティはデータセット作成時にしか指定できない。既に問題が起きてしまっている場合は、'' | ||
+ | |||
+ | そのうえでSamba側の'' | ||
+ | |||
+ | Sambaがファイル作成時にファイル名を全舐めしてしているのは、対象フォルダに対する変更をSamba側で検知する術がないからだと思われる。Sambaがファイルを作成しようとしたまさにその時、同名のファイルがサーバのローカルで作られたりする可能性があるから、キャッシュではファイル名のユニーク性を担保できず、都度確認せざるを得ないのだろう。 | ||
+ | |||
+ | 一方、ファイルシステムレベルなら、ファイル名の一意性やアトミック性の保証が効率的に行えているだろうという目論見。 | ||
+ | |||
+ | ===== 結論 ===== | ||
+ | |||
+ | 結論としてはSambaとZFSで以下の設定を行うと幸せになれる。ZFSじゃない人はスマン… | ||
* ZFS | * ZFS | ||
* ファイル共有用にcasesensitivity=caseinsensitiveなFSを作る< | * ファイル共有用にcasesensitivity=caseinsensitiveなFSを作る< | ||
- | zfs create -o casesnsitivity=caseinsensitive ztank/ | + | zfs create -o casesnsitivity=caseinsensitive ztank/ |
+ | </ | ||
* Samba | * Samba | ||
* ファイル名の扱いをcase-sensitiveにする< | * ファイル名の扱いをcase-sensitiveにする< | ||
case sensitive = yes | case sensitive = yes | ||
- | case preserve = no | + | case preserve = yes |
- | short preserve case = no | + | short preserve case = yes |
</ | </ | ||
+ | <WRAP center round info 60%> | ||
+ | (2021-05-17 追記) | ||
+ | |||
+ | 上記設定について、以前はcase preserve, short preserve caseをnoとしていたが、yesの方が良さそうである。これらはファイル新規作成時のファイル名の大文字・小文字の取り扱いのオプションで、noだと大文字ないし小文字に変換されていまう(default caseの指定に因る。デフォルト値はlowerなので小文字になる。) | ||
+ | </ | ||
+ | |||
+ | |||
+ | ===== 参考サイト ===== | ||
+ | |||
+ | * [[https:// |