Translate

понеділок, 28 жовтня 2013 р.

ZFS filesystem on Linux (configuration and performance)

ZFS (Zettabyte File System) - 128-бітна файлова система, створена в Sun Microsystems в 2004 році. Вона об'єднує концепції файлової системи, менеджера логічних дисків і фізичних носіїв, новаторську структуру даних на дисках, а також просте управління томами зберігання даних. ZFS не без підстав називають найбільш функціональною у світі файловою системою.

Подейкують, що ZFS - це розробка інженерів, котрих перекупив Sun (тепер Oracle) в NetApp, через що це ніби як копія WAFL.
Підтримка файлової системи ZFS у Лінуксі реалізована у якості модуля, адже включити його прямісінько в ядро не дозволяє конфлікт ліцензій GPL v2 та CDDL, під якою і було випущено ZFS.

Часом ZFS докоряють тим, що це не unix-way включати купу можливостей (LVM, Raid та ін) в саму файлову систему, краще щоб кожну роль виконувала окрема програма. Проте з іншої сторони таким чином досягається кращий рівень інтегрованості між собою цих можливостей в одній системі.

Починаючи з травня 2013 (версія 0.6.1) файлову систему вважають готовою для використання в  production ситемах.

Наведу приклад установки і налаштування ZFS-розділу в Ubuntu 12.04.3.  Підтримка ZFS в Debian-подібних системах реалізована через модулі dkms, пакети яких розповсюджуються через ppa-репозиторій. Тож спершу додамо репозиторій і встановимо модулі:

# add-apt-repository ppa:zfs-native/stable
# apt-get update
# apt-get upgrade
# apt-get install ubuntu-zfs

Звісно, що по залежностям будуть завантажені деякі додаткові пакети:

The following NEW packages will be installed:
  binutils build-essential cpp cpp-4.6 dkms dpkg-dev fakeroot g++ g++-4.6 gcc gcc-4.6 libalgorithm-diff-perl libalgorithm-diff-xs-perl libalgorithm-merge-perl libc-dev-bin libc6-dev libdpkg-perl libgomp1 libmpc2 libmpfr4 libnvpair1
  libquadmath0 libstdc++6-4.6-dev libuutil1 libzfs1 libzpool1 linux-libc-dev make manpages-dev spl spl-dkms ubuntu-zfs zfs-dkms zfsutils
The following packages will be upgraded:
  mountall
1 upgraded, 34 newly installed, 0 to remove and 0 not upgraded.
Need to get 34.5 MB of archives.
After this operation, 101 MB of additional disk space will be used.
Do you want to continue [Y/n]?

І після їх завантаження почнеться збирання dkms-модулів:

zavl:
Running module version sanity check.
 - Original module
   - No original module exists within this kernel
 - Installation
   - Installing to /lib/modules/3.8.0-32-generic/updates/dkms/

zcommon.ko:
Running module version sanity check.
 - Original module
   - No original module exists within this kernel
 - Installation
   - Installing to /lib/modules/3.8.0-32-generic/updates/dkms/

znvpair.ko:
Running module version sanity check.
 - Original module
   - No original module exists within this kernel
 - Installation
   - Installing to /lib/modules/3.8.0-32-generic/updates/dkms/

zpios.ko:
Running module version sanity check.
 - Original module
   - No original module exists within this kernel
 - Installation
   - Installing to /lib/modules/3.8.0-32-generic/updates/dkms/

zunicode.ko:
Running module version sanity check.
 - Original module
   - No original module exists within this kernel
 - Installation
   - Installing to /lib/modules/3.8.0-32-generic/updates/dkms/

zfs.ko:
Running module version sanity check.
 - Original module
   - No original module exists within this kernel
 - Installation
   - Installing to /lib/modules/3.8.0-32-generic/updates/dkms/

depmod....

DKMS: install completed.

Після установки варто перевантажити ОС і перевірити статус підключення модулів:

# lsmod | grep zfs
zfs                  1151914  0
zcommon                47225  1 zfs
znvpair                88641  2 zfs,zcommon
zavl                   15010  1 zfs
zunicode              331225  1 zfs
spl                   172744  5 zfs,zcommon,znvpair,zavl,zunicode

Після кожного оновлення ядра дані модулі будуть перезбиратись, тож варто задумуватись чи варто його оновлювати взагалі (або робити це уважно), адже zfs-розділи можуть просто "відпасти".

Модулі було встановлено і скомпільовано, тож переходимо до створення ZFS-розділу. Для цього я використав 3 диски, що було земульвано за допомогою VirtualBox (хоча звісно можна використовувати і логічні розділи):

