PVFS : the Parallel Virtual File System


Après avoir vu le GFS (Global File System) dans le numéro précédent, nous allons aujourd'hui nous pencher sur une autre solution dans le domaine des systèmes de fichiers partagés, PVFS.

Financé à l'origine par le Centre Goddard de la NASA dans le département Earth&Space Computing et étroitement lié au projet Beowulf du CESDIS, PVFS est maintenant développé à l'université de Clemson dans le laboratoire de recherche sur les architectures parallèles. PVFS est une solution à considérer à pied d'égalité avec GFS lors de la phase d'étude préliminaire à la mise en uvre d'une solution de stockage partagé et réparti dans un cluster.

Par ailleurs, de par une relative antériorité et peut être aussi de par ses origines, PVFS est déjà supporté dans des solutions Beowulf de production, comme par exemple Scyld, tandis que l'intégration de GFS dans ces mêmes solutions n'est pas encore finalisée (mais le support de cette solution est en cours, et aura probablement bien avancé même entre le moment où ces lignes sont écrites et où vous les lirez).

PVFS assure une compatibilité avec les entrées/sorties standard Unix, de telle sorte qu'il est possible de mettre en place PVFS sans qu'il ne soit en aucune manière nécessaire de recompiler l'application. De plus, PVFS a été conçu pour être très facilement installable, et pour permettre de donner à l'utilisateur le contrôle sur la répartition des fichiers sur les différents n uds constituant le cluster (stripping).

PVFS offre également une interface vers MPI-IO, par le biais de ROMIO. ROMIO est une implémentation open source des spécifications d'entrées-sorties de la norme MPI-2. Les fonctions sont optimisées pour les entrées-sorties sur des structures non contiguës, ce qui est le cas le plus fréquent dans le domaine du calcul parallèle.
ROMIO est disponible pour le téléchargement sur le site http://www-unix.mcs.anl.gov/romio/, mais si vous utilisez MPICH ou LAM-MPI, ou d'autres implémentations MPI propriétaires (HP, NEC, …), sachez que ROMIO est d'ores et déjà intégré dans l'implémentation MPI en question et que vous n'aurez donc aucune manipulation d'installation à effectuer afin de pouvoir en bénéficier.

Enfin, et grâce à un financement de Scyld Computing Corp., PVFS possède désormais une interface implémentée dans les noyaux Linux 2.2 et 2.4. Cette interface, implémentée sous la forme d'un module, est le composant qui permet à toutes les commandes Unix classiques de manipulation de fichiers et de répertoires (ls, mv, cp, rm…) de fonctionner sur les systèmes de fichiers PVFS de façon transparente.

En revanche, si le support du mode 64 bits a été implémenté, les tests ne sont pas encore suffisamment aboutis afin de garantir un fonctionnement sûr en production.

Sans aucune modification à apporter au kernel (pas de patch, ni de recompilation), PVFS apporte simultanément à l'utilisateur d'une solution cluster quatre fonctionnalités essentielles:
·         Un espace de nommage consistant à travers tout le cluster ;
·         Un accès transparent pour les divers utilitaires aux ressources distribuées ;
·         Une répartition physique des données sur l'ensemble des disques attachés à l'ensemble des n uds du cluster ;
·         Un environnement hautes performances pour l'accès utilisateur aux applications.

Pour être simple à utiliser, un système de fichiers distribué doit permettre aux utilisateurs d'avoir une vision commune et simultanée des fichiers et des répertoires sur l'ensemble des n uds, et PVFS permet un montage simultané d'un système de fichiers sur le même répertoire existant sur tous les n uds du cluster. L'accès aux données est ensuite effectué comme si les données étaient locales.

La répartition des données sur différents n uds permet d'obtenir une bonne performance, en augmentant la bande passante (soit répartie entre plusieurs clients, ou cumulée au profit d'un seul), en supprimant les goulots d'étranglement, et en offrant des chemins d'accès redondants aux données.

