Linux は日々進化を続けており、Ubuntu や Fedora など、ユーザが特に何もしなくともドライブの種類に合わせて最適な設定を行ってくれるディストリビューションも増えてきました。
しかし、 Arch や Gentoo などの一部のディストリでは自分で設定しなければ十全にドライブの性能を引き出せません。こういったディストリビューションは自分で入れない限り余計なプログラムをインストールしないので素のままでも十分に快適なことがほとんどですが、ちょっとしたチューニングを行うことを読み書き速度を改善させることができる。
最適化設定
パーティショニング
最初に筆者のPC環境をご紹介。SSDとHDD 混在している状態だ。
SSD にはブートパーティションとルートパーティション。 バックアップデータや大きなファイルは HDD。
TRIMの設定
先述したTRIMの設定を行うことによって削除領域を予約しパフォーマンスの低下を防ぐ。
TRIM に SSD 本体が対応しているか確認する
lsblk
コマンドを用いて各ドライブがTRIMに対応しているかどうか確認する
$ lsblk --discard
実行結果。DISC-GRAN
とDISC-MAX
のパラメータを確認し0以外ならば、ドライブはTRIMをサポートしていることになる。
NAME DISC-ALN DISC-GRAN DISC-MAX DISC-ZERO
sda 0 512B 2G 0
├─sda1 0 512B 2G 0
├─sda2 0 512B 2G 0
└─sda3 0 512B 2G 0
sdb 0 0B 0B 0
├─sdb1 0 0B 0B 0
├─sdb2 0 0B 0B 0
└─sdb3 0 0B 0B 0
fstrim で定期的に TRIM を適用する
/etc/fstab
に discard
マウントフラグを記述することで TRIM を有効にする方法もある。しかし書き込みが行われるたびにTRIMコマンドを実行するためストレージのパフォーマンスがかえって低下する恐れがある。
現在多くのディストリビューションで Systemd を使って定期的に TRIMコマンドを適用する方法が推奨されている。
# systemctl enable fstrim.timer
正常にコマンドが実行されればTRIMタイマーのシンボリックリンクが作成され、起動時に fstrim.timer
サービスが作動するようになる。
Created symlink /etc/systemd/system/timers.target.wants/fstrim.timer → /usr/lib/systemd/system/fstrim.timer.
fstrim が稼働しているか確認・ステータスを表示
下記のコマンドで fstrim サービスのステータスを確認することができる。
# systemctl status fstrim
実行結果。Loaded
がloaded
になっていれば正しく設定されていることになる。さらに直近のTRIMログが表示される。3月17日の22時ごろに /etc/fstab
からデバイス情報を読み込み、 /dev/sda1
(ブートパーティション)と /dev/sda3
(ホームパーティション)に対しTRIMを実行して成功している。
systemd 上で稼働しているすべてのタイマーを表示するコマンド。
$ sudo systemctl list-timers --all
I/O スケジューラーの変更
I/OスケジューラはブロックI/O処理を効率化させる仕組み。I/Oリクエストの処理する順番を入れ替えることにより、スループット(処理速度)を向上させたり特定の処理を優先的に実行させることができる。
2023年現在、LinuxカーネルがサポートしているI/Oスケジューラは mq-deadline
kyber
bfq
none
となっている。
Ubuntu が SSD ではデフォルトで none
に移行している。Fedora などはまだ bfq
を使っているところを見るに、まだ業界内のコンセンサスは得られていないようだ。
しかし、高速なドライブで I/O リクエストの入れ替え処理の必要性が疑問視されるようになったら none
に移行していく可能性も考えられる。
mq-deadline | すべてのI/Oリクエスト処理に制限時間を設けるスケジューラ。特定の処理でシステムがスタックすることを防ぐことができる。単純なスケジューラだが設計思想的にはHDDを意識した作りとなっており、高速でも低速なドライブでもイケるバランスが良いスケジューラだと考える。 |
kyber | 読み込みと同期、それぞれの待ち時間のみで構成されているシンプルなスケジューラ。どちらかといえば高速なデバイスに適している。 |
bfq | CFQのマルチキュー対応版でI/Oリクエストをなるべく公平な時間で処理しようとする。リクエストの入れ替えを頻繁に行うのでシステムへの負荷は比較的高い。スループットを犠牲にしてリスポンスを重視しているのでHDDなどの低速なドライブに適している。 |
none | 全くスケジューリングを行わないスケジューラ。そのままリクエストをデバイスに送るのでシステムへの負荷は最小限。スループット高速なNVMeなどに適している。HDDや低速なSSDだとリクエストがスタックしてプチフリなどが起こってしまう可能性があるので注意。 |
現在のI/Oスケジューラの確認
下記のコマンドでシステムに接続されているすべてのデバイスが使っているI/Oスケジューラを確認することができる。
$ cat /sys/block/sd*/queue/scheduler
実行結果。現在使われているスケジューラは[ ]
で囲われている。Arch Linuxの場合はBFQが初期設定になっている。
mq-deadline kyber [bfq] none
mq-deadline kyber [bfq] none
SSDとHDDの混在環境での設定
SSD と HDD 両方を使ったシステムの設定がしたいので udev
にルールを設定する。
$ sudoedit /etc/udev/rules.d/60-schedulers.rules
以下ルール作例。回転しないドライブは none
に設定する。
ACTION=="add|change", KERNEL=="sd[a-z]", ATTR{queue/rotational}=="0", ATTR{queue/scheduler}="none"
fstab マウントフラグを変更
noatime
noatime
マウントオプションを加えることで atime
情報の更新を止めます。
relatime
でも notime
とさほどパフォーマンスの違いはなく、体感もできませんが書き込み量を減らすことができます。 notime オプションに変えると正常に動かなくなるプログラムがあるそうですが、今まで著者は HDD に noatime
フラグを付けても問題が起きたことがなかったのと、Debian Wiki でも HDD に付けても大丈夫だと書いてあったのでOKだと判断してます。
詳しくは下の記事をご覧ください。
万が一、動かなくなったプログラムがありましたら元に戻しましよう。
discard=async
$ sudo nano /etc/fstab
# SDD
# /dev/sda1
UUID=********** /boot vfat default 0 2
# /dev/sda2
UUID=********** / ext4 defaults,noatime 0 1
# /dev/sda3
UUID=********** /sdata ext4 defaults,noatime 0 2
### HDD ###
# /dev/sdb1
UUID=********** /var ext4 defaults,noatime 0 2
# /dev/sdb2
UUID=********** /home ext4 defaults,noatime 0 2
ファイルシステムの更新後は initramfs イメージの設定をアップデートします。
$ sudo update-initramfs -u -k all
おわり
コメント