Deepdive – Thin provisioning Reclaim Space (VAAI / UNMAP)

Le Reclaiming Space (UNMAP)

Qu’est-ce que c’est ?

Cela consiste à réclamer des blocs de stockage inutilisés sur une LUN provisionnée en mode dynamique (thin).

Avant d’expliquer pourquoi il est utile de faire du reclaiming space, attardons nous sur les deux modes de provisionnement de LUN existant au sein d’une baie SAN.

Le provisionnement statique (thick):

C’est le modèle traditionnel de provisionnement de stockage. Les blocs sont réservés sur le pool de disque de la baie SAN à la création de la LUN. En mode thick, tous les blocs utilisés ou non sur les disques physiques sont mappés à la LUN. Avec le provisionnement statique, une quantité d’espace de stockage est prévue à l’avance en prévision des futurs besoins de stockage. Toutefois, l’espace peut rester inutilisé et entraîner une sous-utilisation de la capacité de stockage.

Ci-dessous un exemple de RAID groupe de 5 disques de 10GB et 6 LUNs en mode thick :

Chaque LUN (de couleur différente) est constituée de tranche de 10Go sur les disques disponibles dans le raid group.

Un espace de 5x10GB est utilisé pour créer une LUN. Chaque LUN est répartie sur les disques de 1 à 5.

Dans ce cas, 100% de l’espace physique disponible est consommé mais il est rare que les LUNs soient 100% utilisées et cela peut engendrer un gaspillage d’espace.

Le provisionnement dynamique (thin):

À la différence du provisionnement statique, cette méthode se base sur une allocation flexible (à la demande) de l’espace de stockage, ce qui élimine les problèmes de sous-utilisation du stockage. Vous pouvez utiliser deux modèles de provisionnement dynamique, au niveau de la baie et au niveau du disque virtuel de la VM.

Ci-dessous un exemple de RAID groupe de 5 disques de 10GB et 6+(1) LUNs en mode thin :

En mode thin, seul les blocs utilisés sur les disques physiques sont mappés, laissant de l’espace pour de nouvelles LUNs.

Dans cette exemple, aucune de ces LUNs n’est pleinement utilisées et ne consomment sa capacité théorique. Cela signifie que le pool d’espace peut être over-provisionned (sur provisionné) et qu’une sixième nouvelle LUN peut être créée. Le mode thin permet d’allouer plus de capacité logique qu’il n’en n’existe réellement. Par contre, cela ne signifie pas que les ressources sont infinies car si tous les blocs venaient à être écrit évidemment l’espace physique serait épuisé.

Maintenant que nous en savons un peu plus sur les différents modes de provisionnement, attardons nous sur le mode dynamique (thin).

Lorsque vous présentez une LUN à un hôte, elle est formatée avec un system de fichier (NTFS pour Windows, VMFS pour ESXi, EXT4 pour Linux, etc …). Un système de fichier possède un certain format standardisé qui détermine ou sont situés les fichiers d’indexation et la méthode utilisée pour stocker les fichiers sur le disque.

Exemple d’un volume VMFS:


Capacité libre = Libre jamais utilisé

Si nous regardons l’occupation du volume, nous voyons les différents blocs, leurs emplacements, leurs tailles, etc …

Mais que se passe-t-il sur notre volume en Thin si dans le système de fichier VMFS nous supprimons des fichiers (VMs) ?

Capacité libre = Libre jamais utilisé + Libre VM effacée ou déplacée

Il apparait clairement qu’un grand nombre de blocs des disques mappés à la LUN sont inutilisés.

La plupart des systèmes de fichiers suppriment un fichier en supprimant l’entrée dans son index plutôt que d’écraser physiquement le contenu du fichier avec des zéros binaires. Ceci est rapide et efficace, pas forcément best practice en terme de sécurité. En effet, les données supprimées ne sont pas écrasées et il est donc logique que certains outils soient en mesure de récupérer les informations. Le problème vient du fait que la plupart des baies ne sont pas conscientes du système de fichier qui repose sur les LUNs et ne sont pas capable de détecter une suppression logique de fichier.

Cela signifie donc que la suppression de fichiers ne permettra pas de libérer l’espace inutilisé dans le pool de blocs libres du volume.

Cette faiblesse vient d’un manque de communication entre le système de fichier et le stockage. Il n’existe aucun mécanisme permettant de signaler quand l’espace n’est plus utilisé.

Et voici ce qui va se produire sur notre volume :

