LinuxのSSD設定

# 概要

SSDで寿命とかパフォーマンスを改善するために設定しておいた方が良い点のまとめです。
よくある系のネタですが、久しぶりにSSD設定見なおしたら勘違いしてた点がいくつかあったので備忘を兼ねて残します。目次見て「こんなの常識だよね」って思った方はスルーしてくださいm(_ _)m

# 基本

* firmwareを最新化する
* kernel/osはなるべく新しいものを使う
* 新しいファイルシステムを使う(多分今のところext4が一番良さそう)
* swapしないようメモリを沢山積む

# TRIMを使う
## TRIMとは
SSD上のデータは削除しても削除マークが付くだけで削除されません。
この状態のブロックにデータを書き込む場合、一度完全に消去してから書き込みます。
TRIMコマンドはOS上のファイルが不要になったことをSSDに伝えて明示的にデータの消去を行うコマンドです。

### メリット
TRIMを使わない場合、以前データを書き込んだブロックに再度データを書き込む場合、実際にデータを書き込む際に消去が行われるため、まっさらなブロックに書き込む場合と比べて速度が低下します。
これはSSDを使えば使うほど起こりやすくなります。
TRIMコマンドを使うとこの速度低下を緩和することができます。

### デメリット
HDDやTRIMなしのSSDの場合、rmでファイルを削除しても復旧可能な可能性があります。
しかし、TRIMコマンドを使った場合、データを完全に削除するため[データ復旧が不可能になります。](http://www.logitec.co.jp/data_recovery/column/vol_005/)
よってバックアップがより重要になると思います。

## TRIMに対応しているか確認
TRIMを使うにはディスクとOS・ファイルシステムが対応している必要があります。
### diskが対応しているか確認
hdparmの結果で判断できます。

```bash
sudo hdparm -I /dev/sda | grep -i trim
   *	Data Set Management TRIM supported (limit 8 blocks)
```

### 対応しているファイルシステム
新しめのKernelだと、ext4,xfs,btrfs等は対応しているようです。
Kernelのバージョン等で変わるので実際に自分の環境で対応してるか調べてから設定してください。

## TRIMコマンドを使う
2つやり方があります。

### マウントオプションにdiscardを追加する
fstabとかでマウントオプションにdiscardを追加します。
これだと書き込み時に自動的にTRIMしてくれます。
が、書き込みが遅くなるのであまりおすすめできません。

### fstrimコマンドを使う(多分こっちが推奨)
マウントポイントを指定してfstrimコマンドを実行すると明示的にTRIMできます。
こちらの方法ではコマンド実行するまでの間ならrmしたファイルの復旧ができる可能性もあります。

```
sudo fstrim -v /
/: XXXXX bytes were trimmed
```

何バイトがTRIMされたかが表示されます。
2回目以降の実行では初回よりも少ない数字が表示されるはずです。([btrfsでは毎回フルで走るようです](http://forums.fedoraforum.org/showpost.php?p=1568303&postcount=2))
ただし、リブートした場合や対象のドライブをリマウントした場合はリセットされてしまいます。
よって、サーバ機等、常時起動しているものではこちらの方法をcronとかで設定して定期的に実行すると良いでしょう。
systemdであれば、`systemctl enable fstrim.timer`ですね。

# IOスケジューラをdeadlineに変える
IOスケジューラはその名の通り、IOのスケジューリングをしてくれるものです。
HDDのデフォルトはCFQ(Completely Failr Queueing)というスケジューラでプロセスごとにIOのキューを持ち、
プロセスごとに公平にIOできるようにスケジューリングします。
SSDだと通常のパフォーマンスはnoop(IOのスケジューリングを何もしない)が良いらしいんですが、[大きいファイルの読み書き等が発生した場合に他のタスクに多大な影響が出るため、deadlineが良いようです。](https://wiki.debian.org/SSDOptimization#Low-Latency_IO-Scheduler)
deadlineは各プロセスでIO要求があった場合、IO待ち時間に最大値が割り当てられ、それを過ぎたものから優先的に処理するようなものらしいです。

* 以下のようになっていればdeadlineになっています。

```
cat /sys/block/sda/queue/scheduler
noop [deadline] cfq
```

sdaは実際のssdのドライブに書き換えてください。

* deadlineになっていなければechoで上記のファイルにdeadlineを書いてあげましょう

```
echo "deadline" | sudo tee /sys/block/sda/queue/scheduler
```

* 恒久的に変える場合はgrubの設定ファイルを書き換えます。

```bash:/etc/default/grub
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash elevator=deadline"
```

elevator=deadlineが追加する点です。
変更後は`update-grub`(ubuntu14.04)または`grub2-mkconfig --output=/boot/efi/EFI/fedora/grub.cfg`(Fedora21)をしておきましょう。

* ちなみにOSがディスクをssdとして認識していればデフォルトでdeadlineになってます。
OSがssdを認識しているかは以下で確認できます。

```
cat /sys/block/sda/queue/rotational
0
```

結果が0ならSSDとして認識されています。

# マウントオプションにnoatime付ける
そのまんまですね。
noatimeはファイルが最後にアクセスされた時間を記録しないようにするオプションです。
これがファイルにアクセスする度に毎回書かれるとディスク寿命とパフォーマンスに影響があります。
ただし、[一部のソフトウェアでは不具合が出ることがあるようです。](http://linux.koolsolutions.com/2009/01/30/installing-linux-on-usb-part-4-noatime-and-relatime-mount-options/)
その場合はrelatimeに変えましょう。

# swapをオフにする

* `/etc/sysctl.conf`に`vm.swappiness=1`を書く。
昔は0で良いと思ってたんですが、[挙動が変わったみたいです。](http://www.mysqlperformanceblog.com/2014/04/28/oom-relation-vm-swappiness0-new-kernel/)
* そもそも`swapoff -a`するかfstab編集して全くswapしないようにしてしまっても良いでしょう。

# tmpfs(RAMディスク)を使う

/var/log等の一時ファイル系はtmpfsかRAMディスク(いずれもメモリ上のファイルシステム)に書くようにすると良いでしょう。

# 参考

記事の中で触れたもの以外では以下を参考にさせて頂きました。

* http://xfs.org/index.php/FITRIM/discard
* http://www.makeuseof.com/tag/optimize-linux-ssds/
* http://blog.neutrino.es/2013/howto-properly-activate-trim-for-your-ssd-on-linux-fstrim-lvm-and-dmcrypt/

他にもあったら追記します。