Marvin Pascale

[B.Log]

04 Settembre 2021

ZFS

MongoDB ZFS non è di certo nuovo sul mercato ma è tra i filesystem più versatili che si possano incontrare. La prima versione uscì nel novembre del 2004 su OpenSolaris ma da allora sono cambiate molte cose.

Tra le caratteristiche più interessanti di ZFS troviamo:

  • capacità;
  • copy-on-write;
  • snapshot;
  • compressione;
  • deduplica.

La compressione e la deduplica a mio avviso lo rendono il filesystem perfetto per grosse quantità di dati (archivi, backup, ecc).

Mani in pasta

Vediamo come installare OpenZFS su una macchina basata su RHEL8.

# source /etc/os-release
# dnf install epel-release -y
# dnf install https://zfsonlinux.org/epel/zfs-release-2-2$(rpm --eval "%{dist}").noarch.rpm
# dnf install kernel-devel zfs -y
# dnf update -y

Per essere sicuri di caricare i moduli nel kernel all’avvio basta

# sh -c "echo zfs> /etc/modules-load.d/zfs.conf"
# reboot

Zpool e volumi

In ZFS abbiamo due oggetti con i quali familiarizzare: i zpool e i volumi.

Uno zpool è composto da uno o più dischi (hard drive) ed è paragonabile al volume group di LVM con la grande differenza di essere utilizzabile fin da subito.

Un volume è contenuto all’interno di un zpool (ne eredita le configurazioni) e permette di impostare delle soglie (quote) e cosa ancora più interessante permette di essere formattato con il filesystem che più ci piace (xfs, ext4, ecc).

Livelli di ridondanza

ZFS permette di avere un RAID software a livello di zpool definendo quelle che sono le caratteristiche di ridondanza e altra affidabilità.

RAID-0 è scontato; con 3 dischi da 4TB otteniamo un zpool da 12TB ma in caso di guasto anche di un solo disco i dati sono persi.

RAID-1 funziona con almeno 2 dischi e abbiamo una replica di tutti i dati su tutti i dischi; esempio 2 dischi da 4TB fanno un zpool da 4TB con i file duplicati. In caso di guasto di un disco i dati saranno ancora disponibili.

RAID-10 è la fusione tra RAID-0 e RAID-1 ovvero con un set di 4 dischi da 4TB ottieni un zpool da 4TB con velocità in lettura/scrittura migliori ai precedenti (minimo 4 hard drive).

RAIDZ-1 è uguale a un canonico RAID 5, con un minimo 3 dischi, duplica i dischi come un RAID-1, ma usa una suddivisione dei dati a livello di blocco, distribuendo i dati di parità uniformemente tra tutti i dischi che lo compongono. Con 3 dischi da 4TB ottieni un zpool da 8TB.

RAIDZ-2 fa una replica dei dati come RAID-1, ma usa una divisione a livello di blocchi con i dati di parità distribuiti due volte tra tutti i dischi. Con 4 dischi da 4TB ottieni un zpool da 8TB.

Nella pratica

Dopo aver installato tutto il necessario e aver riavviato la vostra istanza con pochi semplici passi avrete a disposizione tutti i vantaggi di ZFS.

Con l’aiuto di Terraform avviamo una nuova istanza:

resource "hcloud_ssh_key" "userkey" {
  name = "Marvin Pascale"
  public_key = file("~/.ssh/id_rsa.pub")
}

resource "hcloud_server" "rocky" {
  name = "nodo1"
  image = "rocky-8"
  server_type = "cx11"
  backups = false
  location = "nbg1"
  user_data = file("kickstart_centos.sh")
  ssh_keys = [hcloud_ssh_key.userkey.name]
}

resource "hcloud_volume_attachment" "rocky" {
  volume_id = hcloud_volume.rocky.id
  server_id = hcloud_server.rocky.id
  automount = false
}

