差分

このページの2つのバージョン間の差分を表示します。

この比較画面にリンクする

次のリビジョン
前のリビジョン
次のリビジョン 両方とも次のリビジョン
blog:2018:2018-07-03 [2018-07-03 11:53]
Decomo 作成
blog:2018:2018-07-03 [2019-07-24 16:18]
Decomo
行 1: 行 1:
-====== ZFSとSambaで大量のファイルを扱う時はcase-sensitiveの組み合わせを最適化する ======+====== SambaとZFSで大量のファイルを扱う時はcase-sensitiveの組み合わせを最適化する ======
  
-同一フォルダに大量のファイルがあるとSambaが超遅くなる問題、自分なりの知見が得られたのでメモ。結果だけ知りたい人は最後までスクロールしてくだしあ。+[[blog:2017:2017-08-04|同一フォルダに大量のファイルがあるとSambaが超遅くなる]]問題、自分なりの知見が得られたのでメモ。結果だけ知りたい人は最後までスクロールしてくだしあ。
  
-まずはおさらい+===== おさらい =====
  
-ことの発端は、数万個のファイルがあるフォルダをSambaのファイルサーバにコピーすると、速度が10kB/s前後まで低下する現象に見舞われた。速度はコピーが進むごとに低下し、比例するようにsmbdのCPU占有率が上がるというのが特徴。ファイルサーバ上で直接コピーすると何の問題もない。+ことの発端は、数万個のファイルがあるフォルダをSambaのファイルサーバにコピーすると、速度が10kB/s前後まで低下する現象に見舞われた。速度はコピーが進むごとに低下し、比例してsmbdのCPU占有率が上がるというのが特徴。サーバ上で直接コピーすると何の問題もない。
  
-調べてみると、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負荷が上がる)という挙動から、当たらずとも遠からずだと思う。
  
-''case sensitive = yes''にすれば万事解決かとえば、そうじゃない+では''case sensitive = yes''にすれば万事解決かとえば、そう簡単な話ではない。
  
-前述の通りWindowsはFS的にはcase-sensitiveだが、歴史的理由で表面はcase-insensitiveとして振る舞う。この仕様に胡坐をかき、ファイルパスを部大文字or小文字に変換して扱うアプリケーションが少なくない。つまり、本来のファイルパスは''\\Server\FILE.dat''にもかかわらず、アプリケーション内部では +前述の通りWindowsはFS的にはcase-sensitiveないしcase-preservingだが、表面的にはcase-insensitiveとして振る舞う。この仕様に胡坐をかき、ファイルパスを的に大文字または小文字に変換して扱うアプリケーションが少なくない。例えば、本来のファイルパスは''C:\Data\FILE.dat''にもかかわらず、アプリケーション内部では''c:\data\file.dat''として扱うことが往々にある<fc #c0c0c0>(自分もそういう処理をついいちゃうんだけど(;'∀'))</fc>
-''\\server\file.dat''としてアクセスしていることが往々にしてある<fc #c0c0c0>(自分もそういう処理をよく(;'∀'))</fc>+
  
-で、ローカルのファイルシステムに対してならWindowsがよしなに取り計らってくれるのだが、サーバの共有フォルダ対して何の処理も行わず、アプリか渡されたファイルパスをそのまま渡してるようだアプリが''\\server\file.dat''を指定したなら、Sambaにも''\\server\file.dat''が渡ってくる。この時、''case sensitive''オプションがautoかnoならSambaが処理して無事''\\Server\FILE.dat''とマッチするが、yesの場合は…Ω\ζ°)チーン+ローカルのファイルに対してならWindowsがよしなに取り計らってくれるので問題にはい。
  
