« tmpfs » et « ramfs » : La RAM pour accélérer les IO disques

Dans certains cas d’utilisation, calculs scientifiques, caches, gros accès concurrents à des bases de données, les accès disques sont un facteur limitant important. L’idée qui vient à l’esprit des administrateurs systèmes et d’utiliser la mémoire vive de la machine, la RAM, pour stocker temporairement les données.

« tmpfs » (Temporary File System) et « ramfs » (Random Access Memory File System) permettent d’utiliser la RAM d’une machine Linux en tant que partition au même titre qu’un stockage physique du type disques dur, clé USB, etc.

Différences et points communs

« ramfs » Et « tmpfs » sont tous deux destinés à la création de conteneur en RAM, ils se distinguent cependant par deux différences principales :

  • Au contraire de « ramfs », « tmpfs » et fermement borné, les dimensions du conteneur sont fixées dès sa création et ne bougent plus. Si vous essayez de dépasser la taille maximale d’un conteneur « tmpfs » vous obtiendrez un message d’erreur du type « plus d’espace sur le disque ». Les dimensions de « ramfs » que vous définissez réservent simplement un certain espace dans la RAM, mais cet espace n’est pas borné fermement. Vous pouvez parfaitement copier un fichier de 2Go sur un ram-disque d’1Go… Vous risquez cependant de rencontrer certains problèmes à la relecture…

    Comme vous l’imaginez, il est donc possible en utilisant « ramfs » de copier des données dans la RAM jusqu’à sa saturation… Dans ce cas, l’expérience ce termine par un crash !

  • La seconde différence critique est que « tmpfs » peut utiliser l’espace de SWAP là ou « ramfs » n’utilise QUE la RAM… Si votre système commence à souffrir d’un manque de mémoire vive, « tmpfs » déchargera tout, ou une partie, des données dans la SWAP. Bien sûr, dans ce cas, vous perdez tous le bénéfice de l’utilisation d’un conteneur RAM, mais vous assurez la stabilité de votre système.

ATTENTION : Quelque soit l’usage que vous ferez de ses outils, souvenez vous qu’ils offrent un stockage volatile, c’est à dire que TOUS CE QUI EST STOCKE DANS UN CONTENEUR TMPFS OU RAMFS SERA PERDU AU PREMIER REBOOT !!!

Mise en œuvre

Le support de « ramfs » et/ou de « tmpfs » s’active directement au niveau du noyau Linux. Vous trouverez le support de « tmpfs » sous :

 File systems  --->
    Pseudo filesystems  --->
        [*] Virtual memory file system support (former shm fs)
        [*]   Tmpfs POSIX Access Control Lists

tandis que « ramfs » vient avec le support « d’initramfs » :

General setup  --->
    [*] Initial RAM filesystem and RAM disk (initramfs/initrd) support

Ceci fait, c’est la commande « mount » à qui l’on précisera le type de pseudo file système à utiliser ainsi que la taille du conteneur qui ce chargera de l’allocation / la réservation mémoire. Les montages d’un « tmpfs » et d’un « ram disque » de 512Mo se traduiront par :

root@mafalda:~# mkdir /mnt/{tmpfs,ramfs}
root@mafalda:~# mount -t tmpfs -o size=512m tmpfs /mnt/tmpfs/
root@mafalda:~# mount -t ramfs -o size=512m ramfs /mnt/ramfs/

un rapide coup d’œil au retour de « mount » confirme que les commandes ce sont bien terminées :

root@mafalda:~# mount
/dev/sda1 on / type ext4 (rw,errors=remount-ro)
...
tmpfs on /mnt/tmpfs type tmpfs (rw,size=512m)
ramfs on /mnt/ramfs type ramfs (rw,size=512m)

Pour illustrer l’une des différences entre « ramfs » et « tmpfs » énoncée ci dessus, nous pouvons copier un ou deux fichiers sur ces volumes :

root@mafalda:~# touch /mnt/{tmpfs,ramfs}/un_test.txt
root@mafalda:~# ls /mnt/{tmpfs,ramfs}/
/mnt/ramfs/:
un_test.txt
 
