Про ZFS, Advanced Format и ashift

Пару лет назад я уже исследовал ZFS на дисках с 4k-сектором, но тогда такой диск в массиве был только один (а остальные три - с 512b секторами) и какой-то значимой разницы я не нарыл.

Кроме того, том был загрузочный, а грузиться с тома где ashift не равен 9 тогдашние бутблоки не умели.

Поэтому овладев пятеркой 3Tb сигейтов я просто обязан был это опробовать.

Рассказываю.

Hardware

  • 5x Seagate ST3000DM001 (3Tb)
  • Материнка на Intel X58, Core i7 920, 12GB RAM
  • FreeBSD 9.0-STABLE, обновлялась недели три назад.
  • Попало с машины, откуда я склонировал FreeBSD. Может оно и неправильно, но уже поздно перемеривать:  vfs.zfs.arc_max="4G" vfs.zfs.vdev.max_pending=30

Stripe

512-байтный блок (ashift=9)

Делаем том, смотрим что получилось:  lexa@newgw:/# zpool create zdata ada0 ada1 ada2 ada3 ada4 lexa@newgw:/# zdb | grep ashift ashift: 9 ashift: 9 ashift: 9 ashift: 9 ashift: 9 Создаем 100-гигабайтный файл:  lexa@newgw:/zdata# dd if=/dev/zero of=file bs=1024k count=100000 100000+0 records in 100000+0 records out 104857600000 bytes transferred in 237.302583 secs (441872982 bytes/sec) Ну, честно говоря, 441Mb/sec на пяти дисках, при том что намеривают на них в районе 130-140Mb/sec (на одном) - безобразно мало как-то.

С другой стороны, вот у меня сейчас на WD Green (6-й диск на фото) идет zfs send, скорость по iostat в районе 60Mb/sec, а тот же Анандтех намерял в том же тесте 112Mb/sec на чтении. И там не мелочь какая валяется, а честное кино в BD-формате, мелких файлов практически нет, всяких частых seeks не должно бы быть.

4k-сектор

Делаем gnop c 4k размером блока, создаем на них ZFS, сносим gnop, реимпортируем массив, проверяем ashift:  lexa@newgw:/# for i in 0 1 2 3 4 ; do gnop create -S 4096 ada$i ; done lexa@newgw:/# zpool create zdata ada0.nop ada1.nop ada2.nop ada3.nop ada4.nop lexa@newgw:/# zpool export zdata lexa@newgw:/# for i in 0 1 2 3 4 ; do gnop destroy ada$i.nop ; done lexa@newgw:/# zpool import zdata lexa@newgw:/# zdb | grep ashift ashift: 12 ashift: 12 ashift: 12 ashift: 12 ashift: 12 Ну и опять создаем 100Gb-файл:  lexa@newgw:/zdata# dd if=/dev/zero of=file bs=1024k count=100000 100000+0 records in 100000+0 records out 104857600000 bytes transferred in 227.508645 secs (460895013 bytes/sec) Стало, как видим, примерно на 5% быстрее. И то хлеб.

RAIDZ

Процедура создания отличается только словом raidz в zpool create, приводить ее не буду. Сразу результаты:

ashift=9:

lexa@newgw:/zdata# dd if=/dev/zero of=file bs=1024k count=100000 100000+0 records in 100000+0 records out 104857600000 bytes transferred in 294.153101 secs (356472870 bytes/sec) ashift=12 (4k):

lexa@newgw:/zdata# dd if=/dev/zero of=file bs=1024k count=100000 100000+0 records in 100000+0 records out 104857600000 bytes transferred in 284.168616 secs (368997821 bytes/sec) ashift=13 (8k)

lexa@newgw:/zdata# dd if=/dev/zero of=file bs=1024k count=100000 100000+0 records in 100000+0 records out 104857600000 bytes transferred in 284.024706 secs (369184785 bytes/sec) Те же 5% прироста у 4кб блока относительно 512b

Мораль

Для длинных IO принципиальной разницы нет, но наверное она будет больше на мелких случайных чтениях. Так как мне с этого тома не загружаться, оставил ashift=12.

Но вообще - это все как-то безобразно медленно. Чуть меньше, около 300Mb/sec я имею на запись на 6x старых терабайтных барракудах-ES (RAID6, железный контроллер, диски из того же времени, когда были самоумирающие Barracuda 7200.10 или 11, забыл как их звали), при том что оборотов там столько же, а плотность записи в разы меньше.

Comments

У меня три хитачи в RAIDZ дают 177.47 MB/s Read

