UPD: 13.08.2023 — добавлены тесты по mdadm, lvm, zfs
У данной статьи есть две цели:
-
Протестировать производительность трёх систем объединения физических устройств в одно логическое, как для локального доступа к нему, так и для использования в качестве блочного массива для виртуализации.
-
Создание бэкэнда для кластера в виде одноконтроллерного хранилища.
Иными словами выводы данной статьи не применимы, когда Вам нужно:
-
Синхронное отказоустойчивое решение
-
Надежность >>> скорость
-
Долговременное решение, которое можно поставить и забыть
В связи со значительным удешевлением NVMe дисков на различных ресурсах (таких как авито) можно найти nvme диски дешевле их аналогов на SATA или SAS интерфейсе с таким же объёмом, но остаётся вопрос в их объединение в один логический диск.
К сожалению, текущие рейд контроллеры для NVMe дисков не отличаются особой дешевизной и\или количеством доступных разъёмов для их подключения, поэтому одним из вариантов является использование программного рейда.
Для тестирования выбраны программные рейды:
-
mdadm (UPD: 13.08.2023, добавлены тесты с закрытием write hole — ppl & log)
-
lvm (и надстройка VDO) — (UPD: 13.08.2023 добавлен тест с alloc=anywhere)
-
ZFS (UPD: 13.08.2023 добавлены тесты с zpool blocksize = 128k)
Про кажую из выбранных систем можно подробнее почитать:
Для тестирования локального массива были выбраны тесты описанные тут и тут.
Для тестирования блочного массива виртуализации будет использоваться HCIbench, а параметры взяты из следующей статьи.
Тестовый стенд
Сервер виртуализации:
-
Motherboard: Supermicro H11SSL-i
-
CPU: EPYC 7302
-
RAM: 4x64GB Micron 2933MHz
-
Сеть: 40GbE ConnectX-3 Pro, 10GbE/25GbE ConnectX-4 LN EN
-
ОС: ESXi 7U3 build 20036586
Сервер хранения (в дальнейшем гибридный сервер с PCIe Passthrough для тестов блочного хранилища):
-
Motherboard: Tyan S8030 (ver 1GbE)
-
CPU: EPYC 7302
-
RAM: 4x64GB Micron 2933MHz
-
Сеть: 40GbE ConnectX-3 Pro x2
-
Диски 1: 6 x PM9A3 1.92TB, форматированы в 512n
-
Диски 2: 1 x PM1725 3.2ТБ (не участвует в конфигурации рейда, но используется для сравнения)
Софт для тестов на физике:
-
Debian 12, ядро 6.1.0-10
-
FIO: 3.33-3
Софт для тестов поверх виртуализиации (to-be)
-
ОС: ESXi 7U3 build
-
ВМ: Ubuntu 22.04.03, ядро 6.2
-
FIO: 3.28-1
Список тестов FIO приведён ниже:
fio -name=seq_mbs_write_T1Q1N1 -ioengine=libaio -direct=1 -invalidate=1 -bs=4M -iodepth=32 -rw=write -runtime=60 -filename=/dev/nvme1n1 && sleep 10 && fio -name=seq_mbs_read_T1Q1N1 -ioengine=libaio -direct=1 -invalidate=1 -bs=4M -iodepth=32 -rw=read -runtime=60 -filename=/dev/nvme1n1 && sleep 10 && fio -name=rand_iops_write_T1Q128N1 -ioengine=libaio -direct=1 -invalidate=1 -bs=4k -iodepth=128 -numjobs=4 -group_reporting -rw=randwrite -runtime=60 -randrepeat=0 -filename=/dev/nvme1n1 && sleep 10 && fio -name=rand_iops_read_T1Q128N1 -ioengine=libaio -direct=1 -invalidate=1 -bs=4k -iodepth=128 -numjobs=4 -group_reporting -rw=randread -runtime=60 -randrepeat=0 -filename=/dev/nvme1n1 && sleep 10 && fio -name=rand_iops_read_T1Q1N1 -randrepeat=0 -ioengine=libaio -direct=1 -invalidate=1 -bs=4k -iodepth=1 -rw=randread -runtime=60 -filename=/dev/nvme1n1 && sleep 10 && fio -name=rand_iops_write_T1Q1N1 -randrepeat=0 -ioengine=libaio -direct=1 -invalidate=1 -bs=4k -iodepth=1 -fsync=1 -rw=randwrite -runtime=60 -filename=/dev/nvme1n1
Рассматриваться будет 2 сценария:
-
Raid 0 — (все же делают бэкапы) как крайний сценарий производительного решения, когда за сохранность данных (не доступность) отвечает или репликация или бэкапы.
-
Raid 5 — как хорошая схема для 6 дисков
В качестве блочного доступа будет использоваться iSER и NVMe-oF
Ниже приведена сводная таблица по дискам и график производительности:
Сводная таблица по дискам в системе
|
(MB/s) NVMe# |
NVMe0 (PM1725) |
NVMe1 (PM9A3) |
NVMe2 (PM9A3) |
|
Последовательная запись 4M qd=32 |
1 473.50 |
2 810.50 |
2 809.00 |
|
Последовательное чтение 4M qd=32 |
5 068.50 |
5 882.50 |
5 891.50 |
|
Случайная запись 4k qd=128 jobs=16 |
327.00 |
2 792.00 |
2 787.50 |
|
Случайное чтение 4k qd=128 jobs=16 |
3 957.00 |
4 620.00 |
4 619.00 |
|
Случайная запись 4k qd=1 fsync=1 |
163.50 |
233.00 |
233.50 |
|
Случайное чтение 4k qd=1 fsync=1 |
44.80 |
90.30 |
90.40 |
|
(MB/s) NVMe# |
NVMe3 (PM9A3) |
NVMe4 (PM9A3) |
NVMe5 (PM9A3) |
NVMe6 (PM9A3) |
|
Последовательная запись 4M qd=32 |
2 807.50 |
2 811.00 |
2 809.50 |
2 810.50 |
|
Последовательное чтение 4M qd=32 |
5 884.00 |
5 915.00 |
5 904.50 |
5 885.50 |
|
Случайная запись 4k qd=128 jobs=16 |
2 793.00 |
2 789.00 |
2 779.00 |
2 796.50 |
|
Случайное чтение 4k qd=128 jobs=16 |
4 615.00 |
4 537.50 |
4 526.50 |
4 619.50 |
|
Случайная запись 4k qd=1 fsync=1 |
231.50 |
230.00 |
231.00 |
232.00 |
|
Случайное чтение 4k qd=1 fsync=1 |
90.65 |
90.15 |
90.35 |
90.70 |
Ссылка на excel файл со всеми данными.
MDADM
Создание mdadm достаточно типично:
mdadm —create —verbose /dev/md0 —level=0 —raid-devices=6 /dev/nvme1n1 /dev/nvme2n1 /dev/nvme3n1 /dev/nvme4n1 /dev/nvme5n1 /dev/nvme6n1
Для 5-ого рейда (Перед началом тестов было выждано 3 часа, пока создавался рейд)
mdadm —create —verbose /dev/md5 —level=5 —raid-devices=6 /dev/nvme1n1 /dev/nvme2n1 /dev/nvme3n1 /dev/nvme4n1 /dev/nvme5n1 /dev/nvme6n1
Дополнит
|
RAID 0 |
mdadm-local-raid0 |
|
|
Последовательная запись 4M qd=32 |
11 980.80 MB/s |
— |
|
Последовательное чтение 4M qd=32 |
20 275.20 MB/s |
— |
|
Случайная запись 4k qd=128 jobs=16 |
11 827.20 MB/s |
2 817 002.93 IOPS |
|
Случайное чтение 4k qd=128 jobs=16 |
11 622.40 MB/s |
2 771 891.56 IOPS |
|
Случайная запись 4k qd=1 fsync=1 |
172.50 MB/s |
42 160.66 IOPS |
|
Случайное чтение 4k qd=1 fsync=1 |
99.50 MB/s |
24 269.23 IOPS |
|
RAID 5 |
mdadm-local-raid5 |
|
|
Последовательная запись 4M qd=32 |
1 398.50 MB/s |
— |
|
Последовательное чтение 4M qd=32 |
20 172.80 MB/s |
— |
|
Случайная запись 4k qd=128 jobs=16 |
260.00 MB/s |
63 857.62 IOPS |
|
Случайное чтение 4k qd=128 jobs=16 |
10 444.80 MB/s |
2 503 104.94 IOPS |
|
Случайная запись 4k qd=1 fsync=1 |
35.20 MB/s |
8 609.11 IOPS |
|
Случайное чтение 4k qd=1 fsync=1 |
90.35 MB/s |
22 084.20 IOPS |
|
RAID 5 |
mdadm-local-raid5-ppl |
|
|
Последовательная запись 4M qd=32 |
629.00 MB/s |
— |
|
Последовательное чтение 4M qd=32 |
19 558.40 MB/s |
— |
|
Случайная запись 4k qd=128 jobs=16 |
239.50 MB/s |
58 477.84 IOPS |
|
Случайное чтение 4k qd=128 jobs=16 |
10 444.80 MB/s |
2 502 086.56 IOPS |
|
Случайная запись 4k qd=1 fsync=1 |
36.55 MB/s |
8 927.77 IOPS |
|
Случайное чтение 4k qd=1 fsync=1 |
107.00 MB/s |
26 229.00 IOPS |
|
RAID 5 |
mdadm-local-raid5-log |
|
|
Последовательная запись 4M qd=32 |
725.00 MB/s |
— |
|
Последовательное чтение 4M qd=32 |
20 172.80 MB/s |
— |
|
Случайная запись 4k qd=128 jobs=16 |
208.00 MB/s |
50 794.78 IOPS |
|
Случайное чтение 4k qd=128 jobs=16 |
10 547.20 MB/s |
2 516 402.47 IOPS |
|
Случайная запись 4k qd=1 fsync=1 |
33.10 MB/s |
8 106.66 IOPS |
|
Случайное чтение 4k qd=1 fsync=1 |
90.15 MB/s |
22 037.52 IOPS |
LVM
LVM — для создание используются параметры
lvcreate -i6 -I64 —type striped -l 100%VG -n lvm_stripe stripe
lvcreate -i5 -I64 —type raid5 -l 100%VG -n lvm_raid5 raid
|
RAID0 |
lvm-local-raid0 |
|
|
Последовательная запись 4M qd=32 |
10 905.60 MB/s |
— |
|
Последовательное чтение 4M qd=32 |
20 480.00 MB/s |
— |
|
Случайная запись 4k qd=128 jobs=16 |
14 080.00 MB/s |
3 359 597.24 IOPS |
|
Случайное чтение 4k qd=128 jobs=16 |
14 080.00 MB/s |
3 358 893.54 IOPS |
|
Случайная запись 4k qd=1 fsync=1 |
221.00 MB/s |
53 959.59 IOPS |
|
Случайное чтение 4k qd=1 fsync=1 |
81.05 MB/s |
19 793.28 IOPS |
|
RAID5 |
lvm-local-raid5 alloc default |
|
|
Последовательная запись 4M qd=32 |
1427.50 MB/s |
— |
|
Последовательное чтение 4M qd=32 |
18 995.20 MB/s |
— |
|
Случайная запись 4k qd=128 jobs=16 |
202.00 MB/s |
49 445.24 IOPS |
|
Случайное чтение 4k qd=128 jobs=16 |
9816.50 MB/s |
2 407 383.56 IOPS |
|
Случайная запись 4k qd=1 fsync=1 |
31.20 MB/s |
49 445.24 IOPS |
|
Случайное чтение 4k qd=1 fsync=1 |
87.25 MB/s |
21 266.52 IOPS |
|
RAID5 |
lvm-local-raid5-alloc-normal |
|
|
Последовательная запись 4M qd=32 |
1 352.00 MB/s |
— |
|
Последовательное чтение 4M qd=32 |
19 302.40 MB/s |
— |
|
Случайная запись 4k qd=128 jobs=16 |
203.00 MB/s |
49 445.235 IOPS |
|
Случайное чтение 4k qd=128 jobs=16 |
9 858.00 MB/s |
2 407 383.56 IOPS |
|
Случайная запись 4k qd=1 fsync=1 |
31.40 MB/s |
7 672.28 IOPS |
|
Случайное чтение 4k qd=1 fsync=1 |
87.10 MB/s |
21 266.52 IOPS |
|
RAID5 |
lvm-local-raid5-alloc-anywhere |
|
|
Последовательная запись 4M qd=32 |
1 340.50 MB/s |
— |
|
Последовательное чтение 4M qd=32 |
19 046.4 MB/s |
— |
|
Случайная запись 4k qd=128 jobs=16 |
202.00 MB/s |
49 372.28 IOPS |
|
Случайное чтение 4k qd=128 jobs=16 |
9 826.50 MB/s |
2 400 206.15 IOPS |
|
Случайная запись 4k qd=1 fsync=1 |
31.20 MB/s |
7 620.88 IOPS |
|
Случайное чтение 4k qd=1 fsync=1 |
87.05 MB/s |
21 248.33 IOPS |
LVM+VDO
Так как на Debian vdo просто нет, даже в виде пакета он добавлялся как модуль к ядру с использованием этого руководства), тесты проводились с включённым дедупом, так как это параметр по умолчанию.
При создании использовались следующие параметры, так как по умолчанию VDO не поддерживает raid конфигурацию, поэтому пул создавался через lvconvert.
lvcreate -i6 -I64 --type striped -l 100%VG -n stripe-vdo lvm lvconvert --type vdo-pool --virtualsize 8TB /dev/lvm/stripe-vdo
|
RAID0 |
lvm-vdo-local-raid0 |
|
|
Последовательная запись 4M qd=32 |
735.00 MB/s |
— |
|
Последовательное чтение 4M qd=32 |
2 279.50 MB/s |
— |
|
Случайная запись 4k qd=128 jobs=16 |
415.50 MB/s |
101 344.40 IOPS |
|
Случайное чтение 4k qd=128 jobs=16 |
901.50 MB/s |
220 089.32 IOPS |
|
Случайная запись 4k qd=1 fsync=1 |
6.14 MB/s |
1 534.41 IOPS |
|
Случайное чтение 4k qd=1 fsync=1 |
39.00 MB/s |
9 520.67 IOPS |
lvcreate -i6 -I64 --type raid5 -l 100%VG -n lvm_raid5 raid5 lvconvert --type vdo-pool --virtualsize 8TB /dev/lvm/raid5-vdo
|
RAID5 |
lvm-vdo-local-raid5 |
|
|
Последовательная запись 4M qd=32 |
230.50 MB/s |
— |
|
Последовательное чтение 4M qd=32 |
2 406.50 MB/s |
— |
|
Случайная запись 4k qd=128 jobs=16 |
79.50 MB/s |
19 388.92 IOPS |
|
Случайное чтение 4k qd=128 jobs=16 |
1 536.00 MB/s |
374 751.79 IOPS |
|
Случайная запись 4k qd=1 fsync=1 |
1.59 MB/s |
398.57 IOPS |
|
Случайное чтение 4k qd=1 fsync=1 |
34.25 MB/s |
8 329.27 IOPS |
ZFS
После каждой группы тестов сервер перезапускался, т.е., к примеру, после тестов stripe 16k и перед тестами на 8k, чтобы однозначно очистить ARC.
Когда выйдет ZFS 3.0 с патчем O_DIRECT для nvme, я расширю её, сейчас же ZFS выглядит следующим образом:
v1 — блок 16k (новые дефолтные параметры), компрессия lz4 (не оказывает влияния на IOPS, по множественным заявлениям и по результатом тестов), дедуп выключен:
zpool create -o ashift=12 -O compression=lz4 -O atime=off -O recordsize=16k nvme /dev/nvme1n1 /dev/nvme2n1 /dev/nvme3n1 /dev/nvme4n1 /dev/nvme5n1 /dev/nvme6n1 zfs create -s -V 10T -o volblocksize=16k -o compression=lz4 nvme/iser
|
Stripe |
zfs-local-stripe-16k |
|
|
Последовательная запись 4M qd=32 |
2 826.00 MB/s |
— |
|
Последовательное чтение 4M qd=32 |
5 955.00 MB/s |
— |
|
Случайная запись 4k qd=128 jobs=16 |
176.50 MB/s |
43 120.67 IOPS |
|
Случайное чтение 4k qd=128 jobs=16 |
827.00 MB/s |
201 500.96 IOPS |
|
Случайная запись 4k qd=1 fsync=1 |
22.85 MB/s |
5 580.61 IOPS |
|
Случайное чтение 4k qd=1 fsync=1 |
66.35 MB/s |
16 209.50 IOPS |
|
RaidZ |
zfs-local-raidZ-16k |
|
|
Последовательная запись 4M qd=32 |
1 701.00 MB/s |
— |
|
Последовательное чтение 4M qd=32 |
3 967.00 MB/s |
— |
|
Случайная запись 4k qd=128 jobs=16 |
154.50 MB/s |
37 638.80 IOPS |
|
Случайное чтение 4k qd=128 jobs=16 |
427.50 MB/s |
104 231.22 IOPS |
|
Случайная запись 4k qd=1 fsync=1 |
11.30 MB/s |
2 757.17 IOPS |
|
Случайное чтение 4k qd=1 fsync=1 |
28.75 MB/s |
7 017.52 IOPS |
2 — блок 8к (старые дефолтные параметры)
zpool create -o ashift=12 -O compression=lz4 -O atime=off -O recordsize=8k nvme /dev/nvme1n1 /dev/nvme2n1 /dev/nvme3n1 /dev/nvme4n1 /dev/nvme5n1 /dev/nvme6n1 zfs create -s -V 10T -o volblocksize=8k -o compression=lz4 nvme/iser
|
Stripe |
zfs-local-stripe-8k |
|
|
Последовательная запись 4M qd=32 |
1 513.00 MB/s |
— |
|
Последовательное чтение 4M qd=32 |
3 352.00 MB/s |
— |
|
Случайная запись 4k qd=128 jobs=16 |
155.00 MB/s |
37 860.44 IOPS |
|
Случайное чтение 4k qd=128 jobs=16 |
710.00 MB/s |
172 631.13 IOPS |
|
Случайная запись 4k qd=1 fsync=1 |
21.75 MB/s |
5 311.53 IOPS |
|
Случайное чтение 4k qd=1 fsync=1 |
65.55 MB/s |
16 005.12 IOPS |
|
RaidZ |
zfs-local-raidZ-8k |
|
|
Последовательная запись 4M qd=32 |
1 035.50 MB/s |
— |
|
Последовательное чтение 4M qd=32 |
2 877.00 MB/s |
— |
|
Случайная запись 4k qd=128 jobs=16 |
153.00 MB/s |
37 383.61 IOPS |
|
Случайное чтение 4k qd=128 jobs=16 |
427.50 MB/s |
104 453.05 IOPS |
|
Случайная запись 4k qd=1 fsync=1 |
10.90 MB/s |
2 657.64 IOPS |
|
Случайное чтение 4k qd=1 fsync=1 |
23.45 MB/s |
5 716.16 IOPS |
v3 — блок 64к (как просто большой блок)
zpool create -o ashift=12 -O compression=lz4 -O atime=off -O recordsize=64k nvme /dev/nvme1n1 /dev/nvme2n1 /dev/nvme3n1 /dev/nvme4n1 /dev/nvme5n1 /dev/nvme6n1 zfs create -s -V 10T -o volblocksize=64k -o compression=lz4 nvme/iser
|
Stripe |
zfs-local-stripe-64k |
|
|
Последовательная запись 4M qd=32 |
4 778.00 MB/s |
— |
|
Последовательное чтение 4M qd=32 |
5 121.00 MB/s |
— |
|
Случайная запись 4k qd=128 jobs=16 |
183.50 MB/s |
44 785.15 IOPS |
|
Случайное чтение 4k qd=128 jobs=16 |
1 062.50 MB/s |
259 321.58 IOPS |
|
Случайная запись 4k qd=1 fsync=1 |
22.80 MB/s |
5 559.02 IOPS |
|
Случайное чтение 4k qd=1 fsync=1 |
65.85 MB/s |
16 085.35 IOPS |
|
RaidZ |
zfs-local-raidZ-64k |
|
|
Последовательная запись 4M qd=32 |
3 758.00 MB/s |
— |
|
Последовательное чтение 4M qd=32 |
4 269.00 MB/s |
— |
|
Случайная запись 4k qd=128 jobs=16 |
156.00 MB/s |
38 111.73 IOPS |
|
Случайное чтение 4k qd=128 jobs=16 |
1 086.50 MB/s |
265 232.02 IOPS |
|
Случайная запись 4k qd=1 fsync=1 |
17.90 MB/s |
4 372.47 IOPS |
|
Случайное чтение 4k qd=1 fsync=1 |
73.15 MB/s |
17 855.23 IOPS |
v4 — Все параметры по умолчанию, zpool recordsize = 128k, zvol blocksize=8k
|
Stripe |
zfs-local-stripe-default |
|
|
Последовательная запись 4M qd=32 |
1 568.50 MB/s |
— |
|
Последовательное чтение 4M qd=32 |
3 494.00 MB/s |
— |
|
Случайная запись 4k qd=128 jobs=16 |
166.50 MB/s |
40 598.80 IOPS |
|
Случайное чтение 4k qd=128 jobs=16 |
741.00 MB/s |
180 330.46 IOPS |
|
Случайная запись 4k qd=1 fsync=1 |
17.40 MB/s |
4 241.05 IOPS |
|
Случайное чтение 4k qd=1 fsync=1 |
45.20 MB/s |
11 033.33 IOPS |
|
RaidZ |
zfs-local-raidZ-default |
|
|
Последовательная запись 4M qd=32 |
986.50 MB/s |
— |
|
Последовательное чтение 4M qd=32 |
3 538.00 MB/s |
— |
|
Случайная запись 4k qd=128 jobs=16 |
145.00 MB/s |
35 350.86 IOPS |
|
Случайное чтение 4k qd=128 jobs=16 |
715.50 MB/s |
173 890.22 IOPS |
|
Случайная запись 4k qd=1 fsync=1 |
17.30 MB/s |
4 221.97 IOPS |
|
Случайное чтение 4k qd=1 fsync=1 |
68.75 MB/s |
16 777.54 IOPS |
v5 — zpool recordsize = 128k, zvol blocksize=16k
|
Stripe |
zfs-local-stripe-128k-16k |
|
|
Последовательная запись 4M qd=32 |
3 037.00 MB/s |
— |
|
Последовательное чтение 4M qd=32 |
5 812.00 MB/s |
— |
|
Случайная запись 4k qd=128 jobs=16 |
172.50 MB/s |
42 164.89 IOPS |
|
Случайное чтение 4k qd=128 jobs=16 |
926.00 MB/s |
225 542.80 IOPS |
|
Случайная запись 4k qd=1 fsync=1 |
22.55 MB/s |
5 498.39 IOPS |
|
Случайное чтение 4k qd=1 fsync=1 |
62.20 MB/s |
15 186.53 IOPS |
|
RaidZ |
zfs-local-raidZ-128k-16k |
|
|
Последовательная запись 4M qd=32 |
1 693.50 MB/s |
— |
|
Последовательное чтение 4M qd=32 |
5 858.00 MB/s |
— |
|
Случайная запись 4k qd=128 jobs=16 |
138.00 MB/s |
33 766.93 IOPS |
|
Случайное чтение 4k qd=128 jobs=16 |
828.50 MB/s |
201 839.62 IOPS |
|
Случайная запись 4k qd=1 fsync=1 |
17.55 MB/s |
4 286.75 IOPS |
|
Случайное чтение 4k qd=1 fsync=1 |
66.60 MB/s |
16 262.31 IOPS |
Также для ZFS дополнительно был сделан тест на 64 потока в виде 64 разных файлов на пуле:
recordsize=8k
|
Stripe |
zfs64-local-stripe-8k |
|
Последовательная запись 4M qd=32 |
1 242.50 MB/s |
|
Последовательное чтение 4M qd=32 |
3 123.00 MB/s |
|
Случайная запись 4k qd=128 jobs=16 |
275.50 MB/s |
|
Случайное чтение 4k qd=128 jobs=16 |
1 436.00 MB/s |
|
Случайная запись 4k qd=1 fsync=1 |
196.50 MB/s |
|
Случайное чтение 4k qd=1 fsync=1 |
1 439.00 MB/s |
|
RaidZ |
zfs64-local-raidZ-8k |
|
Последовательная запись 4M qd=32 |
981.00 MB/s |
|
Последовательное чтение 4M qd=32 |
3 756.00 MB/s |
|
Случайная запись 4k qd=128 jobs=16 |
187.50 MB/s |
|
Случайное чтение 4k qd=128 jobs=16 |
1 192.50 MB/s |
|
Случайная запись 4k qd=1 fsync=1 |
138.00 MB/s |
|
Случайное чтение 4k qd=1 fsync=1 |
1 209.00 MB/s |
recordsize=16k
|
Stripe |
zfs64-local-stripe-16k |
|
Последовательная запись 4M qd=32 |
2 346.00 MB/s |
|
Последовательное чтение 4M qd=32 |
4 508.00 MB/s |
|
Случайная запись 4k qd=128 jobs=16 |
296.50 MB/s |
|
Случайное чтение 4k qd=128 jobs=16 |
1 248.50 MB/s |
|
Случайная запись 4k qd=1 fsync=1 |
201.00 MB/s |
|
Случайное чтение 4k qd=1 fsync=1 |
1 228.50 MB/s |
|
RaidZ |
zfs64-local-raidZ-16k |
|
Последовательная запись 4M qd=32 |
1 579.00 MB/s |
|
Последовательное чтение 4M qd=32 |
5 044.00 MB/s |
|
Случайная запись 4k qd=128 jobs=16 |
186.00 MB/s |
|
Случайное чтение 4k qd=128 jobs=16 |
1 000.00 MB/s |
|
Случайная запись 4k qd=1 fsync=1 |
138.00 MB/s |
|
Случайное чтение 4k qd=1 fsync=1 |
1 003.50 MB/s |
recordsize=64k
|
Stripe |
zfs64-local-stripe-64k |
|
Последовательная запись 4M qd=32 |
5 252.50 MB/s |
|
Последовательное чтение 4M qd=32 |
6 260.00 MB/s |
|
Случайная запись 4k qd=128 jobs=16 |
241.00 MB/s |
|
Случайное чтение 4k qd=128 jobs=16 |
506.00 MB/s |
|
Случайная запись 4k qd=1 fsync=1 |
151.00 MB/s |
|
Случайное чтение 4k qd=1 fsync=1 |
562.00 MB/s |
|
RaidZ |
zfs64-local-raidZ-64k |
|
Последовательная запись 4M qd=32 |
3 658.50 MB/s |
|
Последовательное чтение 4M qd=32 |
5 737.50 MB/s |
|
Случайная запись 4k qd=128 jobs=16 |
177.00 MB/s |
|
Случайное чтение 4k qd=128 jobs=16 |
460.50 MB/s |
|
Случайная запись 4k qd=1 fsync=1 |
128.00 MB/s |
|
Случайное чтение 4k qd=1 fsync=1 |
504.50 MB/s |
Сводные графики по тестам:
Последовательная запись 4M qd=32
Последовательное чтение 4M qd=32
Случайная запись 4k qd=128 jobs=16
Случайное чтение 4k qd=128 jobs=16
Случайная запись 4k qd=1 fsync=1
и без ZFS64
ьвф
Случайное чтение 4k qd=1 fsync=1
И без ZFS64
Вывод
mdadm и stripe LVM имеют +- одинаковую производительность, при этом vdo с настройками по умолчанию в режиме stripe демонстрирует производительность (для случайных операций) на уровне ZFS.
mdadm с закрытым write-hole достаточно сильно режет производительность крупной записи, но почти не уменьшает производительность мелкоблочной записи.
ZFS на 64 потоков вырывается вперёд в тестах qd=1, так как он игнорируется fsync и эффективно это 64 операции для данного теста. В чтении на 64 одних потока же прекрасное работает ARC.
В стандартном состоянии — ZFS демонстрирует то, что ожидаешь от CoW системы ориетированной на HDD. Не особо быструю производительность на NVMe. Особенно грустно со случайной записью с большой очередью.
Если строить таблицу беря mdadm за 100% получится следующая картина:
Raid0/Stripe
|
Raid0/Stripe |
mdadm-raid0 |
lvm-raid0 |
lvm-vdo-raid0 |
|
Последовательная запись 4M qd=32 |
100.00% |
91.03% |
6.13% |
|
Последовательное чтение 4M qd=32 |
100.00% |
101.01% |
11.24% |
|
Случайная запись 4k qd=128 jobs=16 |
100.00% |
119.05% |
3.51% |
|
Случайное чтение 4k qd=128 jobs=16 |
100.00% |
121.15% |
7.76% |
|
Случайная запись 4k qd=1 fsync=1 |
100.00% |
128.12% |
3.56% |
|
Случайное чтение 4k qd=1 fsync=1 |
100.00% |
81.46% |
39.20% |
|
Raid0/Stripe |
zfs-default |
zfs-8k |
zfs-128k-16k |
zfs-16k |
zfs-64k |
|
Последовательная запись 4M qd=32 |
13.09% |
12.63% |
25.35% |
23.59% |
39.88% |
|
Последовательное чтение 4M qd=32 |
17.23% |
16.53% |
28.67% |
29.37% |
25.26% |
|
Случайная запись 4k qd=128 jobs=16 |
1.42% |
1.31% |
1.47% |
1.49% |
1.55% |
|
Случайное чтение 4k qd=128 jobs=16 |
6.32% |
6.11% |
7.90% |
7.12% |
9.14% |
|
Случайная запись 4k qd=1 fsync=1 |
10.09% |
12.61% |
13.07% |
13.25% |
13.22% |
|
Случайное чтение 4k qd=1 fsync=1 |
45.43% |
65.88% |
62.51% |
66.68% |
66.18% |
|
Raid0/Stripe |
zfs64-8k |
zfs64-16k |
zfs64-64k |
|
Последовательная запись 4M qd=32 |
10.37% |
19.58% |
43.84% |
|
Последовательное чтение 4M qd=32 |
15.40% |
22.23% |
30.88% |
|
Случайная запись 4k qd=128 jobs=16 |
2.33% |
2.51% |
2.04% |
|
Случайное чтение 4k qd=128 jobs=16 |
12.36% |
10.74% |
4.35% |
|
Случайная запись 4k qd=1 fsync=1 |
113.91% |
116.52% |
87.54% |
|
Случайное чтение 4k qd=1 fsync=1 |
1446.23% |
1234.67% |
564.82% |
Отдельно сравнение ZFS 16k с\без дедупа:
|
zfs-local-stripe-16k |
zfs-local-stripe-16k-dedup |
|
|
Последовательная запись 4M qd=32 |
100.00% |
27.16% |
|
Последовательное чтение 4M qd=32 |
100.00% |
102.38% |
|
Случайная запись 4k qd=128 jobs=16 |
100.00% |
53.57% |
|
Случайное чтение 4k qd=128 jobs=16 |
100.00% |
97.94% |
|
Случайная запись 4k qd=1 fsync=1 |
100.00% |
97.16% |
|
Случайное чтение 4k qd=1 fsync=1 |
100.00% |
105.05% |
Raid5/RaidZ
|
Raid5/RaidZ |
mdadm-raid5 |
mdadm-raid5-ppl |
mdadm-raid5-log |
|
Последовательная запись 4M qd=32 |
100.00% |
44.98% |
51.84% |
|
Последовательное чтение 4M qd=32 |
100.00% |
96.95% |
100.00% |
|
Случайная запись 4k qd=128 jobs=16 |
100.00% |
92.12% |
80.00% |
|
Случайное чтение 4k qd=128 jobs=16 |
100.00% |
100.00% |
100.98% |
|
Случайная запись 4k qd=1 fsync=1 |
100.00% |
103.84% |
94.03% |
|
Случайное чтение 4k qd=1 fsync=1 |
100.00% |
118.43% |
99.78% |
|
Raid5/RaidZ |
lvm-raid5 |
lvm-raid5-alloc-normal |
lvm-vdo-raid5 |
|
Последовательная запись 4M qd=32 |
76.02% |
77.20% |
15.12% |
|
Последовательное чтение 4M qd=32 |
59.52% |
56.98% |
11.96% |
|
Случайная запись 4k qd=128 jobs=16 |
90.87% |
92.09% |
32.25% |
|
Случайное чтение 4k qd=128 jobs=16 |
88.71% |
88.28% |
14.56% |
|
Случайная запись 4k qd=1 fsync=1 |
56.87% |
74.31% |
5.13% |
|
Случайное чтение 4k qd=1 fsync=1 |
87.18% |
91.69% |
55.24% |
|
Raid5/RaidZ |
zfs-raidz-default |
zfs-raidZ-8k |
zfs-128k-16k |
zfs-raidZ-16k |
zfs-raidZ-64k |
|
Последовательная запись 4M qd=32 |
70.54% |
67.95% |
121.09% |
111.61% |
246.59% |
|
Последовательное чтение 4M qd=32 |
17.54% |
14.29% |
29.04% |
19.71% |
21.21% |
|
Случайная запись 4k qd=128 jobs=16 |
55.77% |
62.07% |
53.08% |
62.68% |
63.29% |
|
Случайное чтение 4k qd=128 jobs=16 |
6.85% |
4.05% |
7.93% |
4.05% |
10.30% |
|
Случайная запись 4k qd=1 fsync=1 |
49.15% |
35.22% |
49.86% |
36.51% |
57.84% |
|
Случайное чтение 4k qd=1 fsync=1 |
76.09% |
37.82% |
73.71% |
46.37% |
117.98% |
|
Raid5/RaidZ |
zfs64-raidZ-8k |
zfs64-raidZ-16k |
zfs64-raidZ-64k |
|
Последовательная запись 4M qd=32 |
64.37% |
103.61% |
240.06% |
|
Последовательное чтение 4M qd=32 |
18.66% |
25.06% |
28.51% |
|
Случайная запись 4k qd=128 jobs=16 |
76.06% |
75.46% |
71.81% |
|
Случайное чтение 4k qd=128 jobs=16 |
11.31% |
9.48% |
4.37% |
|
Случайная запись 4k qd=1 fsync=1 |
445.88% |
445.88% |
413.57% |
|
Случайное чтение 4k qd=1 fsync=1 |
1950.00% |
1618.55% |
813.71% |
Для дальнейших тестов с использованием iSER и NVMe-oF будут использоваться 3 основных варианта:
-
mdadm stripe
-
lvm stripe
-
ZFS stripe с recordsize=128k, blocksize=16k и компрессией
-
ZFS stripe с recordsize=128k, blocksize=16k и компрессией + дедупом
P.S. Если Вы считаете, что эти тесты неполные, в них что-то упущено или они некорректно — я открыт к любым предложениям по их дополнению.
Для теста zfs64 был использован следующий формат команды:
fio -name=test1 -ioengine=libaio -direct=1 -invalidate=1 -bs=4M -iodepth=32 -rw=write -runtime=60 -filesize=20G >> zfs64-.txt && echo «***» >> zfs64-.txt && sleep 30 && fio -name=test1 -ioengine=libaio -direct=1 -invalidate=1 -bs=4M -iodepth=32 -rw=read -runtime=60 -filesize=20G >> zfs64-.txt && echo «***» >> zfs64-.txt && sleep 30 && fio -name=test1 -ioengine=libaio -direct=1 -invaqdlidate=1 -bs=4k -iodepth=128 -numjobs=16 -group_reporting -rw=randwrite -runtime=60 -randrepeat=0 -filesize=20G >> zfs64-.txt && echo «***» >> zfs64-.txt && sleep 30 && fio -name=test1 -ioengine=libaio -direct=1 -invalidate=1 -bs=4k -iodepth=128 -numjobs=16 -group_reporting -rw=randread -runtime=60 -randrepeat=0 -filesize=20G >> zfs64-.txt && echo «***» >> zfs64-.txt && sleep 30 && fio -name=test1 -ioengine=libaio -direct=1 -randrepeat=0 -rw=randwrite -bs=4k -numjobs=1 -iodepth=1 -fsync=1 -runtime=60 -filesize=20G >> zfs64-.txt && echo «***» >> zfs64-.txt && sleep 30 && fio -name=test1 -ioengine=libaio -direct=1 -randrepeat=0 -rw=randread -bs=4k -numjobs=1 -iodepth=1 -fsync=1 -runtime=60 -filesize=20G >> zfs64-.txt && echo «###» >> zfs64-.txt && sleep 60 && fio -name=test1 -ioengine=libaio -direct=1 -invalidate=1 -bs=4M -iodepth=32 -rw=write -runtime=60 -filesize=20G >> zfs64-.txt && echo «***» >> zfs64-.txt && sleep 30 && fio -name=test1 -ioengine=libaio -direct=1 -invalidate=1 -bs=4M -iodepth=32 -rw=read -runtime=60 -filesize=20G >> zfs64-.txt && echo «***» >> zfs64-.txt && sleep 30 && fio -name=test1 -ioengine=libaio -direct=1 -invalidate=1 -bs=4k -iodepth=128 -numjobs=16 -group_reporting -rw=randwrite -runtime=60 -randrepeat=0 -filesize=20G >> zfs64-.txt && echo «***» >> zfs64-.txt && sleep 30 && fio -name=test1 -ioengine=libaio -direct=1 -invalidate=1 -bs=4k -iodepth=128 -numjobs=16 -group_reporting -rw=randread -runtime=60 -randrepeat=0 -filesize=20G >> zfs64-.txt && echo «***» >> zfs64-.txt && sleep 30 && fio -name=test1 -ioengine=libaio -direct=1 -randrepeat=0 -rw=randwrite -bs=4k -numjobs=1 -iodepth=1 -fsync=1 -runtime=60 -filesize=20G >> zfs64-.txt && echo «***» >> zfs64-.txt && sleep 30 && fio -name=test1 -ioengine=libaio -direct=1 -randrepeat=0 -rw=randread -bs=4k -numjobs=1 -iodepth=1 -fsync=1 -runtime=60 -filesize=20G >> zfs64-.txt && echo «***» >> zfs64-.txt
ссылка на оригинал статьи https://habr.com/ru/articles/753322/
Добавить комментарий