/mnt/tmpfs/:
un_test.txt
root@mafalda:~# ls -lh ~fhh/Téléchargements/
total 697M
-rw-r--r-- 1 fhh fhh 697M 2010-12-03 17:02 xubuntu-10.10-desktop-i386.iso
root@mafalda:~# cp ~fhh/Téléchargements/xubuntu-10.10-desktop-i386.iso /mnt/tmpfs/
cp: écriture de «/mnt/tmpfs/xubuntu-10.10-desktop-i386.iso»: Aucun espace disponible sur le périphérique
root@mafalda:~# cp ~fhh/Téléchargements/xubuntu-10.10-desktop-i386.iso /mnt/ramfs/
root@mafalda:~# ls /mnt/{tmpfs,ramfs}/
/mnt/ramfs/:
un_test.txt
xubuntu-10.10-desktop-i386.iso
 
/mnt/tmpfs/:
un_test.txt

Aucun problème donc pour copier une iso de plus de 600Mo sur le disque « ramfs », en revanche, en « tmpfs », un message affichant « Aucun espace disponible sur le périphérique » est retourné.

Dans tous les cas, les données sont perdues après démontage :

root@mafalda:~# umount /mnt/{tmpfs,ramfs}
root@mafalda:~# mount -t tmpfs -o,size=512m tmpfs /mnt/tmpfs
root@mafalda:~# mount -t ramfs -o,size=512m ramfs /mnt/ramfs/
root@mafalda:~# ls /mnt/{tmpfs,ramfs}
/mnt/ramfs:
 
/mnt/tmpfs:

Les conteneurs peuvent être remontés automatiquement après chaque reboot en les ajoutant à votre « /etc/fstab ». Par exemple, pour le montage avec le gid users d’un conteneur de 5Go au démarrage de votre système, vous pourrez ajouter à votre fstab une ligne du type :

root@mafalda:~# cat /etc/fstab
# <fs>			<mountpoint>	<type>		<opts>		<dump/pass>
...
tmpfs			/mnt/tmpfs	tmpfs		size=5120m,gid=users	0 0

Exemple : Optimiser le cache d’un site web

A titre d’exemple « ludique » (car il existe bien d’autres façons d’optimiser un cache), je vous propose « d’optimiser manuellement » le cache d’un site internet basé sur un CMS. Le principe d’un tel cache, en très simplifié, consiste à ne calculer qu’une fois les pages. Une fois la page générée, elle est enregistrée sur le disque dans le répertoire de cache. Jusqu’à ce que la page soit modifiée, dès qu’un client ce connecte au site web, le serveur lui expédie la page pré calculée.

Dans notre exemple, toutes les pages déjà calculées sont enregistrées dans le répertoire « CACHE » à la racine du site web. La taille maximale du cache peut être définie dans l’application. Le cache sera fixé à 10Mo.

Afin de pouvoir servir les pages stockées dans le cache plus rapidement, nous allons utiliser un conteneur « tmpfs » de 10Mo. Afin de ne pas avoir à refaire tous le cache en cas de redémarrage ou de crash, le cache sera sauvegardé toutes les 30 minutes sur le disque dur.

Le site internet à « optimiser » est contenu dans le répertoire « /websites/admin-linux/site » son répertoire de cache est donc « /websites/admin-linux/site/CACHE ».

Commençons par sauver l’état actuel de notre cache :

webserver ~ # mkdir /websites/admin-linux/savedcache
webserver ~ # cp -a /websites/admin-linux/site/CACHE/* /websites/admin-linux/savedcache/

Nous pouvons ensuite ajouter à notre « fstab » le montage d’un conteneur « tmpfs » de 11Mo (supposons que nous ayons de la place en RAM et que nous souhaitions jouer la sécurité) dans « /websites/admin-linux/site/CACHE » :

webserver ~ # cat >> /etc/fstab
tmpfs			/websites/admin-linux/site/CACHE		tmpfs		size=11m,uid=apache,gid=apache	0 0

Nettoyons maintenant le répertoire de cache avant de le monter et d’y restaurer le contenu déjà calculé :