Alors que les mécanismes conventionnels d'accès aux données sont efficaces et permettent à toutes les applications d'accéder à des données pouvant exister sur des types de systèmes de fichiers différents, le passage systématique requis dans ce cas à travers le noyau induit une contention qui peut être problématique dans le cadre d'un environnement hautes performances. PVFS, à travers son API native, permet aux clients d'effectuer des requêtes directes, en contactant les serveurs PVFS distants plutôt que d'effectuer des appels noyau. Cette API permet ainsi des accès extrêmement rapides en étant ainsi accessible tant aux applications directement qu'aux bibliothèques, comme par exemple ROMIO.

Le diagramme suivant montre comment un ensemble de n uds constituant un cluster peuvent être utilisés pour un environnement PVFS. Les n uds se voient répartis en n uds de calcul, sur lesquels sont exécutées les applications d'une part et d'autre part en n uds de stockage, qui assurent la garde des données du système de fichiers PVFS. Un dernier n ud de gestion assure quant à lui le contrôle des méta-données nécessaires au fonctionnement interne de PVFS.
Si pour les grands clusters, constitués d'un grand nombre de machines, il est préférable de séparer effectivement les tâches confiées aux différents n uds, il est bien évidemment possible de confier de multiples tâches à un même n ud dans le cas d'une configuration plus réduite.

PVFS est donc composé de quatre composants majeurs et distincts:
·         Le serveur de méta-données (mgr) ;
·         Le serveur d'entrées-sorties (iod) ;
·         L'API native PVFS (libpvfs) ;
·         Le support de PVFS dans le noyau.

Les deux premiers composants, mgr et iod, sont des démons s'exécutant sur l'ensemble des n uds.

L'intérêt de posséder un démon (mgr) pour la gestion et le contrôle des méta-données sur chacun des n uds est de permettre une opération atomique en s'affranchissant des mécanismes de verrouillage plus complexes qu'il convient de mettre en uvre afin de garantir la cohérence de ces informations en cas d'accès mutualisé.

Le deuxième démon (iod) est celui qui assure les opérations sur les fichiers en local sur chacun des n uds. Ce serveur utilise les commandes Unix standard, qui implique que tout type de système de fichiers local est utilisable en dessous de PVFS, y compris des solutions RAID matérielles ou logicielles pour des solutions de stockage étendues ou sécurisées.


accès aux méta-données                        accès aux données

Les deux schémas ci-dessus montrent comment sont accédées les données et les méta-données dans un environnement PVFS. Dans le cas de l'accès au méta-données, qui sont des informations relatives à chaque fichier, à ses attributs de propriété et de protection et à ses caractéristiques de répartition dans le cluster, l'API contacte directement le démon servant ces méta-données.
En revanche, dans le cas de l'accès aux données, l'API contacte directement les démons servant les données en s'affranchissant de tout autre contact, ce qui permet des configurations adaptables et hautes performances.

Enfin, l'interface noyau de PVFS présente les mécanismes permettant le montage de système de fichiers PVFS sur les n uds Linux, afin de permettre un accès totalement transparent.
Cette interface n'est pas nécessaire aux applications, mais offre des possibilités d'interaction simple et efficace avec le système d'exploitation.
Le support de PVFS dans le noyau est constitué d'un module externe à charger, d'un patch optionnel permettant de s'affranchir des copies mémoire, et d'un démon (pvfsd) chargé des accès à PVFS pour les applications. Ce démon fait appel à libpvfs pour mener à bien l'ensemble de tâches qui lui sont confiées.



Le diagramme ci-dessus montre le cheminement des informations lorsque le support du noyau Linux est utilisé. La méthode utilisée ici est inspirée du système de fichiers Coda, qui a servi de base au développement de PVFS.
Les opérations sont demandées sous la forme d'appels système vers la couche VFS (Virtual File System) du noyau. Elles sont ensuite placées dans une file de traitement appartenant à pvfsd qui reçoit les demandes à travers un fichier spécial. Le contact avec les démons distants est ensuite effectué, et PVFS retourne les informations demandées par les applications à travers les couches noyau.

