差分

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

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

両方とも前のリビジョン 前のリビジョン
次のリビジョン
前のリビジョン
blog:2018:2018-07-03 [2018-07-17 11:49]
Decomo
blog:2018:2018-07-03 [2021-05-17 09:45] (現在)
Decomo
行 1: 行 1:
-====== SambaとZFSで大量のファイルを扱う時はcase-sensitiveの組み合わせを最適化する ======+====== SambaとZFSで大量のファイルを扱う時はcase-sensitiveを最適化する ======
  
 [[blog:2017:2017-08-04|同一フォルダに大量のファイルがあるとSambaが超遅くなる]]問題、自分なりの知見が得られたのでメモ。結果だけ知りたい人は最後までスクロールしてくだしあ。 [[blog:2017:2017-08-04|同一フォルダに大量のファイルがあるとSambaが超遅くなる]]問題、自分なりの知見が得られたのでメモ。結果だけ知りたい人は最後までスクロールしてくだしあ。
  
-まずはおさらい+===== おさらい =====
  
 ことの発端は、数万個のファイルがあるフォルダをSambaのファイルサーバにコピーすると、速度が10kB/s前後まで低下する現象に見舞われた。速度はコピーが進むごとに低下し、比例してsmbdのCPU占有率が上がるというのが特徴。サーバ上で直接コピーすると何の問題もない。 ことの発端は、数万個のファイルがあるフォルダをSambaのファイルサーバにコピーすると、速度が10kB/s前後まで低下する現象に見舞われた。速度はコピーが進むごとに低下し、比例してsmbdのCPU占有率が上がるというのが特徴。サーバ上で直接コピーすると何の問題もない。
  
