start

SambaとZFSで大量のファイルを扱う時はcase-sensitiveを最適化する

同一フォルダに大量のファイルがあるとSambaが超遅くなる問題、自分なりの知見が得られたのでメモ。結果だけ知りたい人は最後までスクロールしてくだしあ。

ことの発端は、数万個のファイルがあるフォルダをSambaのファイルサーバにコピーすると、速度が10kB/s前後まで低下する現象に見舞われた。速度はコピーが進むごとに低下し、比例してsmbdのCPU占有率が上がるというのが特徴。サーバ上で直接コピーすると何の問題もない。

調査を進めると、Sambaはファイル名の重複チェックのため、ファイル作成時に作成先フォルダ内の全ファイル名を検査することが分かった。この時に行われる、ファイル名の大文字/小文字変換と比較処理がボトルネックとなっているようだ。Windowsでは歴史的にファイル名の大文字/小文字を区別しない1)が、UNIX系ではOS/ファイルシステム共に大文字/小文字を区別することが多い。このWindowsとUNIXの違いをSambaで吸収してやる必要があるわけだ。

プロファイルしたわけでもソースコードを見たわけでもないので確証はないが、Sambaのドキュメントに「ディレクトリに大量のファイルがある特殊なケースでは、case sensitiveをyesにせよ」(抄訳)と書かれており、ファイルコピーの進捗にあわせ指数関数的に速度が落ちる(CPU負荷が上がる)という挙動から、当たらずとも遠からずだと思う。

ではcase sensitive = yesにすれば万事解決かといえば、そう簡単な話ではない。

前述の通りWindowsはFS的にはcase-sensitiveないしcase-preservingだが、表面的にはcase-insensitiveとして振る舞う。この仕様に胡坐をかき、ファイルパスを内部的に大文字または小文字に変換して扱うアプリケーションが少なくない。例えば、本来のファイルパスはC:\Data\FILE.datにもかかわらず、アプリケーション内部ではc:\data\file.datとして扱うことが往々にある。(自分もそういう処理をつい書いちゃうんだけど(;'∀'))

ローカルのファイルに対してなら、Windowsがよしなに取り計らってくれるので問題にはならない。

しかし、共有フォルダのアクセスに関しては、忖度することなくリクエストされたファイルパスをそのままサーバに渡しているようだ。ゆえにサーバ側でそのあたりが考慮されてないと、意図したファイルが見つからないという事になる。Sambaのcase sensitiveオプションは、まさにその辺の制御に関するオプションなのだ。

case sensitive=yesにするということは、\\Server\Data\FILE.dat\\Server\data\file.datは別のファイル扱いになるということで、手抜きアプリからすれば、case-insensitiveなら見えていたファイルが見つからなくなる。これでは使い物にならない2)

そこでZFSのcasesensitivityプロパティの登場だ。

その名の通り、ファイル名の大文字/小文字の取り扱いに関するプロパティで、デフォルト値はcasesensitiveである。

これをcaseinsensitiveにしてやれば、大文字/小文字を区別しないようにファイルシステムが処理するようになる。“insensitive”とはなっているけど、挙動としては“preserving”のようだ。ちなみに、mixedというのもあるが、使いどころがよくわからない挙動なので指定しない方が無難(一応、Windowsを想定した挙動らしいんだけど…)。

残念ながら、というか性質を考えたら仕方ないけど、本プロパティはデータセット作成時にしか指定できない。既に問題が起きてしまっている場合は、caseinsensitiveなデータセットを新たに作り、casesensitiveの方からファイルコピーで移行するしかない。(zfs send/recvではプロパティが引き継がれるので意味がない。)

そのうえでSamba側のcase sensitive=yesとしてやれば、smbdの負荷問題は解決する。

Sambaがファイル作成時にファイル名を全舐めしてしているのは、対象フォルダに対する変更をSamba側で検知する術がないからだと思われる。Sambaがファイルを作成しようとしたまさにその時、同名のファイルがサーバのローカルで作られたりする可能性があるから、キャッシュではファイル名のユニーク性を担保できず、都度確認せざるを得ないのだろう。