Ну то же самое, те же ~80-90 со шпинделя, минус избыточность.

Ну ведь безобразно мало же.

чем больше шпинделей, тем больше raidz от аппаратного raid 10 отстает:
были у меня замеры на 14 шпинделях 15к SAS - совсем грустно :(

Не, ну 10 - это совсем другая избыточность.

По моему опыту, raidz любит CPU и сильно. Я вот про это писал: http://blog.lexa.ru/2010/11/06/freebsd_zfs_performance_prosto_vozmite_mo...

Вместе с тем, вот для хранилища, куда суточный трафик - ну 200Gb в плохом случае (100G бэкапов ну и допустим два фильма в BD) - я однозначно за raidz. Оно настолько удобнее администрируется, что аппаратный массив просто в топку.

А вот что делать с задуманной, но пока не сделанной "внешней дисковой полкой" - я пока не решил. Но диски свободные есть, поэкспериментируем и так и эдак.

а харды так только во время тестов или перманентно?

Их физическое положение в пространстве ничего не меняет?

На время переноса старого массива. Провода короткие, места мало, горизонтально 5 штук можно положить, а 6 - нет.

Живут они вертикально на длинной стороне. Так точно можно.

Про недостаточную длину проводов не подумал. Они ведь на SATA2?

На ем, родимом.
Но не хватает длины питания.

один раз винт глючил, я думал уже, что умирает, а это оказался провод виноват, потом через этот провод вообще данные ходить перестали, хотя никаких перегибов не было...

Может они виноваты в снижении скорости?

Все тесты делались с дисками лежащими на спинке, фото - позже.

И загрузка (svc_t, всякий %load) по дискам была одинаковая, вряд-ли там все пять заглючили одинаково.

ну то, что там намеряли -- это филькина грамота.
трансфер-то на внешних и внутренних дорожках существенно разный.

В теории да, а на практике там вот чего намеряют: http://benchmarkreviews.com/index.php?option=com_content&task=view&id=84...

не верю. это противоречит физике.
у тебя ведь есть собственный дд, померяй.

Поздно уже мерять, на этом массиве уже несколько терабайт кина налито.

чтение -- процесс не дуструктивный

Чтение - не та бенчмарка. Горб по скорости в районе 1-го терабайта меня удивил:

lexa@new-gw:/archive# dd if=/dev/ada0 of=/dev/null bs=1G count=10
10+0 records in
10+0 records out
10737418240 bytes transferred in 57.559866 secs (186543489 bytes/sec)
lexa@new-gw:/archive# dd if=/dev/ada0 of=/dev/null bs=1G count=10 skip=500
10+0 records in
10+0 records out
10737418240 bytes transferred in 51.813996 secs (207230074 bytes/sec)
lexa@new-gw:/archive# dd if=/dev/ada0 of=/dev/null bs=1G count=10 skip=1000
10+0 records in
10+0 records out
10737418240 bytes transferred in 55.373747 secs (193908103 bytes/sec)
lexa@new-gw:/archive# dd if=/dev/ada0 of=/dev/null bs=1G count=10 skip=2000
10+0 records in
10+0 records out
10737418240 bytes transferred in 69.051609 secs (155498451 bytes/sec)
lexa@new-gw:/archive# dd if=/dev/ada0 of=/dev/null bs=1G count=10 skip=2700
10+0 records in
10+0 records out
10737418240 bytes transferred in 96.443796 secs (111333426 bytes/sec)

Во время копирования надо параллельно запустить systat -vm 3 и смотреть строчку KB/t - килобайт на "транзакцию", то есть выяснить, блоками какого размера ZFS обращается к носителю. Подозреваю, что мелкими, а современным дискам от этого значительно плохеет в смысе скорости. Либо как-то заставить ZFS работать с носителем блоками не менее чем по 64K (а лучше всего по MAXPHYS=128K), либо поверх дисков создавать geom_cache с размером блока 128K, а ZFS уже на gcache создавать. Резко лучше становится, когда gcache форсирует работу с дисками блоками по 128K (правда, он только на чтение влияет, на запись он прозрачный и на запись ничего не кеширует).

Там было 121-125k
Т.е. подозреваю что 128+мелочь на данные+метаданные.

А размер блока можно и через ashift дотянуть до любого желаемого. И на чтение и на запись. Но сдается мне, это для ZFS будет скорее вредно. Чтение в любом случае префетчится, а растить блок на запись без нужды как-то глупо.

Я такой скорости могу только позавидовать...

[ paul@biggiesmalls /mnt/Quattro ] # grep -w CPU: /var/run/dmesg.boot [ 20:22 ]
CPU: AMD Athlon(tm) II Neo N36L Dual-Core Processor (1297.87-MHz K8-class CPU)
[ paul@biggiesmalls /mnt/Quattro ] # grep memory /var/run/dmesg.boot [ 20:24 ]
real memory = 4294967296 (4096 MB)
avail memory = 4095074304 (3905 MB)
[ paul@biggiesmalls /mnt/Quattro/torrents ] # uname -a [ 14:07 ]
FreeBSD biggiesmalls 9.0-RELEASE FreeBSD 9.0-RELEASE #0: Tue Jan 3 07:46:30 UTC 2012 root@farrell.cse.buffalo.edu:/usr/obj/usr/src/sys/GENERIC amd64


dd if=/dev/zero of=file bs=1024k count=10000 [ 14:07 ]
10000+0 records in
10000+0 records out
10485760000 bytes transferred in 648.398978 secs (16171771 bytes/sec)

Правда, он забит на 100%:

Quattro 5.2T 5.2T 17G 100% /mnt/Quattro

Состоит массив из 4-х самсунгов по 2 тб.
И, главное, кажется все перепробовал, но принципиальных отличий в скорости так и не заметил.

Как я уже выше по треду ссылался, процессор - важен. Хотя вот 16Mb/sec даже для такого процессора мне кажется маловато.

А там процессор не загружен особо.
Вот я эту запись запустил, и в соседней консоли вывел systat -vm

2 users Load 0,94 0,30 0,21 19 мар 19:50

Mem:KB REAL VIRTUAL VN PAGER SWAP PAGER
Tot Share Tot Share Free in out in out
Act 415540 4544 3254684 13860 233180 count 6
All 2850384 4972 1077125k 65524 pages 27
Proc: Interrupts
r p d s w Csw Trp Sys Int Sof Flt 7 cow 2447 total
104 9756 60 497 2448 1054 19 4 zfod ehci0 ehci
ozfod ohci0 ohci
12,8%Sys 0,9%Intr 0,5%User 0,0%Nice 85,8%Idle %ozfod hdac0 256
| | | | | | | | | | | daefr 182 bge0 257
======+ 5 prcfr 949 ahci0 258
129 dtbuf 18766 totfr 870 hpet0:t0
Namei Name-cache Dir-cache 142837 desvn react 446 hpet0:t1
Calls hits % hits % 44413 numvn pdwak
59 49 83 35708 frevn 14738 pdpgs
intrn
Disks ada0 ada1 ada2 ada3 ada4 pass0 pass1 3387484 wire
KB/t 38,70 41,07 38,17 41,86 16,61 0,00 0,00 111580 act
tps 207 252 181 240 7 0 0 295916 inact
MB/s 7,83 10,12 6,73 9,80 0,11 0,00 0,00 90928 cache
%busy 97 92 100 96 0 0 0 142080 free
427424 buf

Ощущение такое, что операция вообще никак не кешируется. У винтов бизи 100%, при этом трансфер 10 Мб.

Это фрагментация.

Процентов 10 свободных надо иметь, а то плохо все.

Ну вот забили на 100% - теперь не обижайтесь.

Ну вот на пяти вышеупомянутых сигейтах (ada0-ada4) картинка выглядит так:
17,8%Sys   2,2%Intr  0,0%User  0,0%Nice 80,0%Idle        %ozfod       uhci2 uhci
|    |    |    |    |    |    |    |    |    |    |       daefr  1091 hpet0 20
=========+                                                prcfr       uhci3 ehci
                                        22 dtbuf   130053 totfr     1 em0 256
Namei     Name-cache   Dir-cache    269754 desvn          react       hdac0 257
   Calls    hits   %    hits   %      2094 numvn          pdwak  3690 ahci0 258
       3       3 100                    95 frevn          pdpgs       ib_mthca0
                                                          intrn       ib_mthca0
Disks  ada0  ada1  ada2  ada3  ada4   da0 pass0   4637952 wire        ib_mthca0
KB/t    112   113   113   115   115 31,43  0,00     45172 act
tps     760   756   767   758   750     6     0     30932 inact
MB/s  83,46 83,62 84,80 85,37 84,60  0,17  0,00       348 cache
%busy    75    76    76    77    90     1     0   7414948 free
Это mv SOMEDIR /zfs/another-fs/ (большие файлы)

Не сказать, чтобы я был особо доволен, но ~200M чтения и 200 записи одновременно - ну приятно, да.

А не возможен где-то затык? Ну то есть 400MB/s где-то недалеко от PCI-E v2 per lane.

Ну вроде между X58 и IO-чипом рисуют 2Gb/sec: http://en.wikipedia.org/wiki/File:X58_Block_Diagram.png

Поэкспериментировал сегодня.
Собираю ZFS страйп из 4х винтов 1Tb - тест по вышеописаной методике (ВОМ) даёт около 410 MB/sec
Собираю ZFS RAIDZ1 из 4х винтов 1Tb - тест по ВОМ даёт около 75 MB/sec
Както тухло :(
Добавляю ещё один винт.
Собираю ZFS страйп из 5ти винтов 1Tb - тест по ВОМ даёт около 450 MB/sec
выросло, но не сильно, винт другого типа, попроще-помедленней.
Собираю ZFS RAIDZ1 из 5ти винтов 1Tb - тест по ВОМ даёт около 350 MB/sec

"Ниччего не понимаю" ©

А что за процессор?

Я на i7-920 экспериментировал с 4x 2Tb WD Caviar Green. Stripe+mirror оказался медленнее на запись и быстрее на чтение чем RAIDZ. Собственно, неудивительно.

Процессор один и тот-же в случае 4х и 5ти дисков, i7-2600, памяти 16GB.
Удивляет более чем 4х кратный рост скорости в RAIDZ при добавлении одного диска.
При этом в страйпе скорость почти не выросла.

Попробовал на 3х дисках. Чуть медленнее чем на 5ти,
но раза в 3 быстрее чем на 4х.

Магия!

Не может быть 4-й диск (или его кабель, или порт) битым/странным/whatever?

И при 5 дисках это не очень заметно, при 3 - этот порт/кабель не используются?

Я тут просто собирал и из 4 и из 5, результаты получились понятные.

Вроде поймал фефект. FreeNAS 8.2
Диски довольно старые - Seagate Constellation ES 1Tb
двухлетней давности. Эксперименты с размером сектора (512/4K) проводил в конфигурации
страйп. Вроде 4K оказались побыстрее. А вот RAIDZ1 с таким размером сектора оказался
странным. Чётные комбинации - медленные, нечётные - быстрые. пробовал от 3х до 6ти
дисков. Вот такие пироги с котятами.

Ну так у терабайтников сектора то 512 байт. Откуда там 4k взяться то?

Да так-то оно так, но процентов 8-10 выигрыша в страйпе давало.
Да ещё смущала рекомендация
(N+P) with P = 1 (raidz) or 2 (raidz2) and N equals 2, 4, or 8
То-есть как-раз нечётное число дисков в raidz1

Я систематических тестов не делал, но вот с 4 и 5 дисками маленько поигрался - и результаты получил предсказуемые (5 - предсказуемо быстрее).

НО
1) Это единственный тест, запись-чтение больших файлов
2) ZFS v28 (т.е. FreeBSD 9), на восьмерке вроде более старая и все может быть иначе.

