На современных дисках всё чаще используется физический размер сектора равный 4096 байт. И часто можно услышать, что использование на таких дисках сектора размером 512 байт может отрицательно сказаться на производительности. Так, например, после замены вышедшего из строя HDD в одной системе было получено сообщение:
# zpool status green
pool: green
state: ONLINE
status: One or more devices are configured to use a non-native block size.
Expect reduced performance.
action: Replace affected devices with devices that support the
configured block size, or migrate data to a properly configured
pool.
scan: none requested
config:
NAME STATE READ WRITE CKSUM
green ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
gpt/rootdisk ONLINE 0 0 0 block size: 512B configured, 4096B native
gpt/rootmirr ONLINE 0 0 0
Новый диск с GPT меткой rootdisk оказался с размером сектора 4К, что не понравилось ZFS, потому что пул сконфигурирован для дисков с размером сектора 512 байт.
Проверить размер сектора для пула можно командой:
# zdb green | grep ashift
ashift: 9
Два в указанной в ashift степени и является размером сектора. В данном случае - 29 = 512, что корректно для старых дисков.
В связа с тем, что эта система не являлась продуктивной, но была возможность несколько раз прогнать одну и туже задачу, было решено посмотреть, Expect reduced performance - это сколько?
В качестве нагрузки было взято приложение, которое брало ZIP архивы, расположенные на другом ZFS пуле, извлекало из них XML файлы, брало определённые поля этих XML файлов и загружала полученную информацию в СУБД PostgreSQL, хранящую файлы на исследуемом пуле. Таким образом был взять сферический конь в вакууме, который и использовал процессорные ресурсы, и зависел от производительности других носителей. В общем старался быть похожим на работу обычного приложение, а не простого абстрактного нагрузчика.
После запуска приложения в выводе gstat можно было наблюдать следующую картину:
# gstat -a -f gpt/ -I 60s
dT: 60.005s w: 60.000s filter: gpt/
L(q) ops/s r/s kBps ms/r w/s kBps ms/w %busy Name
2 88 5 62 13.3 60 1701 6.1 76.6| gpt/rootdisk
2 93 8 71 6.0 62 1701 1.4 30.0| gpt/rootmirr
Как можно заметить, диск с физическим размером сектора 4K оказался в 2 раза более нагружен, имеет в 2 раза хуже время ответа на операциях чтения и в 4 раза хуже время ответа на операциях записи. Такая просадка производительности легко объяснима: операционная система отправляет диску команду на запись 512 байт, так как считает, что размер сектора на диске равен 512 байтам, но, фактически, для замены части сектора жёсткому диску необходимо сначала прочитать всё содержимое изменяемого сектора, заменить в нём 512 байт и записать обратно.
Пересоздав пул с правильным размером сектора, проверяем настройки пула:
# zdb green | grep ashift
ashift: 12
Перезапускаем приложение и смотрим в gstat:
gstat -a -f gpt/ -I 60s
dT: 60.005s w: 60.000s filter: gpt/
0 87 1 35 9.7 66 4761 1.9 24.3| gpt/rootdisk
0 87 1 46 9.2 65 4761 2.5 29.2| gpt/rootmirr
Можно заметить, что теперь более нагруженным оказался более старый диск, но разница уже не столь велика.
А что же со стороны приложения? Приложение после обработки очередного архива умело вывести среднюю скорость обработки в количестве обработанных XML файлов в секунду. Вот некоторые значения:
Контрольная точка |
Было |
Стало |
1000 |
10.8 |
16.9 |
67842 |
5.7 |
11.5 |
128160 |
5.6 |
11.1 |
185980 |
5.4 |
10.7 |
Таким образом, правильно созданный пул увеличил скорость работы приложения примерно в 2 раза, что более чем заметно.
Исходя из выщесказанного, во избежание проблем с производительностью дисковой подсистемы после замены дисков я бы рекомендовал всегда создавать ZFS пулы ориентируясь на размер сектора 4К.