# ls -lah /dev/disk/by-id/
.......
lrwxrwxrwx 1 root root   9 Oct 21 18:41 scsi-SATA_VBOX_HARDDISK_VB2db3380f-05b3e2ac -> ../../sdb
lrwxrwxrwx 1 root root   9 Oct 21 18:41 scsi-SATA_VBOX_HARDDISK_VB912d411b-f82070cf -> ../../sdd
lrwxrwxrwx 1 root root   9 Oct 21 18:41 scsi-SATA_VBOX_HARDDISK_VBcc5472cc-e9013683 -> ../../sdc
.......

Для створення розділу радять використовувати id дисків, а не назви їх блочних пристроїв:

# zpool create -f -o ashift=12 -m /media/zfs_mount_point zfspoll raidz scsi-SATA_VBOX_HARDDISK_VB2db3380f-05b3e2ac scsi-SATA_VBOX_HARDDISK_VB912d411b-f82070cf scsi-SATA_VBOX_HARDDISK_VBcc5472cc-e9013683

ashift=12 - розмір сектора. 2^12=4096 байт.
-m /media/zfs_mount_point - точка монтування, після виконання даної команди розділ одразу буде примонтовано.
zfspoll - назва пула.
raidz - створити із дисків вдосконалену версію RAID5. Також можна указати режим mirror для створення RAID1 чи просто опустити цей параметр, якщо необхідний звичайний розділ та ін.
SATA_VBOX_HARDDISK_VBcc5472cc-e9013683 - id кожного із дисків.

Перевіримо статут новоствореного zfs-пулу:

# zpool status
  pool: zfspoll
 state: ONLINE
  scan: none requested
config:

NAME                                             STATE     READ WRITE CKSUM
zfspoll                                          ONLINE       0     0     0
 raidz1-0                                       ONLINE       0     0     0
   scsi-SATA_VBOX_HARDDISK_VB2db3380f-05b3e2ac  ONLINE       0     0     0
   scsi-SATA_VBOX_HARDDISK_VB912d411b-f82070cf  ONLINE       0     0     0
   scsi-SATA_VBOX_HARDDISK_VBcc5472cc-e9013683  ONLINE       0     0     0

errors: No known data errors

А так можна переглянути опції з якими було створено пул zfspoll:

# sudo zfs get all zfspoll
NAME     PROPERTY              VALUE                   SOURCE
zfspoll  type                  filesystem              -
zfspoll  creation              Mon Oct 21 18:48 2013   -
zfspoll  used                  709K                    -
zfspoll  available             19.5G                   -
zfspoll  referenced            181K                    -
zfspoll  compressratio         1.00x                   -
zfspoll  mounted               yes                     -
zfspoll  quota                 none                    default
zfspoll  reservation           none                    default
zfspoll  recordsize            128K                    default
zfspoll  mountpoint            /media/zfs_mount_point  local
..............
zfspoll  mlslabel              none                    default
zfspoll  sync                  standard                default
zfspoll  refcompressratio      1.00x                   -
zfspoll  written               181K                    -
zfspoll  snapdev               hidden                  default

У /etc/fstab розділ не прописується, тож і шукати його там не слід, але df звісно покаже всю правду:

# df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda1        11G  1.5G  8.8G  15% /
udev            2.0G  4.0K  2.0G   1% /dev
tmpfs           791M  316K  791M   1% /run
none            5.0M     0  5.0M   0% /run/lock
none            2.0G     0  2.0G   0% /run/shm
zfspoll          20G  128K   20G   1% /media/zfs_mount_point

Досить часто відключають оновлення access time (noatime) для файлів, що може дещо підвищити продуктивність дискової системи і в zfs це робиться таким чином:

# zfs set atime=off zfspoll

Інтенсивність використання пулу можна вивести таким чином:

# zpool iostat 5
               capacity     operations    bandwidth
pool        alloc   free   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
zfspoll     1.35M  29.7G      0      0    468    798

А точку монтування всіх пулів так:

# zfs list

NAME      USED  AVAIL  REFER  MOUNTPOINT
zfspoll 826K 19.5G 282K /media/zfs_mount_point

Включити компресію lz4 для пула:

# zfs set compression=lz4 zfspoll
# zfs list -o compression

COMPRESS
lz4


Так можна зробити снапшот діючого розділу і примонтувати його:

# zfs snapshot zfspoll@snapshot
# mkdir /media/zfspoll_snapshot
# mount -t zfs snapshot zfspoll@snapshot /media/zfspoll_snapshot