一方、ファイルシステムレベルなら、ファイル名の一意性やアトミック性の保証が効率的に行えているだろうという目論見。

結論としてはSambaとZFSで以下の設定を行うと幸せになれる。ZFSじゃない人はスマン…

  • ZFS
    • ファイル共有用にcasesensitivity=caseinsensitiveなFSを作る
      zfs create -o casesnsitivity=caseinsensitive ztank/path/to/cifs

  • Samba
    • ファイル名の扱いをcase-sensitiveにする

      case sensitive = yes
      case preserve = yes
      short preserve case = yes

(2021-05-17 追記)

上記設定について、以前はcase preserve, short preserve caseをnoとしていたが、yesの方が良さそうである。これらはファイル新規作成時のファイル名の大文字・小文字の取り扱いのオプションで、noだと大文字ないし小文字に変換されていまう(default caseの指定に因る。デフォルト値はlowerなので小文字になる。)


1)
ファイルシステム上は区別して保存されている。この差はAPIで吸収され傍目からはcase-preservingのように見える
2)
実際、某有名3Dモデリングソフトでアセットファイルが突然見えなくなるという現象に遭遇している

EmacsのCompletionsバッファを新規ウィンドウではなく既存ウィンドウに表示させる

通常、EmacsでTAB補完の時とかに表示されるCompletionsバッファは、フレーム3)下部を分割した一時的なウィンドウ4)として表示される。言葉じゃわかりにくいので、スクショを張っとくと↓こんな感じね。 こっちは嫌(Completionsウィンドウが独立に開く)

自分のEmacsの使い方は垂直分割した2つのウィンドウ表示が基本で、Completionsバッファは非アクティブな方のウィンドウに出て欲しい。その方が補完候補の一覧性が圧倒的だし、ウィンドウがパカパカしないのがいい。スクショを張(ry こっちがいい(Completionsバッファが非アクティブなウィンドウに表示される)

ここの回答に載ってるelispを参考に、ウィンドウが1つの時はウィンドウ幅に応じて分割方向を変えるようにしてみた。

(defun display-on-side (buffer &optional not-this-window frame)
  (let* ((window (or (minibuffer-selected-window)
                     (selected-window)))
         (display-buffer-function nil)
         (pop-up-windows nil))
    (with-selected-window (or window (error "display-on-side"))
      (when (one-window-p t)
        (if (> (window-pixel-width) (window-pixel-height))
            (split-window-horizontally)
          (split-window-vertically))
        )
      (display-buffer buffer not-this-window frame))))
(setq display-buffer-function 'display-on-side)

水平2分割した状態で使うと、非アクティブなウィンドウの方がCompletions表示時に勝手にリサイズされる問題があったりする…。自分は水平分割使わないので放置してます、すいません。えらいひと直して教えてください。


3)
Emacs用語としてのフレーム
4)
Emacs用語としてのウィンドウ

NETGEARのAdmin Mode項目はLAGの有効/無効を切り替えるものらしい

ネットギアのL2スイッチのLAG設定に「Admin Mode」なる項目がある。下図はXS512EMのWebGUIのもの。

 XS512EMのLAG設定画面

LAGの管理モードの有効無効って何よ?と思い、WebGUIのヘルプを見るも“Admin Mode - Select Enable or Disable to set the Admin Mode.”としか書いておらず、全く役に立たないという…。いろいろググってみて、確実な情報は見つけられなかったんだけど、結局のところLAGのオン/オフを切り替える設定っぽい。言わずもがな、EnableがLAG有効でDisableが無効ね。

機種違いの回答ではあるが、公式フォーラムでは、Enableだとトラフィックが流れてDisableだと全く流れないとされているが、少なくともXS512EMに関してはLAG自体の有効/無効にしか影響してなさそうだ。実際試しても、Admin Modeの状態を問わずパケットは流れる一方、LAGを設定済みの状態でDisableならLAG StatsuはDownのまま、Enableにして初めてUpになった。