Afin que tout système de fichiers puisse être utilisable, des interfaces appropriées doivent préalablement exister. Ce point très important devient même crucial lorsque des applications différentes s'exécutent de façon concurrente, les systèmes de fichiers étant alors encore plus fortement sollicités. Pour répondre efficacement à de tels besoins, trois types d'interfaces différentes sont disponibles avec PVFS:
·         L'API native de PVFS, qui permet aux utilisateurs de définir le schéma de répartition des données au sein du système de fichiers ;
·         L'interface noyau pour Linux, qui permet aux applications d'accéder à PVFS de façon transparente ;
·         L'interface pour entrées-sorties MPI ROMIO, qui permet aux développeurs d'applications d'implémenter directement des fonctions d'entrées-sorties conformes à la norme MPI dans leurs applications. Par ailleurs, ROMIO offre deux types d'optimisation distincts, le data sieving, et le two-phase collective I/O, chacune de ces optimisations offrant des possibilités de performances optimales dans un contexte donné.

Sur le point des performances, PVFS a été conçu dès le départ suivant deux axes: la rapidité d'accès aux données, et la capacité à supporter des extensions de configuration. Les clusters Beowulf comportant de plus en plus de n uds, le sous-système d'entrées-sorties occupe une place de plus en plus critique et prépondérante, et devient le point le plus important de telles configurations.

Comment installer PVFS?

Il faut aller chercher sur le serveur ftp (
ftp://ftp.parl.clemson.edu:/pub/pvfs/) les deux tarballs permettant de construire PVFS :
·         pvfs (pvfs-1.5.0.tgz), qui contient les sources pour le serveur PVFS et pour la bibliothèque PVFS ;
·         pvfs-kernel (pvfs-kernel-0.9.0.tgz), qui contient, comme nous l'avons vu précédemment, le code permettant aux systèmes de fichiers PVFS d'être montés sous Linux. Cette dernière partie n'est pas absolument nécessaire au bon fonctionnement de PVFS, mais rend toutes choses beaucoup plus faciles.
Placez les deux tarballs dans un même répertoire de votre choix, ce qui facilitera la compilation des modules kernel. Lors de l'éclatement des tarballs, vous observerez la création d'un lien symbolique qui permet au make de pvfs-kernel de localiser les composants requis.
La compilation de pvfs se fait de façon très classique:
·         ./configure
·         make
Ensuite, un ./make install effectuera l'installation de PVFS sur votre machine, en plaçant:
·         mgr, iod dans /usr/local/sbin/
·         libpvfs.a, libminipvfs.a dans /usr/local/lib/
·         include files dans /usr/local/include/
·         les codes de test et les utilitaires dans /usr/local/bin/
·         et les man pages dans /usr/local/man/
Si toutefois ces options d'installation ne vous conviennent pas, il est possible de modifier ces valeurs par défaut ; voir dans ce cas les possibilités offertes par un ./configure help.
La compilation du noyau se fera sans difficulté, si vous avez soin de compiler cet environnement sur une machine utilisant le même noyau que les machines sur lesquelles vous envisagez de mettre PVFS en uvre. Les mêmes étape que précédemment seront requises (./configure, make, make install), et à la fin de cette étape, les fichiers suivants se verront ajoutés à votre système:
·         /usr/local/sbin/pvfsd
·         /sbin/mount.pvfs
·         pvfs.o dans /lib/module/<kernel …>/misc
Mise en uvre de PVFS
Cette étape est plus complexe que la précédente, la complexité provenant du fait que nous allons évoluer dans un environnement distribué, mais aussi parce qu'il faut bien reconnaître que les étapes à franchir ne coulent pas nécessairement de source.
Il faut tout d'abord se rappeler les trois fonctions distinctes dans l'environnement PVFS, à savoir, respectivement, client, serveur de méta-données, serveur de données, et aussi se rappeler que toute machine peut assurer une seule, ou toute combinaison de ces fonctions, y compris les trois simultanément.
Il reste alors à définir le rôle de chaque machine dans
votre cluster, en fonction de vos besoins, il n'existe pas réellement de configuration type.
En plus des rôles différents que chaque machine peut jouer, il existe trois répertoires distincts utilisés par PVFS sur chaque machine, à savoir:
·         le répertoire de méta-données: il n'en existe qu'un pour tout le système PVFS et contient les informations de caractérisation des fichiers, ainsi que deux autres fichiers, .iodtab et .pvfsdir, qui permettent au serveur de méta-données de localiser les serveurs d'entrées-sorties et les fichiers pvfs.
·         le répertoire de données, qui existe sur chaque serveur de données ;
·         le point de montage du système de fichiers PVFS, qui existe sur chaque client.
Machine/répertoire        Méta-données       Données   Point de montage
Serveur de méta-données    Oui, 1   Non      Non
         mgr      .iodtab .pvfsdir                 
Serveur de données        Non      Oui, n   Non
                  iod      iod.conf, <datadir>     
Client   Non      Non      Oui, n
                           pvfs.o mount.pvfs pvfsd  pvfstab
<mountpoint>
/dev/pvfsd

Configuration du serveur de méta-données
Ce serveur requiert trois fichiers pour fonctionner:
·         le démon mgr (exécutable). Lancé sous root, il doit être opérationnel avant toute requête client.
·         .iodtab (fichier data), qui contient les adresses IP de tous les serveurs de données et les numéros de port pour les démons d'entrées-sorties. Cette liste est ordonnée ; aussi, une fois créée, il ne faut pas la ré-ordonner sous peine de risquer une corruption de données.
·         .pvfsdir (fichier data) définit les permissions du répertoire où sont stockées les méta-données.
Les deux fichiers de données que nous venons de décrire peuvent être créés manuellement, ou à travers le script /usr/local/bin/mkmgrconf (installé en même temps que les autres utilitaires).
Configuration des serveurs de données
Ces serveurs ont quant à eux besoin des fichiers suivants:
·         Le démon iod (exécutable), qui offre les services d'entrées-sorties pour PVFS. Il doit être lancé sous root ; il change alors son UID et son GID automatiquement pour des raisons de sécurité.
·         iod.conf (fichier data), qui décrit le répertoire utilisé pour stocker les données PVFS et les UID et GID sous lesquels iod passera après son lancement. Un fichier similaire existera pour mgr dans une future version.
Le fichier iod.conf possède la structure suivante (par exemple) :
# iod.conf
datadir /pvfs_data
user nobody
group nobody
Nous allons ensuite créer le répertoire tel que défini dans le fichier sous notre premier serveur d'entrées-sorties :
[root@ios1 /]# cd /
[root@ios1 /]# mkdir /pvfs-data
[root@ios1 /]# chmod 700 /pvfs-data
[root@ios1 /]# chown nobody.nobody /pvfs-data
[root@ios1 /]# ls -ald /pvfs-data
drwx------ 2 nobody nobody 35 Dec 1 09:41 /pvfs-data/
Et il ne nous reste ensuite qu'à répéter cette opération sur chacun des serveur d'entrées-sorties de notre configuration. Pour les très grosses configurations, il sera bon de prévoir un petit shell de configuration "automatique" ; nous entrons alors dans la problématique de gestion et d'administration des grands environnements…
Configuration des clients
Il y a cinq fichiers et un point de montage par client:
·         le démon pvfsd (exécutable), qui assure les transferts entre machines à la requête des clients. Il doit être lancé sous root, avant le montage du système de fichiers par le client.
·         le module noyau pvfs.o, qui autorise les opérations standard sur PVFS en enregistrant ce nouveau type de système de fichiers.
·         le fichier spécial /dev/pvfsd, passerelle entre pvfsd et pvfs.o. Il n'est créé qu'une seule fois, mais doit exister avant le lancement de pvfsd.
·         le programme mount.pvfs (exécutable), utilisé par mount pour assurer les étapes spécifiques au montage d'un système de fichiers PVFS de façon transparente. Il peut alternativement être utilisé directement en manuel.
·         le fichier pvfstab (data), similaire au fstab, il décrit comment les fichiers PVFS doivent être accédés par les applications, si et seulement si ces dernières sont linkées avec libpvfs ou libminipvfs. Ceci comprend l'utilisation de l'interface ROMIO.
·         le point de montage, qui est juste un répertoire vide, avec ses attributs de fichier spécial donnés par mknod (c=caractère, major id=60 arbitraire )
[root@client0 /]# mkdir /pvfs
[root@client0 /]# ls -ald /pvfs
drwxr-xr-x 2 root root 35 Dec 1 09:37 /pvfs/
[root@client0 /]# mknod /dev/pvfsd c 60 0
[root@client0 /]# ls -l /dev/pvfsd
crw-r--r-- 1 root root 60, 0 Dec 1 09:45 /dev/pvfsd
Prévoyant l'utilisation d'applications faisant appel aux bibliothèques PVFS sur nos clients, nous allons également créer pvfstab :
[root@client0 /]# chmod 644 /etc/pvfstab
[root@client0 /]# ls -al /etc/pvfstab
-rw-r--r-- 1 root root 46 Dec 17 15:19 /etc/pvfstab
[root@client0 /]# cat /etc/pvfstab
client0:/pvfs-meta /pvfs pvfs port=3000 0 0
Ces étapes sont à effectuer sur chaque n ud client.
Démarrage et arrêt de PVFS
La première étape consiste à démarrer les serveurs. L'ordre de démarrage n'importe pas, mais il faut s'assurer qu'ils sont tous opérationnels avant de commencer à utiliser le système.

Par exemple, nous allons lancer le démon du serveur de méta-données /usr/local/bin/mgr, qui va alors créer un fichier de log dans /tmp, nommé mgrlog.<>. L'extension particulière donnée à ce fichier est unique et différente à chaque redémarrage de mgr.

[root@ios1 /root]# /usr/local/sbin/mgr
[root@ios1 /root]# ls -l /tmp
total 5
-rwxr-xr-x 1 root root 0 Dec 18 18:22 mgrlog.MupejR*

Ensuite, il nous faut démarrer /usr/local/sbin/iod sur chaque serveur de données, et à nouveau sera créé dans /tmp un fichier de log nommé iolog.<>, avec toujours une extension particulière et unique à chaque session.

[root@client0 /root]# /usr/local/sbin/iod
[root@client0 /root]# ls -l /tmp
total 5
-rwxr-xr-x 1 root root 82 Dec 18 18:28 iolog.n2MjK4

Tous nos démons étant lancés, nous allons pouvoir connecter nos clients. Il nous faut préalablement charger le module noyau (et ensuite renseigner /etc/modules.conf en prévision du prochain redémarrage).

[root@client0 /root]# insmod pvfs.o
[root@client0 /root]# lsmod
Module Size Used by
pvfs 32816 0 (unused)
[root@client0 /root]# /usr/local/sbin/pvfsd
[root@client0 /root]# ls -l /tmp
total 7
-rwxr-xr-x 1 root root 0 Dec 18 18:22 mgrlog.MupejR*
-rwxr-xr-x 1 root root 102 Dec 18 18:22 pvfsdlog.Wt0w7g*
[root@client0 /root]# /sbin/mount.pvfs head:/pvfs-meta /pvfs
[root@client0 /root]# ls -al /pvfs
total 1
drwxrwxrwx 1 root root 82 Dec 18 18:33 ./
drwxr-xr-x 20 root root 378 Dec 17 15:01 ../
[root@client0 /root]# df -h /pvfs
Filesystem Size Used Avail Use% Mounted on
client0:/pvfs-meta 808M 44M 764M 5% /pvfs

Nous pouvons maintenant nous lancer à la création de quelques fichiers afin de vérifier que tout est bien en place:
[root@client0 /root]# cp /etc/pvfstab /pvfs/
[root@client0 /root]# dd if=/dev/zero of=/pvfs/zeros bs=1M count=10
[root@client0 /root]# ls -l /pvfs
total 10240
-rw-r--r-- 1 root root 46 Dec 18 18:41 pvfstab
-rw-r--r-- 1 root root 10485760 Dec 18 18:41 zeros
[root@client0 /root]# cat /pvfs/pvfstab
client0:/pvfs-meta /pvfs pvfs port=3000 0 0

Comme pour tout autre système de fichiers, il est possible d'effectuer un démontage:

[root@client0 /root]# umount /pvfs
[root@client0 /root]# ls -al /pvfs
total 1
drwxrwxrwx 1 root root 82 Dec 18 18:33 ./
drwxr-xr-x 20 root root 378 Dec 17 15:01 ../

Pour l'arrêt de PVFS, il est préférable de respecter les étapes suivantes en séquence:
·         démontage des PVFS sur les clients ;
·         arrêt des démons pvfsd avec kill ou killall ;
·         déchargement de pvfs.o module avec rmmod ;
·         arrêt du demon mgr avec kill ou killall ;
·         arrêt des démons iod avec kill ou killall.
Les utilitaires spécifiques à PVFS
Lors de l'installation de PVFS, quelques utilitaires dédiés sont mis à votre disposition:
·         u2P: copie de fichiers vers PVFS, qui contrairement à cp, permet à l'utilisateur de contrôler la répartition physique des fichiers sur les différentes machines du cluster. u2p se base sur les informations contenues dans /etc/pvfstab.
·         pvstat, qui permet de visualiser la distribution physique d'un fichier après sa création. pvstat se base également sur les informations contenues dans /etc/pvfstab.
·         iodping, qui permet de vérifier l'état d'un serveur de données.
·         mgrping, qui permet de vérifier l'état d'un serveur de méta-données.
Il est possible, pour iodping et mgrping, de préciser le numéro de port si celui-ci est différent des valeurs par défaut (3000 et 7000, respectivement). De plus, ces deux commandes ont des codes de retour standard (échec/succès) qui permettent d'intégrer ces commandes dans des shell scripts d'administration.
Développement d'applications avec PVFS
Le mode d'accès transparent est certes de loin le plus confortable à utiliser (il n'y a rien à faire), mais le revers de la médaille est que les pertes de performances induites par les appels aux primitives noyau et au dialogue avec le démon pvfsd peuvent être loin d'être négligeables.
Aussi, les développeurs d'applications désireux d'obtenir la meilleure performance possible de leur code peuvent faire appel aux primitives PVFS en direct. Il faut noter que les appels aux primitives PVFS sont intégralement compatibles avec les systèmes de fichiers standard.
Pour un code faisant appel à ces primitives, il faut (bien sûr) ajouter cette directive d'inclusion dans le code:

#include <pvfs.h>
et aussi, pour linker une application avec cette librairie, installée typiquement dans /usr/local/lib/, il faut ajouter -lpvfs à la commande de link et éventuellement -L/usr/local/lib si la définition du chemin d'accès n'est pas complète.
Définition des paramètres de stripping
Le schéma de répartition physique des données sous PVFS est simple et basé sur trois paramètres:
·         base: l'index du premier n ud d'entrées-sorties, le premier n ud du cluster ayant la valeur 0 ;
·         pcount: le nombre de serveurs d'entrées-sorties sur lesquels les données se verront réparties ;
·         Ssize: strip size, la taille des blocs contigus répartis sur chacun des serveurs d'entrées-sorties.
Dans l'exemple suivant, vous voyez ce que donne une répartition des données avec base=0 et pcount=4, et ces paramètres, spécifiés lors de la création du fichier, font partie des méta-données et restent valables pour toute la durée de "vie" du fichier.
Le schéma de distribution est défini dans une structure que l'on passe de façon optionnelle lors de la création du fichier. Si cette structure n'est pas passée, un schéma par défaut (répartition globale) sera appliqué.
pvfs_open(char *pathname, int flag, mode_t mode);
pvfs_open(char *pathname, int flag, mode_t mode, struct pvfs_filestat *dist);

struct pvfs_filestat
int base; /* The first iod node to be used */
int pcount; /* The number of iod nodes for the file */
int ssize; /* stripe size */
int soff; /* NOT USED */
int bsize; /* NOT USED */

Il est également possible, par le biais d'une fonction ioctl, de récupérer les valeurs des paramètres de cette même structure pour un fichier déjà existant.
pvfs_ioctl(int fd, GETMETA, struct pvfs_filestat *dist);
Définition d'une partition logique
Le système de partitionnement logique en uvre dans PVFS permet de définir des zones à l'intérieur même d'un fichier, et ce de façon plus performante, car les zones ainsi définies sont vues comme des unités séparées.
Ce modèle est particulièrement adapté à la programmation parallèle, chaque entité d'exécution (tâche) ne verra que les données contenues dans la zone le concernant.
Egalement trois paramètres définissent une partition logique:
·         Offset: "distance" en bytes par rapport au début du fichier ;
·         Gsize: nombre d'octets contigus au sein de la partition ;
·         Stride: "distance" en bytes d'un groupe par rapport à l'autre.
La définition d'une partition se fait par un appel à une ioctl:
pvfs_ioctl(fd, SETPART, &part);
où les paramètres sont définis dans une structure passée par un pointeur :
struct fpart
int offset;
int gsize;
int stride;
int gstride; /* NOT USED */
int ngroups; /* NOT USED */
;
Les deux dernier paramètres sont des vestiges de recherches antérieures et doivent toujours être à zéro.
Le partitionnement est un appel purement local et n'entraîne aucun dialogue entre les démons pvfsd, ce qui permet de modifier le schéma de partitionnement à volonté dans une application. Lors de l'ouverture, le schéma de partitionnement par défaut permet à l'application de voir tout le fichier.
Comme précédemment, il est également possible de récupérer les caractéristiques d'un fichier déjà existant.
Dans l'exemple suivant, nous allons supposer un fichier contenant 40000 enregistrements de 1000 octets, accédés par quatre tâches parallèles accédant chacune à 10000 enregistrements. Dans ce cas de figure, groupsize aura donc pour valeur 10000*1000, et chaque tâche (de 0 à 3) définira une valeur de décalage (offset) égale à gsize*taskid afin de localiser "sa" zone de données.
Il est également possible de considérer une allocation cyclique des enregistrements. Dans ce cas, la valeur de gsize sera de 1000 octets, le stride aura pour valeur 4000 octets, et les offsets seront définis de façon à obtenir l'accès sur des plages non contiguës.
Il est important de comprendre que la définition du partitionnement pour une tâche n'a aucune incidence sur les autres tâches, et que des recouvrements peuvent être effectués si cela est souhaité. Il n'y a pas non plus de rapport entre le schéma de partitionnement et le striping du fichier, et même si une correspondance entre ces deux caractéristiques est le plus souvent souhaitable, ce n'est absolument pas une nécessité.
Le partitionnement simple est utile pour l'accès à des structures mono-dimensionelles et à des distributions simples sur des structures bi-dimensionnelles. Pour des opérations plus complexes, le partitionnement multi-dimensionnel est plus adapté.
Mise en oeuvre du partitionnement multi-dimensionnel
L'interface de partitionnement multi-dimensionnel (MDBI = Multi Dimensional Bloc Interface) propose une vue à plus haut niveau que l`interface standard de PVFS. En effet, MDBI propose de visualiser les données comme un tableau d'enregistrements de dimension N. Ce tableau est découpé en paquets d'enregistrements, en spécifiant les dimensions du tableau et la taille des blocs dans chaque dimension. Les paramètres utilisés pour cela sont les suivants:
·         d, le nombre de dimensions ;
·         rs, la taille de l'enregistrement ;
·         nb(n), le nombre de blocs dans chaque dimension ;
·         ne(n), le nombre d'éléments par bloc dans chaque dimension ;
·         bf(n), le blocking factor utilisé pour les buffers mémoire.
Dès que la vue du jeu de données ait ainsi été définie, les paquets de données peuvent être accédés par le biais de simples appels à des fonctions système, en spécifiant un jeu de valeurs d'index, une valeur par dimension.
Cinq fonctions existent pour ces opérations:
int open_blk(char *path, int flags, int mode);
int set_blk(int fd, int D, int rs, int ne1, int nb1, ..., int nen, int nbb);
int read_blk(int fd, char *buf, int index1, ..., int indexn);
int write_blk(int fd, char *buf, int index1, ..., int indexn);
int close_blk(int fd);
open_blk et close_blk ont le même comportement que le open/close standard unix, set_blk définit quant à lui les paramètres de dimensionnement et peut être appliqué autant de fois que nécessaire. Read_blk et write_blk peuvent être appelés dès que set_blk a été appliqué.
Dans l'exemple ci dessus, nous pouvons voir un fichier qui est visualisé comme un tableau à deux dimensions de blocs, lesquels blocs sont des tableaux 2x3 d'enregistrements.
L'appel à set_blk pour définir une telle géométrie est le suivant:
set_blk(fd, 2, 500, 2, 6, 3, 3);
Pour lire le bloc (2, 0) du tableau, les paramètres de lecture sont les suivants :
read_blk(fd, &buf, 2, 0);