webserver ~ # rm -rf /websites/admin-linux/site/CACHE/* &&
> mount /websites/admin-linux/site/CACHE && 
> cp -a /websites/admin-linux/savedcache/* /websites/admin-linux/site/CACHE/
webserver ~ #

Voilà. Notre site stocke et restaure les pages déjà calculées depuis la RAM directement.

Pour améliorer le système, nous synchroniserons via rsync le répertoire « /websites/admin-linux/site/CACHE/ » et sa sauvegarde « /websites/admin-linux/savedcache/ » toutes les demi-heures. Pour cela, ajouter au cron une commande du type :

*/30    *       *       *       *       /usr/bin/rsync -az --delete-after /websites/admin-linux/site/CACHE/ /websites/admin-linux/savedcache

Enfin, pour que le cache soit sauvé à chaque arrêt et restauré au redémarrage, ajouter la synchronisation aux fichiers « rc.local » gérant le démarrage des programmes complémentaires sur votre distribution.

Sous Gentoo Linux par exemple, tous ce passe dans « /etc/conf.d/local » ou une fonction (« local_start ») effectue les actions que vous souhaitez accomplir au « boot », tandis que « local_stop » s’occupe des actions d’arrêt. Dans notre cas nous trouverions :

webserver ~ # cat /etc/conf.d/local
local_start() {
# Restauration du cache Web :
	/usr/bin/rsync -az --delete-after /websites/admin-linux/site/savedcache/ /websites/admin-linux/CACHE > /dev/null 2>&1
 
	return 0
}
 
local_stop() {
# Backup du cache Web :
	 /usr/bin/rsync -az --delete-after /websites/admin-linux/site/CACHE/ /websites/admin-linux/savedcache  > /dev/null 2>&1
 
	return 0
}

Conclusion

Comme vous l’aurez constaté dans l’exemple présenté ici, l’utilisation de « tmpfs » et de « ram-disques » est rapide à mettre en œuvre, et peut s’appliquer à une multitude de services (bases de données, serveurs ftp, etc) pour lesquelles la vitesse de lecture et d’écriture sur disque devient un problématique.

3 réflexions au sujet de « « tmpfs » et « ramfs » : La RAM pour accélérer les IO disques »

  1. @Benoist
    pour les base de donnée en ram, faut le définir dans la table engine memory, mais une petite incident sur la ram et les donées … donc il ne faut pas mettre des choses sensibles dessus, à voir plus détailler sur le site mysql si sa a évolué.

  2. Merci pour cet article qui ouvre des perspectives de rapidité !

    Peut-on faire cela selon toi :

    J’ai un serveur avec 16 Go de RAM sur Ubuntu 10.10. J’aimerai mette en ram mes
    3 blogs wordpress (300 Mo chacun tout compris avec template, photos… sans la base de données). J’ai donc 1 GO de blog + 3 base de données de 1 GO chacune soit 4 GO. Penses tu qu’il soit possible de mettre les blogs et/ou leurs bases de données en RAM ?

    J’imagine un bash qui au lancement du serveur copie tout en ram et quand on reboot réécrie tout sur le disque pour « sauvegarder » la base de données.

    Faisable ? Possible ? Envisageable ? lol

    1. Bonjour Benoist,

      Oui, cela doit pouvoir ce faire, mais tu devra certainement ajouter un script de démarrage exécuté avant le lancement d’apache et de MySQL pour que les données soient bien déposées dans le conteneur RAM avant leurs démarrage.

      Ensuite, pour la synchro du conteneur sur les disques, ne te contente pas d’une simple sauvegarde au démarrage et à l’arrêt, fais en régulièrement sous peine de voir toutes les modifs disparaitre en cas de pépin.

      Le système sera plus lent à démarrer et à s’arrêter. Attention donc aux gestions d’arrêts critique (autonomie des onduleurs, etc).

      Pour conserver les modifs de la db, le mieux est peut être d’utiliser la réplication de la base sur une autre instance de mysql écrivant, elle, sur le disque dur (voir « Réplication de bases de données MySQL« ).

      Voilà comme ça mes premières pensées, mais si d’autres lecteurs ont des idées, elles sont les bienvenues…

      La montée en RAM du cache ne te suffit pas ? combien de millier de visiteurs reçois tu sur tes sites ? 😉

      FHH

Laisser un commentaire

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