Les blocs grisés représentent le dead space ! L’espace qui n’est plus utilisé dans le système de fichier VMFS suite à la suppression d’une VM, un SVMotion, une consolidation/suppression de snapshot, etc … Au niveau du datastore VMFS, cet espace est marqué comme libre mais au niveau de la LUN sur la baie cet espace est encore marqué comme utilisé.

Comment récupérer cet espace ?

Pour remédier à ce problème du thin provisionning, le T10 Technical Committee a établi la spécification (SBC-3 / SCSI Block Commands3) qui définit la commande SCSI UNMAP

Toutefois, pour utiliser cette commande, il est non seulement nécessaire d’avoir du matériel SCSI compatible T10 SBC-3, mais aussi de passer par une API comme les VAAI pour vSphere, IOCTL DSM pour Windows, etc …

L’unmapping va permettre de supprimer la relation entre l’adressage LBA (Logical Block Addressing) des secteurs des disques durs et les blocs physiques affectés à la LUN.

Cette action aussi connue sous le nom de HOLE PUNCHING agit au sein du système de fichiers en marquant une partie des fichiers ainsi que son stockage associé comme étant inutile afin de pouvoir libérer l’esprit espace.

Ci-dessous, un exemple de l’espace disque mesuré coté LUN sur la baie (à gauche) et sur le volume VMFS (à droite). La LUN utilise 2To, mais le volume VMFS affiche 500Go d’espace libre.

Cela signifie que ce LUN a probablement 500Go d’espace mort.

Pour récupérer nos 500Go de dead space , VMware a introduit depuis la version 5.0 d’ESXi une nouvelle fonctionnalité appelée Space Reclamation. Cette dernière est apportée par la primitive UNMAP des VAAI (VMware vSphere API for Array Integration). Cette fonctionnalité va permettre à l’hyperviseur ESXi d’informer la baie de stockage d’une suppression/déplacement de fichier ou VM d’un datastore en mode thin. L’hôte va indiquer à la baie les blocs inutilisés pouvant être démappés et réaffectés au pool d’espace libre.

Vérifier si votre baie support le space reclaiming :

Pour être en mesure d’utiliser cette primitive SCSI UNMAP, votre baie doit être capable d’exploiter les VAAI. Il est possible de vérifier que le hardware accélération est supporté par la baie mais cela n’indique pas exactement quelles sont les primitives supportées.

Depuis le vSphere Client classique :

Ou

Depuis le vSphere Web Client :

Pour vérifier les primitives supportées par notre baie de stockage, il nous faut lister les volumes et récupérer leurs NAA id.

esxcli  storage vmfs extent list

naa.xxxxxxxxxxxxxxxxxxxx

naa.xxxxxxxxxxxxxxxxxxxx

naa.xxxxxxxxxxxxxxxxxxxx

La commande suivante va nous montrer des informations telles que la révision du firmware, l’état ​​de provisionnement thin, le filtre VAAI et le statut VAAI.

esxcli storage core device list –d naa_ID

Vérifier la liste des primitives supportées :

esxcli storage core device vaai status get -d l.xxxxxxxxxxxxxxxxxxxx

La primitive Delete Status signifie que l’hôte est capable d’envoyer des commandes SCSI UNMAP à la baie lors d’une opération de récupération d’espace.

Nous avons validé que notre baie de stockage est capable de récupérer l’espace mort.

Ci-dessous une vue sur l’espace provisionné et utilisé d’un point de vue VMDK :

Nous avons déployé une machine virtuelle avec un VMDK de 15Go sur un volume VMFS-5 reposant sur une LUN en thin.

La VM sur ce datastore utilise environ 8.82Go de l’espace depuis la création de son VMDK en mode thin.

Jetons un coup d’œil au datastore:

Comme on peut le voir à partir du retour de commande ci-dessous, nous avons un datastore de 50 Go formaté avec en VMFS-5 sur lequel il reste 40.0Go d’espace utilisable.

# vmkfstools -Ph -v 1 /vmfs/volumes/source-datastore/
File system label (if any): source-datastore
Mode: public ATS-only
Capacity 49.8 GB, 40.0 GB available, file block size 1 MB
Volume Creation Time: Tue Nov 25 11:13:47 2015
Files (max/free): 130000/129975
Ptr Blocks (max/free): 64512/64483
Sub Blocks (max/free): 32000/31998
Secondary Ptr Blocks (max/free): 256/256
File Blocks (overcommit/used/overcommit %): 0/10006/0
Ptr Blocks  (overcommit/used/overcommit %): 0/29/0
Sub Blocks  (overcommit/used/overcommit %): 0/2/0
UUID: 4f96b6c3-dcc7c210-a943-001b217b4553
Partitions spanned (on « lvm »):
naa.60a98000572d54724a346a3435766a56:1
DISKLIB-LIB   : Getting VAAI support status for /vmfs/volumes/source-datastore/
Is Native Snapshot Capable: NO

