Файловая система ZFS — достаточно продвинутая и многофункциональная. Тут вам и дедупликация, и сжатие, и контрольные суммы, продвинутое кэширование и т.д. Одно из хороших применений ZFS — создание ZVOL на ее основе и дальнейшее расшаривание их по iSCSI для любых целей. Плюсы достаточно очевидны: надежность хранения как на любом RAID, отсутствие дорогих аппаратных RAID-контроллеров, быстрое восстановление массива в случае замены диска (ZFS не перестраивает весь массив, как классические RAID — перестраивается только реально необходимое место). Но потом всплывают малоизвестные минусы…
Итак, при создании ZVOL с параметрами по умолчанию (а именно volblocksize=8k) на raidz и заполнении всего раздела данными мы можем внезапно обнаружить очень немаленький оверхэд по реальному размеру, занимаемому этим разделом в массиве. Причем речь идет не о 10%, которые можно было бы простить «на служебные нужды». Речь легко может идти о 60-70% оверхэда. Да-да, при размере ZVOL в 1 ТБ, он вполне может занять 1.7 ТБ в вашем массиве. И произойдет это ровно в тот момент, когда вы этого ожидаете меньше всего — массив заполнен полезными данными, а найти такое количество места, чтобы быстро сбросить туда всё — нереально.
К сожалению, никаких «магических» способов исправить такую ситуацию, когда она уже случилась — нет. Более того, скорее всего вам придется уничтожить весь zpool для того, чтобы вернуть его к жизни — так как даже при удалении всех zvol в массиве вы не сможете создать такое же количество новых zvol с тем же размером. Т.е. только zfs destroy/zpool destroy/zpool create/zfs create.
А теперь немного цифр. Я провел тесты для определения потерь места на массиве raidz из 8 HDD с разными volblocksize. Ниже в таблице представлены результаты тестов. Методика такая: создаем ZVOL на 5 ГБ с размерами блоков 4k, 8k, 16k, 32k, 64k и 128k. После этого при помощи dd с параметром bs=8k записываем данные на раздел пока dd не скажет, что место закончилось. Далее при помощи команды zfs get all zpool/zvol1 смотрим на параметр used — он-то и расскажет о реально занятом месте.
Размер блока | 4k | 8k | 16k | 32k | 64k | 128k |
Занятое место | 8,52 ГБ | 8,48 ГБ | 6,34 ГБ | 5,28 ГБ | 5,27 ГБ | 5,01 ГБ |
% | 170,4 | 169,6 | 126,8 | 105,6 | 105,4 | 100,2 |
Для моих целей прекрасно подошел размер блока 128к, т.к. мелкие файлы на нем не хранятся и потери в таком случае будут минимальны. Следует учитывать, что эти сведения актуальны для массива raidz из 8 дисков. Если у вас raidz2 или другое количество дисков — данные будут другими. Как вариант, вы можете использовать комбинации stripe и mirror — они лишены этой неприятной особенности.