При нормальном размере блока ashift: 9
фефект пропал, и система ведёт себя предсказуемо,
т.е. скорость растёт монотонно по мере добавления дисков.
Как в страйпе так и в raidz1.

Не, ну вам же никто не гарантировал, что число блоков (512-байтных) на дорожке кратно 8-ми. И это почти гарантированно не так, число секторов по диску разное на разных радиусах.

То есть единичная запись с некоей (довольно большой, наверное, собственно ~8/число секторов на дорожке) вероятностью оказывается размазанной по нескольким дорожкам. А это seek и почти целый оборот ожидания нужного сектора.
Почти целый оборот - потому что мы пишем в хвост одной дорожки и начало следующей.

Понятно, что ничего хорошего от этого получиться не может.

Комрады, 'zfs best practice' при создании массивов raidz[i] заключается в том, чтобы количество дисков массива, за минусом четности, равнялось степени двойки, тогда достигается оптимальное распределение блоков данных при чтении/записи по дискам массива. Т.е. для массива raidz1 оптимальными по быстродействию являются конфигурации:
2+1 = 3диска;
4+1 = 5 дисков;
8+1 = 9 дисков.
Для массива raidz2:
2+2 = 4 диска;
4+2 = 6 дисков;
8+2 = 10 дисков.
Для raidz3 - соответственно.
Создавать vdev raidz[i] из более чем 8+i физических дисков - не рекомендуется, для большего числа дисков рекомендуется создавать страйпы из vdev raidz[i].
Таковы официальные рекомендации от разработчиков, приведенные в документации Oracle (Sun).