Nous pouvons clairement voir que 10006 blocs consommés x 1Mo sur le volume VMFS-5 donne environ 9.77Go.

L’autre information à prendre en compte est l’espace consommé par les métadonnées VMFS sur le volume VMFS-5. La meilleure façon d’obtenir une approximation de cette espace est d’utiliser la commande « du » sur le datastore:

# du -h /vmfs/volumes/source-datastore/
8.8G    /vmfs/volumes/source-datastore/Win
9.6G    /vmfs/volumes/source-datastore

En soustrayant l’espace du volume VMFS-5 consommé par la machine virtuelle (8.8Go) à l’espace consommé sur le volume complet (9.6Go) on obtient approximativement 800Mo de métadonnées.

Maintenant que nous connaissons l’espace consommé sur notre volume, nous sommes enfin prêts à regarder la primitive UNMAP.

Faisons une opération SVMotion afin de déplacer cette machine virtuelle de notre datastore source vers un autre datastore. Ceci est probablement le meilleur cas d’utilisation pour la primitive UNMAP.

Une fois l’opération Storage vMotion terminé, le client vSphere se rend compte que le volume VMFS-5 dispose désormais d’un espace libre

Vérifions maintenant la quantité d’espace libre récupéré sur la LUN VMFS-5 en Thin provisioning sur notre baie de stockage Netapp, nous voyons que nous avons encore de l’espace inutilisé.

lun show -v /vol/voltest/lun-thin
/vol/voltest/lun-thin            50g (53687091200)   (r/w, online, mapped)
Serial#: W-TrP-pfgvgT
Share: none
Space Reservation: disabled
Multiprotocol Type: vmware
Maps: unmap=51 issi=51
        Occupied Size:    8.8g (9473908736)  
Creation Time: Tue Nov 25 11:13:52 BST 2015
Cluster Shared Volume Information: 0x0

C’est justement sur ce point que la primitive UNMAP va agir !

  • Avant la version 5.5 de ESXi :

Nous devions utiliser la commande vmkfstools pour effectuer des reclaiming space.

Il fallait se rendre dans le datastore concerné :

cd /vmfs/volumes/DatastoreName

Puis lancer la commande suivante :

vmkfstools –y <% of free space to unmap>

La valeur en % est utilisée pour calculer la quantité d’espace qui doit être récupérée à partir du volume VMFS.

La formule est la suivante :

Quantité d’espace à récupérer = (% Unmap x Espace libre du VMFS ) / 100

Il est possible de surveiller les primitives UNMAP utilisées en utilisant ESXTOP en appuyant sur « u » pour accéder à la vue « disk device ».

Avec la touche « f », il est possible de sélectionner « o » et « p » pour afficher VAAISTATS et VAAILATSTATS/cmd.

Les valeurs sous « DELETE », « DELETE_F » et « MBDEL/s » sont les colonnes intéressantes lors d’une opération de reclaiming space

Voici la signification des différents compteurs :

ZERO – number of successfully completed ZERO commands

ZERO_F – number of failed ZERO commands

MBZERO/s – data zeroed per second (in MB)

DELETE – number of sucessfully completed DELETE commands

DELETE_F – number of failed DELETE commands

MBDEL/s – data deleted per second (in MB)

 

Dans cet exemple, nous avons lancé une récupération de 60% d’espace libre.

L’espace libre sur notre LUN de 50Go est de 48,8Go.

Cela nous donne :

Quantité d’espace à récupérer = (% Unmap x Espace libre du VMFS) / 100

(60 x 48,80) / 100 = 29,28 Go

Le processus de reclaiming va créer un fichier caché de balloon « .vmfsBalloon+suffix » d’une taille de 29,3 Go (arrondi) dans lequel tous les blocs récupérés vont être stockés avant d’être remis à zéro. Le paramètre -y 60 indique que 60% des blocs libres seront remis à zéro. Cela implique que le datastore dispose de suffisamment d’espace disque libre pour effectuer cette opération. En cas de doute, relancer la commande plusieurs fois avec un % inférieur.

Il est donc important de ne pas spécifier une valeur en % trop élevée et de prendre en compte que le fichier de balloon créé lors de l’opération de reclaiming peut remplir le VMFS. Cela peut avoir un impact sur certaines actions en cours comme l’agrandissement d’un .VMDK, une prise de snapshot, etc… Pendant cette opération l’espace disponible sur le VMFS peut être limité en fonction de la valeur précisée.