resource "hcloud_volume" "rocky" {
  name = "dataDisk"
  size     = 20
  location = "nbg1"
}

output "Public_IP" {
    value = "${hcloud_server.rocky.ipv4_address}"
}

Se tutto va per il meglio dovremmo avere una istanza con un disco di boot e un disco /dev/sdb pronto per essere utilizzato.

A questo punto, dopo esserci connessi in ssh, eseguiamo i passi descritti nel paragrafo relativo all’installazione.

Creiamo il nostro zpool

# zpool create data sdb

se non diversamente speficifato ZFS monterà il nostro zpool in /data (che è anche il nome del pool).

#  df -hT
Filesystem     Type      Size  Used Avail Use% Mounted on
devtmpfs       devtmpfs  867M     0  867M   0% /dev
tmpfs          tmpfs     885M     0  885M   0% /dev/shm
tmpfs          tmpfs     885M   17M  869M   2% /run
tmpfs          tmpfs     885M     0  885M   0% /sys/fs/cgroup
/dev/sda1      ext4       19G  1.6G   17G   9% /
/dev/sda14     vfat       64M  5.8M   59M   9% /boot/efi
tmpfs          tmpfs     177M     0  177M   0% /run/user/0
data           zfs        19G  128K   19G   1% /data

Il pool è subito utilizzabile ma se fosse necessario possiamo creare dei volumi e formattarli diversamente. Questo è utile in quelle situazioni in cui il filesystem è un requisito di un software (es: MongoDB consiglia caldamente di utilizzare xfs).

Ipotizziamo di voler creare un volume da 5GB (mongo) e volerlo formattare in xfs.

# zfs create -V 5gb data/mongo
# mkfs.xfs /dev/data/mongo
# mkdir /mnt/mongo && mount /dev/data/mongo /mnt/mongo
# df -hT
Filesystem     Type      Size  Used Avail Use% Mounted on
devtmpfs       devtmpfs  867M     0  867M   0% /dev
tmpfs          tmpfs     885M     0  885M   0% /dev/shm
tmpfs          tmpfs     885M   17M  869M   2% /run
tmpfs          tmpfs     885M     0  885M   0% /sys/fs/cgroup
/dev/sda1      ext4       19G  1.6G   17G   9% /
/dev/sda14     vfat       64M  5.8M   59M   9% /boot/efi
tmpfs          tmpfs     177M     0  177M   0% /run/user/0
data           zfs        14G  128K   14G   1% /data
/dev/zd0       xfs       5.0G   68M  5.0G   2% /mnt/mongo

I volumi sono legati allo zpool di appartenenza e ne ereditano i settaggi.

Se volessimo attivare compressione in zstandard e deduplica :

# zfs set compression=zstd data
# zfs set dedup=on data
# zdb -b data

Traversing all blocks to verify nothing leaked ...

loading concrete vdev 0, metaslab 38 of 39 ...

	No leaks (block sum matches space maps exactly)

	bp count:                  1414
	ganged count:                 0
	bp logical:            16072192      avg:  11366
	bp physical:           10907136      avg:   7713     compression:   1.47
	bp allocated:          11032576      avg:   7802     compression:   1.46
	bp deduped:                   0    ref>1:      0   deduplication:   1.00
	Normal class:          11002368     used:  0.05%

	additional, non-pointer bps of type 0:         30
	Dittoed blocks on same vdev: 62

Se volessimo creare uno snapshot del nostro filesystem:

# zfs snapshot data/mongo@preupdate

per verificare se esistono snapshots

# zfs list -t snapshot
NAME                   USED  AVAIL     REFER  MOUNTPOINT
data/mongo@preupdate     0B      -     10.4M  -

per fare rollback ad uno snapshot

# zfs rollback data/mongo@preupdate

per eliminare uno snapshot

# zfs destroy data/mongo@preupdate

Le opinioni in quanto tali sono opinabili e nulla ti vieta di approfondire l’argomento.

Risorse: