Я планирую использовать ZFS для резервного копирования. 5-10 серверов будут «передавать» обновления через DRBD в очень большие файлы (по 500 гигабайт каждый) в файловой системе ZFS.
Серверы будут генерировать около 20 мегабайт в секунду случайных записей со скоростью около 100 МБ / с. Я не читаю эти файлы, поэтому шаблон должен быть почти на 100% записан.
Для меня копирование при записи - очень важная функция.
Насколько я понимаю, COW должен преобразовывать случайные записи в последовательные. Но этого не происходит.
Я тестировал сервер с 12 дисками SAS E5520 XEON (4 ядра) и 24 ГБ ОЗУ, и случайная запись была очень низкой.
Я решил сначала отладить его на 1 жестком диске SAS на том же сервере.
Я создал файловую систему EXT4 и провел несколько тестов:
root@zfs:/mnt/hdd/test# dd if=/dev/zero of=tempfile bs=1M count=4096 conv=fdatasync,notrunc 4096+0 records in 4096+0 records out 4294967296 bytes (4.3 GB) copied, 30.2524 s, 142 MB/s
Итак, я вижу, что скорость записи составляет около 140 Мбит / с.
Случайная запись ~ 500 Кбит / с ~ 100-150 иопс. Что нормально.
fio --randrepeat=1 --ioengine=libaio --direct=1 --gtod_reduce=1 --name=test --filename=test --bs=4k --iodepth=1 --size=4G --readwrite=randwrite test: (g=0): rw=randwrite, bs=4K-4K/4K-4K/4K-4K, ioengine=libaio, iodepth=1 fio-2.1.11 Starting 1 process bs: 1 (f=1): [w(1)] [0.6% done] [0KB/548KB/0KB /s] [0/137/0 iops] [eta 02h:02m:57s]
Затем на том же диске я создал ZFS:
zpool create -f -m / mnt / data bigdata scsi-35000cca01b370274
Я установил размер записи 4K, потому что у меня будут случайные записи 4K. Размер записи 4K работал лучше, чем 128k, когда я тестировал.
zfs устанавливает размер записи = 4k bigdata
Проверена случайная запись в файлы 4G.
fio --randrepeat=1 --ioengine=libaio --gtod_reduce=1 --name=./test --filename=test --bs=4k --iodepth=1 --size=4G --readwrite=randwrite ./test: (g=0): rw=randwrite, bs=4K-4K/4K-4K/4K-4K, ioengine=libaio, iodepth=1 fio-2.1.11 Starting 1 process ./test: Laying out IO file(s) (1 file(s) / 4096MB) Jobs: 1 (f=1): [w(1)] [100.0% done] [0KB/115.9MB/0KB /s] [0/29.7K/0 iops] [ [eta 00m:00s]
Похоже, COW преуспела здесь 115,9 МБ в секунду.
Проверена случайная запись в файлы размером 16 ГБ.
fio --randrepeat=1 --ioengine=libaio --gtod_reduce=1 --name=test --filename=./test16G --bs=4k --iodepth=1 --size=16G --readwrite=randwrite test: (g=0): rw=randwrite, bs=4K-4K/4K-4K/4K-4K, ioengine=libaio, iodepth=1 fio-2.1.11 Starting 1 process bs: 1 (f=1): [w(1)] [0.1% done] [0KB/404KB/0KB /s] [0/101/0 iops] [eta 02h:08m:55s]
Очень плохие результаты 400 килобайт в секунду.
Пробовал то же самое с файлами 8G:
fio --randrepeat=1 --ioengine=libaio --gtod_reduce=1 --name=test --filename=./test8G --bs=4k --iodepth=1 --size=8G --readwrite=randwrite test: (g=0): rw=randwrite, bs=4K-4K/4K-4K/4K-4K, ioengine=libaio, iodepth=1 fio-2.1.11 Starting 1 process test: Laying out IO file(s) (1 file(s) / 8192MB) bs: 1 (f=1): [w(1)] [14.5% done] [0KB/158.3MB/0KB /s] [0/40.6K/0 iops] [eta 00m:53s]
В начале COW было нормально 136 мегабайт в секунду.
Device: rrqm/s wrqm/s r/s w/s rMB/s wMB/s avgrq-sz avgqu-sz await r_await w_await svctm %util sda 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 sdg 0.00 0.00 0.00 1120.00 0.00 136.65 249.88 9.53 8.51 0.00 8.51 0.89 99.24
Но в конце, когда тест достиг 90%, скорость записи упала до 5 мегабайт в секунду.
Device: rrqm/s wrqm/s r/s w/s rMB/s wMB/s avgrq-sz avgqu-sz await r_await w_await svctm %util sda 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 sdg 0.00 0.00 0.00 805.90 0.00 5.33 13.54 9.95 12.34 0.00 12.34 1.24 100.00
Так что файлы 4G в порядке, 8G почти в порядке, но файлы 16G не получают COW.
Не понимаю, что здесь происходит. Возможно, здесь играет роль кеширование памяти.
ОС: Debian 8 ZFS ver 500. Без сжатия или дедупликации.
zpool list NAME SIZE ALLOC FREE EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT bigdata 1.81T 64.4G 1.75T - 2% 3% 1.00x ONLINE - root@zfs:/mnt/data/test# zdb bigdata: version: 5000 name: 'bigdata' state: 0 txg: 4 pool_guid: 16909063556944448541 errata: 0 hostid: 8323329 hostname: 'zfs' vdev_children: 1 vdev_tree: type: 'root' id: 0 guid: 16909063556944448541 create_txg: 4 children[0]: type: 'disk' id: 0 guid: 8547466691663463210 path: '/dev/disk/by-id/scsi-35000cca01b370274-part1' whole_disk: 1 metaslab_array: 34 metaslab_shift: 34 ashift: 9 asize: 2000384688128 is_log: 0 create_txg: 4 features_for_read: com.delphix:hole_birth com.delphix:embedded_data zpool status bigdata pool: bigdata state: ONLINE scan: none requested config: NAME STATE READ WRITE CKSUM bigdata ONLINE 0 0 0 scsi-35000cca01b370274 ONLINE 0 0 0 errors: No known data errors
fio не работает с O_DIRECT на ZFS, мне пришлось работать без него. Насколько я понимаю, это должно дать даже лучшие результаты. Но этого не происходит.
fio --randrepeat=1 --ioengine=libaio --direct=1 --gtod_reduce=1 --name=./test --filename=test16G --bs=4k --iodepth=1 --size=16G --readwrite=randwrite ./test: (g=0): rw=randwrite, bs=4K-4K/4K-4K/4K-4K, ioengine=libaio, iodepth=1 fio-2.1.11 Starting 1 process fio: looks like your file system does not support direct=1/buffered=0 fio: destination does not support O_DIRECT
Это нечестный бой:
dd
в то время как fio
по умолчанию генерирует один случайный блок и повторно использует его, когда это возможно. Поскольку все нули (немного) более сжимаемы, это может исказить числа.dd
составляет 1 МБ, тогда как размер, используемый вашим fio
строка составляет 4KBytes.iodepth
вашей fio
запустить только до 1 (этот выбор составляет меньший, чем выбранный выше размер блока dd).dd
всегда разрешено использовать кеш обратной записи, но один из ваших fio
пробежек не было (потому что вы ставили direct=1
)!O_DIRECT
даже если вы попытаетесь использовать большую глубину с libaio
представление не было бы асинхронным (см. IOPS SSD на Linux, DIRECT, намного быстрее, чем с буферизацией, fio ), но поскольку максимальное количество невыполненных операций ввода-вывода ограничено одним (см. выше), это спорный вопрос.dd
записывает так мало данных (4 ГБ) по сравнению с размером вашей памяти (24 ГБ), что Linux может иметь значительные объемы записываемых данных, которые все еще находятся в его кэше страниц после завершения. Вам нужно будет выполнить хотя бы какую-то синхронизацию файлов, чтобы убедиться, что они действительно достигли энергонезависимого хранилища ...conv=fdatasync
был установлен на dd
поэтому перед выходом будет последний fdatasync, который гарантирует, что данные не только в энергонезависимых кэшах.Как минимум, я бы посоветовал начать сначала, сделайте все свои тесты на ZFS, используйте fio
как для последовательных, так и для случайных тестов, а остальная часть строки остается неизменной. Я бы также подумал об использовании чего-то вроде end_fsync
чтобы данные действительно попали на диск, а не только в энергонезависимые кеши (но я вижу аргумент в пользу пропуска этого бита).
TL; DR; Боюсь, ваша методология сравнения ошибочна - может, лучше меньше менять между сравнениями?