-調査を進めると、ファイル作成時Sambaはファイル名の重複チェックのため、作成先フォルダ内の全ファイル名を検査することが分かった。この時に行われるWindowsのファイル名規則(FS上は大文字/小文字を区別するが、一般的なファイルアクセス上は区別しナンチャッテ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小文字に変換して扱うアプリケーションが少なくない。例えば、本来のファイルパスは''C:\Data\FILE.dat''にもかかわらず、アプリケーション内部では +前述の通りWindowsはFS的にはcase-sensitiveないしcase-preservingだが、表面的にはcase-insensitiveとして振る舞う。この仕様に胡坐をかき、ファイルパスを内部的に大文字または小文字に変換して扱うアプリケーションが少なくない。例えば、本来のファイルパスは''C:\Data\FILE.dat''にもかかわらず、アプリケーション内部では''c:\data\file.dat''として扱うことが往々にある<fc #c0c0c0>(自分もそういう処理をつい書いちゃうんだけど(;'∀'))</fc>
-''c:\data\file.dat''としてアクセスすることが往々にある<fc #c0c0c0>(自分もそういう処理をつい書いちゃうんだけど(;'∀'))</fc>。ローカルのファイルに対してなら、これでも問題はない+
  
-しかし、サ共有に対してアプリから渡されたファイルパスをそのまま渡しているうだ。故にサーバ側がその辺を考慮た処理ってないと、ファイルが見つからないという事になる。Sambaの''case sensitive''オプションは、まさにその辺の制御を設定するオプションなのだ。こをyesにすということは、\\Server\Data\FILE.datと\\Server\data\file.datは別ファイルと見なされる、ということだ。アプリからすれば、\\Server\Data\FILE.datが見つからないということなる。これで使い物にならない。+カルのファイルに対してならWindowsがよし取り計らってれるので問題にはならない。
  
-どうするか。ZFSの''casesensitivity''ロパティ登場だ。+しかし、共有フォルダのアクセスに関して、忖度することなくリクエストされたファイルパスをそのままサーバに渡しているようだ。ゆえにサーバ側でそのあたりが考慮されてないと、意図したファイルが見つらないという事になるSambaの''case sensitive''ションは、まさにその辺の制御に関するオプションなのだ。
  
-お察しの通りその名の通りのプロパティで、デフォルト値は''casesensitive''である。これを''caseinsensitive''してやればいい。insensitiveという名付けではあるが、挙動してpreservingのようだ。ちなみに、''mixed''いうもあが、使ろがよくわからない挙動指定しない方が無難(一応Windowsを想定した挙動らしいんだけど…)。+''case sensitive=yes''するというとは、''\\Server\Data\FILE.dat''''\\Server\data\file.dat''は別ファイル扱いになとで、<del>手抜き</del>アプリからすれば、case-insensitiveら見えてたファイルが見つからくなる。これは使い物にならない((実際某有名3Dモデリングソフトでアセットファイルが突然見えなくなるという現象に遭遇る))
  
-本プロパティFS作成時にし指定できないため、Windows共有用のFSを新規に作り、Sambaで共有フォルダに仕立て上げるのがよいだろう。+===== でどうするか =====
  
-Sambaがファイル名をキャッシュせずファイル作成毎に全舐めしてしているのは、恐らく対象フォルダに対する変更をSamba側検知する仕組みがないからだと思う。Sambaがファイルを作成しようとしたまさにその時、同名のファイルがサーバのローカルで作られたり、別のファイルがリネームされたりする可能性があるため、キャッシュではファイル名のユニーク性を担保できないのだろう+そこZFS''casesensitivity''パティ登場だ。
  
-一方、ファイルシステムレベルのような変更検出ク性・ユニク性保証された素敵な仕組みがあるハズだから、アプリ側でファイル名の全比較より効率的なんじゃねっていう目論見。+その名の通りファイル名の大文字/小文字の取り扱いに関するプロパティで、デフォルト値は''casesensitive''である。 
 + 
 +これを''caseinsensitive''にしてやれば、大文字/小文字を区別しないようにファイルシステムが処理するようにる。"insensitive"とはなっているけど挙動としては"preserving"のようだ。ちみに、''mixed''というもあるが、使いどころがよくわからない挙動なので指定しない方が無難(一応、Windowsを想定した挙動らしいんだけど…)。 
 + 
 +残念ながら、いうか性質を考えたら仕方ないけど、本プロパティはデータセッ作成時にしか指定できない。既に問題が起きてしまっている場合は、''caseinsensitive''なデータセトを新たに作り、''casesensitive''の方からファイルコピで移行するしかない。(zfs send/recvではプロパティ引き継がれるので意味がない。) 
 + 
 +そのうえでSamba側の''case sensitive=yes''としてやれば、smbdの負荷問題は解決する。 
 + 
 +Sambaがファイル作成時にファイル名を全舐めしてしているのは、対象フォルダに対する変更をSamba側で検知する術がないからだと思われる。Sambaがファイルを作成しようとしたまにその時、同名のファイルがサーバのローカルで作られたりする可能性があるから、キャッシュファイル名のユニーク性担保できず、都度確認せざるを得ないのだろ。 
 + 
 +一方、ファイルシステムレベルなら、ファイル名の一意性やアトミック性の保証が効率的に行えいるだろうという目論見。 
 + 
 +===== 結論 =====
  
 結論としてはSambaとZFSで以下の設定を行うと幸せになれる。ZFSじゃない人はスマン… 結論としてはSambaとZFSで以下の設定を行うと幸せになれる。ZFSじゃない人はスマン…
行 37: 行 48:
     * ファイル名の扱いをcase-sensitiveにする<code>     * ファイル名の扱いをcase-sensitiveにする<code>
 case sensitive = yes case sensitive = yes
-case preserve = no +case preserve = yes 
-short preserve case = no+short preserve case = yes
 </code> </code>
  
 +<WRAP center round info 60%>
 +(2021-05-17 追記)
 +
 +上記設定について、以前はcase preserve, short preserve caseをnoとしていたが、yesの方が良さそうである。これらはファイル新規作成時のファイル名の大文字・小文字の取り扱いのオプションで、noだと大文字ないし小文字に変換されていまう(default caseの指定に因る。デフォルト値はlowerなので小文字になる。)
 +</WRAP>
 +
 +
 +===== 参考サイト =====
 +
 +  * [[https://www.samba.org/samba/docs/current/man-html/smb.conf.5.html#NAMEMANGLINGSECT|smb.conf — The configuration file for the Samba suite]]のNAME MANGLINGセクション
  • blog/2018/2018-07-03.1531795752.txt.gz
  • 最終更新: 2018-07-17 11:49
  • by Decomo