-は、この差どこ吸収せるか言ったら、うファイルシステムしかない。+しかし、共有フォルダのアクセスに関しては、忖度するとなくリクエストされたファイルパスそのままサーバに渡しているようだ。ゆえにサーバ側そのあたりが考慮れてない、意図しファイルが見つかないという事になる。Sambaの''case sensitive''オプションはまさにその辺の制御に関するオプションなのだ。''case sensitive=yes''にするといことは、''\\Server\Data\FILE.dat''と''\\Server\data\file.dat''は別のファイル扱いになるということで、/-手抜き-/アプリらすれば、case-insensitiveら見えてたファイルが見つからなくなるこれでは使い物にならない((実際、某有名3Dモデリングソフトでアセットファイルが突然見えなくなるという現象に遭遇している))
  
-幸いにしてZFSに''casesensitivity''とい、その名の通りのプロパティが用意されている。デフォルト値は言うまでもなく''casesensitive''であ+===== でか =====
  
-Windowsと共有は''caseinsensitive''なFSを新たに作って行うが良いだろう。設定値はcaseinsensitiveだが、挙動としてはcase-preservingになるようだ。ちなみに、''mixed''は使いどころがよくわからない挙動になるので使わない方が無難(一応、Windowsを想定した挙動らしいんけど…)+そこでZFSの''casesensitivity''プロパティ登場だ。
  
-もそもSambaがファイルをキャッシュせずファイル作成毎に全舐めしてしている恐らく対象フォルダに対する変更をSamba側で検知する仕組みがないからだと思う。Sambaがファイルを作成しようとしたまさにその時、同名のファイルがサーバのローカル作られたり別のァイがリネームされたりする可能性があるため、キャッシュでファイル名のユニーク性を担保きないという判断だと思われる。+名の通り、ファイル名の大文字/小文字取り扱いに関するプパティで、ト値''casesensitive''る。
  
-一方、ファイルシステムレベルのような変更の検出とアトミック性・ユニーク性が保証された素敵な仕組あるハズだから、アプリ側でファイル名全比較を行うより効率的んじゃねってう目論見+これを''caseinsensitive''にしてやれば大文字/小文字を区別しないようにファイルシステムが処理するようにる。"insensitive"とはなっているけど挙動としては"preserving"のようだ。ちなみに、''mixed''というのもあるが、使いどころがよくわからない挙動なで指定しない方が無難(一応、Windowsを想定した挙動らしいんだけど…)
  
-結論としてはSambaとZFSで以下の設定を行う。+残念ながら、というか性質を考えたら仕方ないけど、本プロパティはFS作成時にしか指定できない。既に問題が起きてしまっている場合は、''caseinsensitive''なFSを新たに作り、''casesensitive''なFSの方からファイルコピーして移行するしかない。(zfs send/recvではプロパティが引き継がれるので意味がない。) 
 + 
 +そのうえでSamba側の''case sensitive=yes''としてやれば、smbdの負荷問題は解決する。 
 + 
 +Sambaがファイル作成時にファイル名を全舐めしてしているのは、対象フォルダに対する変更をSamba側で検知する術がないからだと思われる。Sambaがファイルを作成しようとしたまさにその時、同名のファイルがサーバのローカルで作られたりする可能性があるから、キャッシュではファイル名のユニーク性を担保できず、都度確認せざるを得ないのだろう。 
 + 
 +一方、ファイルシステムレベルなら、ファイル名の一意性やアトミック性の保証が効率的に行えているだろうという目論見。 
 + 
 +===== 結論 ===== 
 + 
 +結論としてはSambaとZFSで以下の設定を行うと幸せになれるZFSじゃない人はスマン…
  
   * ZFS   * ZFS
     * ファイル共有用にcasesensitivity=caseinsensitiveなFSを作る<code>     * ファイル共有用にcasesensitivity=caseinsensitiveなFSを作る<code>
-zfs create -o casesnsitivity=caseinsensitive ztank/path/to/cifs</code>+zfs create -o casesnsitivity=caseinsensitive ztank/path/to/cifs 
 +</code>
   * Samba   * Samba
     * ファイル名の扱いをcase-sensitiveにする<code>     * ファイル名の扱いをcase-sensitiveにする<code>
  • blog/2018/2018-07-03.txt
  • 最終更新: 2021-05-17 09:45
  • by Decomo