L’exécution d’UNMAP peut générer beaucoup d’I/O et une forte utilisation CPU, VMware recommande de réaliser ces opérations hors production.


Depuis ESXTOP, il est possible de voir que des commandes de reclaim UNMAP ont été émises (DELETE) et la vitesse de traitement des commandes (MBDEL/s)

Sur la baie de stockage Netapp, nous voyons que la volumétrie a été récupérée.

lun show -v /vol/voltest/lun-thin
/vol/voltest/lun-thin    50g (53687091200)   (r/w, online, mapped)
Serial#: W-TrP-pfgvgT
Share: none
Space Reservation: disabled MBDEL/s
Multiprotocol Type: vmware
Maps: unmap=51 issi=51
Occupied Size:   76.3m (79966208)    
Creation Time: Tue Nov 25 11:23:51 BST 2015
Cluster Shared Volume Information: 0x0

  • Depuis la version 5.5 :

Le reclaiming space utilise une nouvelle commande de reclaiming des blocs. La commande fait maintenant partit d’un namespace d’esxcli.

esxcli storage vmfs unmap -l <datastorename>

Il existe trois paramètres disponibles pour utilisation de unmap, l’un des deux premiers est obligatoire et le troisième est facultatif.

-l | -VOLUME-label = Le nom du volume VMFS ou lancer le unmap

-u | -VOLUME-uuid = L’UUID du volume VMFS ou lancer le unmap.

-n|–reclaim-unit = Le nombre de blocs VMFS qui devraient être unmapped par itération.

Cette nouvelle commande peut être lancée à partir de n’importe où depuis le Shell en indiquant le nom du datastore ou son UUID. Auparavant avec vmkfstools, nous devions nous positionner dans le dossier du volume VMFS dans lequel nous lancions l’UNMAP.

Cette nouvelle commande ne permet plus de préciser un % d’espace à réclamer mais un nombre de blocs afin de simplifier les calculs.

Le dead space est maintenant réclamé par incrément et non d’un seul coup pour éviter des impacts sur la performance. UNMAP est un processus itératif qui s’exécute à travers de nombreux cycles jusqu’à la fin du traitement.

Le paramètre reclaim-unit spécifie la quantité de blocs à démapper pour chaque itération du processus UNMAP.

Dans les versions précédentes de vSphere, les datastores en VMFS-3 pouvait avoir des tailles de blocs de 1, 2, 4 ou 8Mo. Une mise à jour des datastores de VMFS-3 en VMFS-5 ne modifie pas la taille de bloc. L’exécution d’UNMAP sur un nouveau datastore en VMFS-5 travaillera avec des blocs de 1MB uniquement. Par conséquent, pour une valeur de reclaim-unit de 100 lancé sur un datastore VMFS-5, nous aurons 100Mo d’espace récupéré auprès du volume brut de la baie de stockage par itération jusqu’à ce que tous les blocs marqués comme disponible par UNMAP soient récupérés.

Exemple de commande :

esxcli storage vmfs unmap -l <datastorename> -n 100

Si le reclaim-unit n’est pas spécifié lors de l’utilisation d’UNMAP, par défaut UNMAP utilise une valeur à 200 (200Mo sur un VMFS-5 avec des blocs de 1MB).

Une autre différence par rapport à la version précédente est le nom du fichier de balloon temporaire caché. Il ne s’appelle plus «.vmfsBalloon+suffix » mais « .asyncUnmapFile ».

En version 5.5, un mécanisme permet de garantir que les blocs ciblés par UNMAP ne soient pas utilisés en écriture par des demandes d’I/O d’autres processus tant que l’UNMAP n’est pas terminé.

Exemple :

/vmfs/volumes/<datastore-name># ls -l -h -A
-r — 1 root root 200.0M 25 novembre 10h48 .asyncUnmapFile
-r — 1 root root 5,8M 25 novembre 11h42 .fbb.sf
-r — 1 root root 265.0M 25 novembre 11h42 .pbc.sf
-r — 1 root root 240.6M 25 novembre 11h42 .sbc.sf
drwx– 1 root root 420 25 novembre 11h39 .vSphere-HA

L’utilisation d’UNMAP permet maintenant de préciser la taille réelle du fichier temporaire à la place d’une taille de fichier temporaire déterminée par un % d’espace libre sur la LUN. Cela permet notamment d’éviter des catastrophes si UNMAP tente de démapper plusieurs To d’un seul coup.

