dm-writecacheを試す

dm-writecacheを試す

dm-writecacheとは

kernel 4.18でマージされたキャッシュの機能

docs.kernel.org www.admin-magazine.com manpages.ubuntu.com

以前から存在したdm-cacheはデフォルトだとwrite throughで読み取りもキャッシュしていた。 dm-writecacheではwrite backのみで書き込みのみをキャッシュして、読み取りは通常のページキャッシュに任せる仕様になっている

設定方法

環境

OSがUbuntu 22.04.1 LTSの RaspberryPi 4 4GBモデルでテストする。

ubuntu@ubuntu:~$ uname -a
Linux ubuntu 5.15.0-1013-raspi #15-Ubuntu SMP PREEMPT Mon Aug 8 06:33:06 UTC 2022 aarch64 aarch64 aarch64 GNU/Linux
ubuntu@ubuntu:~$ cat /etc/os-release
PRETTY_NAME="Ubuntu 22.04.1 LTS"
NAME="Ubuntu"
VERSION_ID="22.04"
VERSION="22.04.1 LTS (Jammy Jellyfish)"
VERSION_CODENAME=jammy
ID=ubuntu
ID_LIKE=debian
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"

対象ディスクのセットアップ

USBで接続したHDDにbrdで作成したブロックデバイスをキャッシュとして割り当てる。

まずキャッシュに使うデバイスをbrdで作成。サイズは2GBに設定。 rd_nrで作成するデバイスの数、rb_sizeでサイズを制御する。rb_sizeの単位はKBなのでGBをKBに変換して入力

sudo modprobe brd rd_nr=1 rd_size=2097152

2GBのディスクが作成される

ubuntu@ubuntu:~$ sudo fdisk -l
<中略>
Disk /dev/ram0: 2 GiB, 2147483648 bytes, 4194304 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes

これをキャッシュとして設定していく

最初にPVを作成

ubuntu@ubuntu:~$ sudo pvcreate /dev/sdb
  Physical volume "/dev/sdb" successfully created.
ubuntu@ubuntu:~$ sudo pvcreate /dev/ram0
  Physical volume "/dev/ram0" successfully created.
ubuntu@ubuntu:~$ sudo pvs
  PV         VG Fmt  Attr PSize   PFree
  /dev/ram0     lvm2 ---    2.00g   2.00g
  /dev/sdb      lvm2 ---  596.17g 596.17g

VGを作成

ubuntu@ubuntu:~$ sudo vgcreate cache-test /dev/ram0 /dev/sdb
  WARNING: Devices have inconsistent physical block sizes (4096 and 512).
  Volume group "cache-test" successfully created
ubuntu@ubuntu:~$ sudo vgs
  VG         #PV #LV #SN Attr   VSize   VFree
  cache-test   2   0   0 wz--n- 598.16g 598.16g

それぞれにLVを作成する

ubuntu@ubuntu:~$ sudo lvcreate -n hdd -L 20G cache-test /dev/sdb
  Logical volume "hdd" created.
ubuntu@ubuntu:~$ sudo lvcreate -n brd -l 100%FREE cache-test /dev/ram0
  Logical volume "brd" created.
ubuntu@ubuntu:~$ sudo lvs
  LV   VG         Attr       LSize  Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
  brd  cache-test -wi-a----- <2.00g
  hdd  cache-test -wi-a----- 20.00g

キャッシュの設定

両方のLVをdeactiveにしてキャッシュありに変換

ubuntu@ubuntu:~$ sudo lvchange -a n cache-test/hdd
ubuntu@ubuntu:~$ sudo lvchange -a n cache-test/brd
ubuntu@ubuntu:~$ sudo lvconvert --type writecache --cachevol brd cache-test/hdd
Erase all existing data on cache-test/brd? [y/n]: y
  Using writecache block size 512 for unknown file system block size, logical block size 512, physical block size 512.
  Logical volume cache-test/hdd now has writecache.
ubuntu@ubuntu:~$ sudo lvchange -a y cache-test/hdd

完成形

ubuntu@ubuntu:~$ sudo lvs
  LV   VG         Attr       LSize  Pool       Origin       Data%  Meta%  Move Log Cpy%Sync Convert
  hdd  cache-test Cwi-a-C--- 20.00g [brd_cvol] [hdd_wcorig] 0.00

後は普通にファイルシステムを作ってマウント

ubuntu@ubuntu:~$ sudo mkfs.ext4 /dev/cache-test/hdd
mke2fs 1.46.5 (30-Dec-2021)
Creating filesystem with 5242880 4k blocks and 1310720 inodes
Filesystem UUID: cc7706fd-ef32-4b28-ae76-accb28fbd49c
Superblock backups stored on blocks:
        32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
        4096000

Allocating group tables: done
Writing inode tables: done
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done

ubuntu@ubuntu:~$ sudo mount /dev/cache-test/hdd /mnt

解除

アンマウントしてからsplitcacheする。キャッシュに乗っている分の書き込みがあるのでそれなりに時間がかかる

sudo lvconvert --splitcache cache-test/hdd

fioでどのくらい出るのか試した結果

本当は各デバイスの結果とキャッシュ設定時の3パターン用意したうえで複数回実行しないとあまり意味はないので参考程度

1回目
           "Seq-Read" bw: 74MB iops:   73 latency:us"20":90.625
          "Seq-Write" bw:138MB iops:  135 latency:us"50":51.757812
       "Rand-Read-4K" bw:  0MB iops:  151 latency:us"20":47.79258
      "Rand-Write-4K" bw: 35MB iops: 8983 latency:us"10":95.363998
2回目
           "Seq-Read" bw: 19MB iops:   19 latency:ms"20":41.894531
          "Seq-Write" bw:159MB iops:  155 latency:us"20":85.449219
       "Rand-Read-4K" bw:  0MB iops:   80 latency:ms"20":67.7573
      "Rand-Write-4K" bw:  1MB iops:  429 latency:us"10":54.063604

キャッシュが効いているのか1回目のRand-Write-4KはHDDとは思えない速度が出ているが、2回目はキャッシュがいっぱいでHDDに転送が追い付いていないのかかなり落ち込んでしまった。