フォーラム回答の挙動は、マネージドスイッチ以上で設定できるポート毎のAdmin Modeの解説なんじゃないかって気がする。いずれにせよ、もっと分かりやすい項目名にしてくださいよとしか……

東芝のエンプラ向けSSD THNSNJ960PCSZ (HK3R2 960GB) 購入

これまでSSDはIntel DCシリーズを買ってきたが、今回はTOSHIBAの読み出し重視型エンタープライズ向けSSD THNSNJ960PCSZを買ってみた。例によって例によって中古。新品じゃ高くて買えませんからね。それでもっていつものごとくベンチ。今回もSATA接続。

-----------------------------------------------------------------------
CrystalDiskMark 6.0.0 x64 (C) 2007-2017 hiyohiyo
                          Crystal Dew World : https://crystalmark.info/
-----------------------------------------------------------------------
* MB/s = 1,000,000 bytes/s [SATA/600 = 600,000,000 bytes/s]
* KB = 1000 bytes, KiB = 1024 bytes

   Sequential Read (Q= 32,T= 1) :   552.067 MB/s
  Sequential Write (Q= 32,T= 1) :   519.592 MB/s
  Random Read 4KiB (Q=  8,T= 8) :   377.485 MB/s [  92159.4 IOPS]
 Random Write 4KiB (Q=  8,T= 8) :   353.540 MB/s [  86313.5 IOPS]
  Random Read 4KiB (Q= 32,T= 1) :   269.954 MB/s [  65906.7 IOPS]
 Random Write 4KiB (Q= 32,T= 1) :   231.575 MB/s [  56536.9 IOPS]
  Random Read 4KiB (Q=  1,T= 1) :    35.232 MB/s [   8601.6 IOPS]
 Random Write 4KiB (Q=  1,T= 1) :    91.411 MB/s [  22317.1 IOPS]

  Test : 4096 MiB [D: 0.0% (0.2/894.3 GiB)] (x5)  [Interval=5 sec]
  Date : 2018/04/26 22:49:50
    OS : Windows 10 Professional [10.0 Build 16299] (x64)
    TOSHIBA THNSNJ960PCSZ

ベンチ結果もS.M.A.R.T.情報も取り立てて何かあるという事もなく。強いて言えば、総読込量より総書込量が圧倒的に多いことくらい。この使い方ならHK3Eシリーズの方が合ってるんじゃねー?>前のオーナー。まぁ、このくらいの使い方ならどっちでも変わらんだろうけどさ。

THNSNJ960PCSZの耐久性はと言うと、1 DWPD5)──つまり定格寿命たる5年間、毎日1回ドライブ全体に書き込むとTBWに達するということだから5×365×960=1752000GB、つまりTBWは1.752PBである。公称耐久性はDC S3500以上、S3700未満ということになる。そう考えるとDC S3700シリーズの10 DWPDって半端ない耐久性だよなぁ…。東芝のSSDでいえば書き込み重視型のPXシリーズが同等ラインっぽい。

主に自宅鯖の仮想マシン置き場として使う予定。取り付けたら何故かアクセスランプが点きっぱなしなんだけど…w


5)
Drive Write Per Day

ZFSが自動マウントされない時はzfs_enable="YES"になっているか確認する

FreeBSDにおいて、起動時にルートプール以外のZFSファイルシステムが自動でマウントされない時は、/etc/rc.confzfs_enable=“YES”があるかどうかを確認する。この指定がなくとも、ルートプール=システムが入っているプールは自動マウントされるので、なかなか問題に気づきにくい。自動でマウントされないFSのcanmountmountpointプロパティを見ても問題ないし、原因が判るまで苦労したんだぜ★

インストーラに頼らず手動でFreeBSDをインストールした場合なんかは、特に注意が必要だ。

  • start.txt
  • 最終更新: 2022-07-27 15:26
  • by Decomo