Назад | Перейти на главную страницу

Копирование ZFS при записи

Я планирую использовать 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)!
  • Поскольку ваша версия ZFS не «разрешает» O_DIRECT даже если вы попытаетесь использовать большую глубину с libaio представление не было бы асинхронным (см. IOPS SSD на Linux, DIRECT, намного быстрее, чем с буферизацией, fio ), но поскольку максимальное количество невыполненных операций ввода-вывода ограничено одним (см. выше), это спорный вопрос.
  • Ваш dd записывает так мало данных (4 ГБ) по сравнению с размером вашей памяти (24 ГБ), что Linux может иметь значительные объемы записываемых данных, которые все еще находятся в его кэше страниц после завершения. Вам нужно будет выполнить хотя бы какую-то синхронизацию файлов, чтобы убедиться, что они действительно достигли энергонезависимого хранилища ... Так как указал в комментариях conv=fdatasync был установлен на dd поэтому перед выходом будет последний fdatasync, который гарантирует, что данные не только в энергонезависимых кэшах.
  • Вы сравниваете последовательное на томе Ext4 со случайным на томе ZFS (вы изменили рабочую нагрузку И файловые системы между сравнениями).

Как минимум, я бы посоветовал начать сначала, сделайте все свои тесты на ZFS, используйте fio как для последовательных, так и для случайных тестов, а остальная часть строки остается неизменной. Я бы также подумал об использовании чего-то вроде end_fsync чтобы данные действительно попали на диск, а не только в энергонезависимые кеши (но я вижу аргумент в пользу пропуска этого бита).

TL; DR; Боюсь, ваша методология сравнения ошибочна - может, лучше меньше менять между сравнениями?