# filebench
* [公式Wiki](https://github.com/filebench/filebench/wiki)
* [公式Repository](https://github.com/filebench/filebench/)
色々なパターンでI/O負荷がかけられるツール。WML(Workload Model Language) という言語で I/O の動作を定義して実行するらしい。
* [Workload model language](https://github.com/filebench/filebench/wiki/Workload-model-language)
それほど複雑ではなさそうなのであらかじめ付属している WML ファイルを見ながら自作もできそう。
あらかじめ例として色々な WML ファイルが付属している。
* [Predefined personalities](https://github.com/filebench/filebench/wiki/Predefined-personalities)
## WML ファイル
例えば `fileserver.f` というファイルはこんな感じ (コメントは削除してある)。
まずは実際の処理の定義内で使う変数定義。
```
set $dir=/tmp
set $nfiles=10000
set $meandirwidth=20
set $meanfilesize=128k
set $nthreads=50
set $iosize=1m
set $meanappendsize=16k
```
次にテスト全体で使うファイルセットを定義。
```
define fileset name=bigfileset,path=$dir,size=$meanfilesize,entries=$nfiles,dirwidth=$meandirwidth,prealloc=80
```
* ファイルセット名 (name): bigfileset
* パス (path): $dir 変数
* サイズ (size): $meanfilesize 変数 (平均ファイルサイズ)
* ファイル数 (entories): $nfiles 変数 (ファイルセットで作成できる最大ファイル数)
* ディレクトリごとのファイル数 (dirwidth): $meandirwidth 変数 (平均数。ファイルの合計数とこの指定から必要なディレクトリを計算する)
* テスト開始前に作成するファイル数 (realloc): 80 %
次はプロセスとスレッドを定義して、スレッド内で行う処理を順に定義。
```
define process name=filereader,instances=1
{
thread name=filereaderthread,memsize=10m,instances=$nthreads
{
```
スレッド (名前は filereaderthread) 数 (instances) が $nthreads (=50) のプロセス (名前は filereader) が 1 つ。スレッドは最初に処理用に 10MB のメモリを確保。
```
flowop createfile name=createfile1,filesetname=bigfileset,fd=1
flowop writewholefile name=wrtfile1,srcfd=1,fd=1,iosize=$iosize
flowop closefile name=closefile1,fd=1
flowop openfile name=openfile1,filesetname=bigfileset,fd=1
flowop appendfilerand name=appendfilerand1,iosize=$meanappendsize,fd=1
flowop closefile name=closefile2,fd=1
flowop openfile name=openfile2,filesetname=bigfileset,fd=1
flowop readwholefile name=readfile1,fd=1,iosize=$iosize
flowop closefile name=closefile3,fd=1
flowop deletefile name=deletefile1,filesetname=bigfileset
flowop statfile name=statfile1,filesetname=bigfileset
}
}
```
これは `flowop` の次にある命令を見れば大体やってくることわかるんじゃないかな。`fileset` で指定したファイルセット内で処理する。`fd` はたくさん処理しているファイルがある時に同じファイルに対して処理を行うことを保証するために指定。
残りはヘルプ。
```
echo "File-server Version 3.0 personality successfully loaded"
usage "Usage: set \$dir=
"
usage " set \$meanfilesize= defaults to $meanfilesize"
: (snip)
```
## インタラクティブ実行
上記のファイルを適当なディレクトリに `fileserver.f` として (必要な部分を変更して) 保存してインタラクティブに実行していく。(`/usr/share/filebench/workload` 内にあるファイルならパス指定は不要)
コマンド実行後、filebench のプロンプトに入るので `load` コマンドで WML ファイルをロード。
```
$ filebench
Filebench Version 1.4.9.1
13045: 0.000: Allocated 170MB of shared memory
filebench> load ./fileserver
```
すると、ヘルプが表示されるので必要に応じて変数を変更。
```
filebench> load ./fileserver
13045: 161.516: Illegal character at '.' on line 1
13045: 161.517: File-server Version 3.0 personality successfully loaded
13045: 161.517: Usage: set $dir=
13045: 161.517: set $meanfilesize= defaults to 131072
13045: 161.517: set $nfiles= defaults to 10000
13045: 161.517: set $nthreads= defaults to 50
13045: 161.517: set $meanappendsize= defaults to 16384
13045: 161.517: set $iosize= defaults to 1048576
13045: 161.517: set $meandirwidth= defaults to 20
13045: 161.517: run runtime (e.g. run 60)
filebench> set $dir=/data
filebench> set $nfiles=5000
```
そして時間を指定して `run` で実行。
```
filebench> run 60
13045: 266.678: Creating/pre-allocating files and filesets
13045: 266.685: Fileset bigfileset: 5000 files, 0 leafdirs, avg dir width = 20, avg dir depth = 2.8, 614.982MB
13045: 271.759: Removed any existing fileset bigfileset in 6 seconds
13045: 271.759: making tree for filset /data/bigfileset
13045: 271.769: Creating fileset bigfileset...
13045: 274.341: Preallocated 3973 of 5000 of fileset bigfileset in 3 seconds
13045: 274.355: waiting for fileset pre-allocation to finish
13080: 274.373: Starting 1 filereader instances
13081: 274.496: Starting 50 filereaderthread threads
13045: 275.558: Running...
13045: 335.607: Run took 60 seconds...
13045: 335.731: Per-Operation Breakdown
statfile1 13445ops 224ops/s 0.0mb/s 3.5ms/op 2173us/op-cpu [0ms - 1082ms]
deletefile1 13445ops 224ops/s 0.0mb/s 17.5ms/op 5470us/op-cpu [0ms - 1138ms]
closefile3 13451ops 224ops/s 0.0mb/s 0.0ms/op 1373us/op-cpu [0ms - 12ms]
readfile1 13473ops 224ops/s 28.7mb/s 52.3ms/op 20751us/op-cpu [0ms - 617ms]
openfile2 13481ops 224ops/s 0.0mb/s 6.4ms/op 2838us/op-cpu [0ms - 1107ms]
closefile2 13483ops 224ops/s 0.0mb/s 0.0ms/op 1334us/op-cpu [0ms - 31ms]
appendfilerand1 13492ops 225ops/s 1.7mb/s 50.9ms/op 17597us/op-cpu [0ms - 519ms]
openfile1 13492ops 225ops/s 0.0mb/s 4.1ms/op 2629us/op-cpu [0ms - 1107ms]
closefile1 13492ops 225ops/s 0.0mb/s 0.1ms/op 1740us/op-cpu [0ms - 63ms]
wrtfile1 13492ops 225ops/s 27.8mb/s 3.0ms/op 3680us/op-cpu [0ms - 317ms]
createfile1 13495ops 225ops/s 0.0mb/s 6.4ms/op 3711us/op-cpu [0ms - 1099ms]
13045: 335.731: IO Summary: 148241 ops, 2467.010 ops/s, (224/449 r/w), 58.2mb/s, 697us cpu/op, 48.0ms latency
13045: 335.731: Shutting down processes
```
このとき `/data` 以下には `bigfileset` というディレクトリ (ファイルセット名で作成) が作成され、その下に多数のディレクトリとファイルが作成される。
```
$ ls /data/bigfileset/
00000001 00000002 00000003 00000004 00000005
$ tree -d /data/bigfileset/
:(snip)
/data/bigfileset/
├── 00000001
│ ├── 00000001
│ ├── 00000002
│ ├── 00000003
│ ├── 00000004
│ ├── 00000005
│ │ ├── 00000001
│ │ ├── 00000002
│ │ ├── 00000003
│ │ ├── 00000004
│ │ ├── 00000005
│ │ └── 00000006
: (snip)
```
## 非インタラクティブモードで実行
引数で WML ファイルを指定して実行できるが、WML ファイル内に `run` コマンドの記述が必要。
末尾に
```
run 60
```
を追加して `-f ./fileserver.f` で指定。
```
$ sudo filebench -f fileserver.f
Filebench Version 1.4.9.1
13500: 0.000: Allocated 170MB of shared memory
13500: 0.001: Creating/pre-allocating files and filesets
13500: 0.017: Fileset bigfileset: 10000 files, 0 leafdirs, avg dir width = 20, avg dir depth = 3.1, 1240.757MB
13500: 0.321: Removed any existing fileset bigfileset in 1 seconds
13500: 0.321: making tree for filset /data/bigfileset
13500: 0.373: Creating fileset bigfileset...
13500: 4.512: Preallocated 7979 of 10000 of fileset bigfileset in 5 seconds
13500: 4.512: waiting for fileset pre-allocation to finish
13503: 4.524: Starting 1 filereader instances
13504: 4.600: Starting 50 filereaderthread threads
13500: 5.644: Running...
```