Buffering par blocs

Le "blocking factor" est un paramètre défini par l'utilisateur et qui permet de définir le nombre de blocs lus simultanément en une opération, et placés ensuite en mémoire, de telle sorte que des opérations de lecture/écriture successives se résument à des accès mémoire, jusqu'à invalidation du cache.

Dans l'exemple précédent, nous pouvons voir comment apparaissent les groupes de blocs ainsi créés, ils sont dénommés "superblocs" dans cette illustration, mais n'ont bien sûr aucun rapport avec les autres superblocs que vous pouvez connaître.

Il est essentiel de garder présent à l'esprit qu'aucun mécanisme de contrôle de cohérence n'est utilisé, cette responsabilité étant laissée entièrement à la charge du programmeur.

Conclusion

Aux côtés de GFS, PVFS est une solution à étudier attentivement. Peut-être plus complexe à mettre en uvre que GFS, mais également plus rodé et mieux intégré dans certaines solutions de gestion et d'administration de clusters Beowulf, PVFS offre une excellente interface de développement, et des fonctionnalités ayant fait leurs preuves dans de multiples environnements.
En revanche, face à GFS, l'absence de gestionnaire de verrous et, dans une moindre mesure, de fsck peuvent paraître relativement problématiques.
D'un autre côté, l'installation de PVFS possible "sans toucher au noyau" peut être un confort, ou une sécurité face aux contraintes d'un environnement sécurisé.
En termes de performances, les comparaisons entre les deux solutions sont difficiles à établir et bien qu'ayant mis l'une et l'autre en uvre, mais dans des environnements très différents, l'auteur se refuse à toute interprétation en raison des contextes matériels trop éloignés.

Cet article et les illustrations qui l'accompagnent est largement basé sur les documents disponibles en ligne sur le site de l'université de Clemson.

Liens

http://www-unix.mcs.anl.gov/pvfs
http://www-unix.mcs.anl.gov/romio/
ftp://ftp.parl.clemson.edu:/pub/pvfs/

Christophe Le Cannellier
Saint Paul Research Labs
sprl@wanadoo.fr