De plus, si le datastore est plein à 75 % ou plus, le nombre de blocs sera toujours remplacé à une valeur par défaut de 200 blocs.

Ces modifications ont été apportées afin d’éviter un purple screen lors de l’utilisation de la primitive UNMAP sur une LUN supérieure à 2To en changeant le paramètre reclaim-unit.

Plus d’information : http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=2086747

Processus de UNMAP:

  1. L’utilisateur ou un script lance la commande UNMAP
  2. Vérifier que la baie supporte les VAAI et la primitive UNMAP ? Oui=3, Non=terminer
  3. Création du fichier caché .asyncUnmapFile à la racine du datastore
  4. . asyncUnmapFile est créé et verrouillé ? Oui=5, Non=terminer
  5. Envoi des commandes reclaim (à la valeur de reclaim-unit) pour allouer les blocs sur la LUN.
  6. L’allocation des blocs a-t-elle réussi ? Oui=7, Non=déverrouiller le fichier et reprendre à l’étape 6
  7. Envoi de commandes UNMAP sur tous les blocs alloués précédemment à l’étape 5
  8. Supprimer le verrouillage sur le fichier
  9. Fin du volume ? Oui=terminer, Non=retour à l’étape 3


  • Depuis la version ESXi 5.5 (patch 3 build 2143827) et ESXi 6.0 :

Le comportement de la primitive UNMAP a encore changé.

En effectuant un test d’utilisation avec une grande valeur de reclaim-unit (par exemple 30000 blocs (30Go), nous voyons bien que la valeur MBDEL/s est bien plus basse que 30 000Mo (30Go)

Ceci est facilement vérifiable par ESXTOP :

Il est possible de le voir dans les logs de hostd.

Log du hostd :

Unmap: Async Unmapped 200 blocks from volume 6322374e-751a563c-a4b7-xxxxxxxxxxxxxx
Unmap: Async Unmapped 200 blocks from volume 6322374e-751a563c-a4b7-xxxxxxxxxxxxxx
Unmap: Async Unmapped 200 blocks from volume 6322374e-751a563c-a4b7-xxxxxxxxxxxxxx
Unmap: Async Unmapped 200 blocks from volume 6322374e-751a563c-a4b7-xxxxxxxxxxxxxx
Unmap: Async Unmapped 145 blocks from volume 6322374e-751a563c-a4b7-xxxxxxxxxxxxxx
Unmap: Done : Total Unmapped blocks from volume 6322374e-751a563c-a4b3-xxxxxxxxxxxxxx : 944945

La procédure de récupération d’UNMAP émet 200 blocs par itération jusqu’à la fin où il émet seulement 145 blocs parce que l’espace libre restant sur le volume n’est pas suffisant pour faire une itération complète de 200 Mo (en d’autres termes l’espace libre total n’était pas divisible par 200 Mo)

Il est important de comprendre que la dernière ligne ne représente pas en nombre de blocs l’espace récupéré sur la LUN de la baie. L’espace physique récupérée sera bien inférieur à ce nombre. Cette ligne représente l’espace logique libre sur lequel UNMAP a travaillé.

En effectuant un test sur 2000 blocs sur un volume de 1To :

esxcli storage vmfs unmap -l <datastore> -n 2000

Log dans hostd :

Unmap: Async Unmapped 2000 blocks from volume 6322374e-751a563c-a4b7-xxxxxxxxxxxxxx

Nous voyons que la valeur n’est pas remplacée par 200 en utilisant une valeur de reclaim-unit plus petite.

Quel est donc le seuil qui passe la valeur de reclaim-unit à 200 (valeur par défaut) ?

En revenant sur la valeur plus haut :

Unmap: Done : Total Unmapped blocks from volume 6322374e-751a563c-a4b7-xxxxxxxxxxxxxx: 944945

En analysant la capacité de Free Space « 922,79 GB», on la multiplie par 1024 pour la passer en Mo et on la multiplie par 1% en arrondissant au dixième.

922.79 * 1024 * 0.01 = 9449.3696

En PowerCLI :

$datastore = get-datastore <datastore>

$blockcount = [math]::floor($datastore.FreeSpaceMB * .01)

Le nombre de blocs max qu’il est possible de passer à la commande UNMAP pour ce volume est de 9449. Au-delà, UNMAP prendra la valeur par défaut de 200 et risque de prendre un certain temps à effectuer son reclaiming space.

Vous n’avez plus d’excuse pour dire qu’il n’y a plus d’espace sur vos LUN 😉

twitterlinkedin
Publié dans Vmware vSphere Tagués avec : , , , , , , , , , , , , , ,

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

*