Виведення всіх наявних снапшотів:

# zfs list -t snapshot
NAME                USED  AVAIL  REFER  MOUNTPOINT
zfspoll@snapshot    117K      -   282K  -
zfspoll@snapshot2  10.7K      -  1.06G  -

Повернення до стану снапшоту (rollback) файлової системи:

# zfs rollback zfspoll@snapshot

І всі зміни будуть затерті до попереднього стану. Також zfs-пули варто часом (наприклад, щонеділі за допомогою сron-а ) перевіряти на предмет певних сбоїв, для чого запускається scrub:

# zpool scrub zfspoll

Під час його запуску загальний відгук файлової системи може дещо знизитись.
Також zfs-пули можна імпортувати та експортувати чи додати окремий розділ у якості кеша, що може значно підвищити швидкість роботи розділу (особливо якщо в якості кеша використати SSD).

Видалити pool можна так (видаляться також снапшоти пула, якщо такі присутні):

# zpool destroy zfspoll

Переглянути історію всіх існуючих пулів можна за допомогою команди:

# zpool history
History for 'zfspoll2':
2013-10-24.10:01:27 zpool create -f -o ashift=12 -m /media/zfs_mount_point zfspoll2 scsi-SATA_VBOX_HARDDISK_VB2db3380f-05b3e2ac scsi-SATA_VBOX_HARDDISK_VB912d411b-f82070cf scsi-SATA_VBOX_HARDDISK_VBcc5472cc-e9013683
2013-10-26.20:32:27 zfs set atime=off zfspoll2


Тепер пару слів щодо швидкості роботи файлової системи. Я провів тестування за допомогою програми bonnie++ ext4 та zfs розділів під ОС Ubuntu 12.04 на одній і тій самій віртуальній машині Virtualbox. Розділи були змонтовані із дефолтними значеннями та опціями noatime:

$ mount
...
/dev/sda1 on / type ext4 (rw,noatime,errors=remount-ro)
zfspoll2 on /media/zfs_mount_point type zfs (rw,noatime)
...

zfs-pool було створено як звичайний пул без жодних raid і т.п. Команда, що була подана на тестування кожного із розділів і виглядає так:

# bonnie++ -d /mount_point -m 'some_name' -n 100:16384:0:20 -u root > out.csv && cat out.csv | bon_csv2html > page.html

-d /mount_point - адреса примонтованого розділу.
-m 'some_name' - назва, якою буде іменуватись поле документу
-n 100:16384:0:20 - протестувати швидкість створення 100 файлів розміром від 0 до 16384 байтів в 20 піддиректоріях
bon_csv2html - підпрограма, що перетворює результуючу csv-таблицю в симпатичний html-документ.

Результати виглядають наступним чином. Для ext4-розділу:


Для zfs-розділу тієї ж системи:


Дам деякі пояснення до термінології наведеної в таблиці:

Sequential Output - послідовний запис на розділ. Char - побайтний, Block - блоками по 8912 байт. Rewrite - читання, а потім запис файлу, що був попередньо затертий.
Sequential Input - послідовне читання із розділу.
Random Seeks - кількість блоків до яким зміг звернутись Bonnie за 1 секунду.
Latency - затримка перед виконанням кожної операції.
++++ - тест закінчився настільки швидко, що Bonnie не встиг зареєструвати результат.
Далі відображаються результати створення 100 файлів розміром від 0 до 16384 байтів в 20 піддиректоріях і що вони означають легко здогадатись зі слів написаних мною вище.

Як бачимо на Linux ZFS значно програє в швидкості, причому абсолютно у всіх тестах. Тому поки для Linux, якщо для вас важлива швидкість, ZFS - не найкращий вибір. Ось також результати тестів Phoronix http://www.phoronix.com/scan.php?page=news_item&px=MTM1NTA .

Подейкують, що на Solaris ZFS має показати значно кращі результати, адже ця файлова система "рідна" для неї. І я перевірив цю легенду:


Для тестування я використав той же Virtualbox із 4 ГБ RAM, процесором AMD Phenom II X4 B55 (одне ядро, як і в попередніх тестах) та Oracle Solaris 11.1. Як бачимо результати справді хороші, майже такі ж як і для EXT4 в Ubuntu.

Про деякі проблеми використання ZFS на Linux можна почитати тут http://habrahabr.ru/post/153461/

Буду вдячний, якщо помітите будь-які неточності в статті, про котрі можна згадати в коментарях.

Посилання:

Немає коментарів:

Дописати коментар