Server@Home
Economie d'énergie : disques
Comme on s'intéresse ici à un serveur, il n'y a pas d'écrans ou autres
périphériques consommateurs d'énergie. Pour économiser l'énergie
consommée par le serveur, le gros du travail va donc concerner les
disques. Les deux possibilités principales sont :
- placer le disque dur en mode standby aussi souvent que possible
- remplacer un disque dur traditionnel par une mémoire flash
Dans les deux cas, la problématique est la même : il faut
limiter autant que possible
la fréquence des accès au disque dur. En effet, la durée de vie d'une mémoire flash
est limitée par le nombre de cycles lecture/écriture supportés. D'autre part, chaque accès
à un disque dur le fait nécessairement sortir du mode
standby. Une grande partie
des idées présentées ici provient originellement de
cette
page.
Arrêt du disque dur en cas d'inactivité
Mode standby
Sur les disques durs modernes, il existe un mode de fonctionnement en
économie d'énergie (mode
standby), dans lequel le disque dur
s'arrête de tourner.
L'utilitaire
hdparm
permet de gérer différents aspect de configuration des périphériques IDE. En particulier,
il permet de configurer la durée d'inactivité après laquelle le disque dur doit passer en
mode d'économie d'énergie (
standby).
Test des commandes hdparm
On peut commencer par tester temporairement l'effet de
hdparm, en utilisant les options de la ligne de
commande.
Pour configurer la durée d'inactivité avant le mode
standby, on
utilise l'option
-S (la table de correspondance entre la
valeur passée à l'option et la durée d'inactivité correspondante est
disponible dans la page de manuel) :
# hdparm -S 120 /dev/hda
/dev/hda:
setting standby to 120 (10 minutes)
Pour passer immédiatement en mode
standby, on utilise l'option
-y :
# hdparm -y /dev/hda
/dev/hda:
issuing standby command
L'état actuel du disque dur est donné par l'option
-C :
# hdparm -C /dev/hda
/dev/hda:
drive state is: standby
Configuration définitive de hdparm
Lorsqu'on a déterminé la période optimale de passage en mode
standby, on peut configurer de manière plus définitive les
options de
hdparm. Pour cela, on utilise le fichier de
configuration de
hdparm qui est lu à chaque démarrage du
serveur :
/etc/hdparm.conf :
/dev/hda {
spindown_time = 120
}
Monitoring de l'activité des disques
Le mode
standby des disques durs est très intéressants, mais requiert que le disque
passe de long intervalles de temps sans recevoir de requêtes. En effet, dès que le disque
reçoit la moindre requête, il doit se remettre à tourner pour pouvoir y répondre. Outre le
fait que le "réveil" du disque est assez long et induit de gros délais sur les temps de
réponse du système, il faut être conscient que la plupart des disques durs (surtout les
disques 3.5" destinés aux PC Desktop), ne sont pas conçus pour subir des cycles
activité/standby trop fréquents.
Pour être capable de vraiment diminuer la quantité d'accès aux disques, la première étape
consiste à monitorer ces accès et à déterminer quelles en sont les causes. Dans un
deuxième temps, une fois qu'on a assez restreint la quantité d'accès à un disque dur, on
peut le configurer pour passer en mode d'économie d'énergie (
standby) en cas
d'inactivité. A partir de ce moment là, le monitoring des changements d'état du disque
l'état du disque (
standby -> actif) permet de détecter très finement
le moindre accès disque ponctuel. Une analyse fine des logs peut permettre d'en trouver
l'origine et éventuellement de supprimer encore quelques accès.
Monitoring des accès disque
Le paquet Debian
sysstats
contient des outils utiles pour surveiller (entre autres) les I/O sur le disque
dur.
Par exemple :
# iostat -d 1 3
Linux 2.6.18-4-686 (zenega) 06/29/2007
Device: tps Blk_read/s Blk_wrtn/s Blk_read Blk_wrtn
hda 0.24 5.23 0.22 58979 2534
Device: tps Blk_read/s Blk_wrtn/s Blk_read Blk_wrtn
hda 0.00 0.00 0.00 0 0
Device: tps Blk_read/s Blk_wrtn/s Blk_read Blk_wrtn
hda 0.00 0.00 0.00 0 0
ou bien :
# sar -d 1 3
Linux 2.6.18-4-686 (zenega) 06/29/2007
03:13:01 PM DEV tps rd_sec/s wr_sec/s avgrq-sz avgqu-sz await svctm %util
03:13:02 PM dev3-0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
03:13:02 PM DEV tps rd_sec/s wr_sec/s avgrq-sz avgqu-sz await svctm %util
03:13:03 PM dev3-0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
03:13:03 PM DEV tps rd_sec/s wr_sec/s avgrq-sz avgqu-sz await svctm %util
03:13:04 PM dev3-0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
Average: DEV tps rd_sec/s wr_sec/s avgrq-sz avgqu-sz await svctm %util
Average: dev3-0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
J'ai pris cet exemple après avoir appliqué toutes les techniques
expliquées dans la suite de ce document pour réduire la fréquence des
accès aux disques. On voit clairement que les accès disque ont été
reduits à leur minimum (zéro !)
Monitoring de l'état du disque dur
Comme on l'a vu précédement; la commande
hdparm -C permet de connaitre l'état
d'activité d'un disque dur (actif ou en mode standby). Voici un petit script bash qui
permet de suivre l'état du disque et de noter chaque changement d'état.
#! /bin/bash
while true ; do
STATE=$( \
hdparm -C /dev/hda |
perl -ne 'print if s/\s*drive state is:\s+//' )
if [ ! "${STATE}" = "${STATE_OLD}" ] ; then
STATE_OLD=${STATE}
DATE=$(date)
echo -e "${DATE}\t${STATE}"
fi
sleep 1
done
Attention, lors du lancement du script,
bash effectue plein
d'accès à des fichiers de
/etc et
/home. Ceci peut
"réveiller" artificiellement le(s) disque(s) sur lesquels ces
répertoires sont montés. Comme le script ne fait plus d'acès disques
après, ça ne perturbe l'état du disque qu'au début, mais il vaut mieux
être conscient de l'existence de cet effet collatéral.
Réduction de la fréquence des accès au disque
Option de montage noatime
Un premier petit coup de
sar
permet immédiatement de remarquer un phénomène inattendu : on passe
notre temps à écrire sur les disques !
Certains systèmes de fichiers (en particulier les systèmes de fichiers
journalisés comme par exemple
ext2 ou
ext3) tiennent à jour
une date de dernier accès (
atime) pour chaque fichier. Ceci signifie
que chaque lecture sur le système de fichiers provoque aussi la mise à jour de
la date de dernier accès au fichier. On peut éviter ceci (et ainsi économiser de
nombreux accès en écriture) en utilisant l'option
noatime au montage de
toutes les partitions du disque :
ex:
/etc/fstab :
/dev/hda1 / ext3 defaults,errors=remount-ro,noatime 0 1
Montage de /var/log en mémoire vive
La deuxième source importante d'utilisation des disques durs est
l'écriture des journaux du système et des différents services. On
pourrait essayer de reconfigurer
syslogd et tous les démons
pour éviter les logs inutiles, mais une solution beaucoup plus simple
consiste à monter
/var/log en mémoire vive, avec un système
de fichiers
tmpfs :
/etc/fstab :
tmpfs /var/log tmpfs size=10m 0 0
L'inconvénient d'une telle solution est que les logs sont perdus à
chaque arrêt de la machine (puisque la mémoire vive est effacée). Si
l'on souhaite garder les logs (ce qui est assez recommandé pour un
serveur), il faut donc mettre en place un système de back-up régulier
des logs sur le disque.
Fonctionnement de la gestion des logs sous Debian
Dans un système classique, la gestion des logs se résume à leur
rotation : pour éviter que les fichiers de logs prennent trop de
place, on jette périodiquement (en général tous les jours ou toutes
les semaines) les logs trop anciens.
Sous Debian, la rotation des logs est assurée par deux mécanismes :
- syslogd : la plupart des journaux du système
(/var/log/syslog, /var/log/auth.log, /var/log/daemon.log,
etc.) sont gérés par le démon syslogd. Leur rotation est assurée par
des scripts cron appelés quotidiennement et hebdomadairement :
/etc/cron.daily/sysklogd et /etc/cron.weekly/sysklogd.
- logrotate : bien que certains services utilisent aussi
syslogd pour écrire leurs journaux, beaucoup d'autres (comme par exemple
Apache) préfèrent écrire eux-même dans leurs propres fichiers de log. Dans ce cas, la
rotation des logs est effectuée par l'outil logrotate. logrotate est
conçu pour permettre une rotation des journaux aussi peu intrusive que possible
(i.e. il ne faut pas que la rotation d'un fichier de log perturbe le fonctionnement du
démon qui est en train d'écrire dedans). Chaque service est installé par défaut avec
un fichier de configuration de logrotate placé dans le répertoire
/etc/logrotate.d. Un script cron (/etc/cron.daily/logrotate) appelle
quotidiennement logrotate pour qu'il effectue la rotation des journaux.
Mécanisme de sauvegarde des journaux
Si
/var/log est monté en mémoire vive et que nous voulons sauvegarder
régulièrement les logs sur le disque dur, il nous faut rajouter une couche supplémentaire
au mécanisme traditionnel de rotation des logs.
Typiquement, le système de back-up des logs doit permettre deux choses :
- Sauvegarder les logs (sic !), de manière non-obtrusive pour les démons qui les
gèrent, régulièrement et juste avant l'arrêt du système
- Restaurer les logs au démarrage du système
Pour effectuer la sauvegarde de manière complètement non-intrusive pour les démons, l'une
des meilleures manières consiste à forcer une rotation des logs, et ne sauvegarder que les
logs "tournés".
Suivant cette idée, j'ai essayé de mettre en place un système global et modulaire de
sauvegarde des logs (que j'ai appelé
logbackup), dont le fonctionnement est le
suivant :
- Le système de rotation traditionnel des journaux est désactivé
- Un répertoire /etc/logbackup.d contient des shell-scripts permettant de
gérer différents fichiers de log. Ces shell-scripts supportent les deux
commandes :
- retrieve : restaure les logs depuis le répertoire de back-up vers
/var/log. Les fichiers de logs ne sont restaurés que s'il y en a besoin
(i.e. si /var/log ne contient pas le journal concerné).
- backup : restaure les logs si besoin, effectue la rotation des logs, et
sauvegarde les journaux "tournés". La rotation des logs est assurée en appelant
directement le script de rotation sysklogd ou logrotate concerné
suivant les cas.
- Un script /etc/init.d/logbackup permet d'appeler d'un seul coup tous les
scripts de /etc/logbackup.d en leur envoyant la commande :
- retrieve juste après le démarrage du système (/etc/init.d/logbackup start)
- backup juste avant l'arrêt du système (/etc/init.d/logbackup stop)
- backup sur appel direct (/etc/init.d/logbackup reload)
- Un script cron /etc/cron.daily appelle /etc/init.d/logbackup
reload pour forcer la sauvegarde des logs au moins une fois par jour.
En termes d'implémentation, voici ce que ça donne :
/etc
|
|-- cron.daily
| |-- logrotate # Appel quotidien de logbackup au lieu de logrotate
| `-- sysklogd # Désactivation de la rotation quotidienne avec syslogd
|
|-- cron.weekly
| `-- sysklogd # Désactivation de la rotation hebdomadaire avec syslogd
|
|-- init.d
| `-- logbackup # Gestion globale de logbackup
|
|-- logbackup.conf # Fichier de configuration global
|
|-- logbackup.d
| |-- clean # Suppression des logs non désirés
| |-- skeleton # Modèle de script logbackup
| `-- syslog # Gestion des logs système
|
`-- logrotate.d
`-- login # Rotation des journaux de login (wtmp, btmp, lastlog)
Mise en place et utilisation de logbackup
Pour installer logbackup, vous pouvez télécharger l'archive tgz :
logbackup.tar.gz, qui contient tous les fichiers nécessaires.
Désarchivez puis lancez le script d'installation
logbackup:
$ wget http://francesco.ovh.org/serveur/logbackup.tar.gz
$ tar xzf logbackup.tar.gz
$ su
# cd logbackup
# ./logbackup config
###############################################
# Configuring system logs rotation and backup #
###############################################
Using configuration file config/etc/cron.daily/sysklogd
Using configuration file config/etc/cron.weekly/sysklogd
Using configuration file config/etc/init.d/logbackup
Using configuration file config/etc/logbackup.conf
Using configuration file config/etc/cron.daily/logrotate
Using configuration file config/etc/logbackup.d/syslog
Using configuration file config/etc/logbackup.d/clean
Using configuration file config/etc/logrotate.d/login
Removing any system startup links for /etc/init.d/logbackup ...
Adding system startup for /etc/init.d/logbackup ...
/etc/rc0.d/S37logbackup -> ../init.d/logbackup
/etc/rc2.d/S17logbackup -> ../init.d/logbackup
/etc/rc3.d/S17logbackup -> ../init.d/logbackup
/etc/rc4.d/S17logbackup -> ../init.d/logbackup
/etc/rc5.d/S17logbackup -> ../init.d/logbackup
/etc/rc6.d/S37logbackup -> ../init.d/logbackup
On peut lancer manuellement la rotation et sauvegarde des logs avec la commande
invoke-rc.d logbackup reload
Après chaque exécution de
logbackup, le fichier
/var/log/logbackup.included contient la liste de journaux sauvegardés par
logbackup. Inversement, le fichier
/var/log/logbackup.omitted contient
la liste des journaux qui n'ont pas été traités. Ces journaux sont à surveiller car rien
ne les empêche de grossir démesurément et d'occuper toute la place sur la partition
/var/log. Si ces journaux ne vous intéressent pas, vous pouvez les rajouter dans
la liste des fichiers traités par
/etc/logbackup.d/clean pour qu'ils soient
automatiquement détruits. Si vous voulez sauvegarder certains journaux qui ne sont pas
encore gérés par
logbackup, vous pouvez vous inspirer de
/etc/logbackup.d/skeleton pour construire un script
logbackup permettant
de les sauvegarder.
Tâches cron
Par défaut, le démon
cron se réveille donc toutes les heures pour exécuter les scripts présents dans le répertoire
/etc/cron.hourly. Si ce répertoire esst vide (ce qui est en général le cas), vous pouvez commenter la ligne correspondante dans la
crontab principale :
/etc/crontab :
# /etc/crontab: system-wide crontab
# Unlike any other crontab you don't have to run the `crontab'
# command to install the new version when you edit this file
# and files in /etc/cron.d. These files also have username fields,
# that none of the other crontabs do.
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
# m h dom mon dow user command
#17 * * * * root cd / && run-parts --report /etc/cron.hourly
25 6 * * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6 * * 7 root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6 1 * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )
#
Configuration de ntpd
En monitorant l'état du disque dur à l'aide d'
hdparm, on
observe un certain nombre de "réveils" du disque suivant un motif
régulier :
# monitor_hdparm > /var/log/monitor_hdparm &
# tail -f /var/log/monitor_hdparm
Mon Jul 16 10:12:10 CEST 2007 active/idle
Mon Jul 16 10:26:11 CEST 2007 standby
Mon Jul 16 10:29:54 CEST 2007 active/idle
Mon Jul 16 10:47:31 CEST 2007 standby
Mon Jul 16 13:00:06 CEST 2007 active/idle
Mon Jul 16 13:45:39 CEST 2007 standby
Mon Jul 16 14:29:53 CEST 2007 active/idle
Mon Jul 16 14:40:25 CEST 2007 standby
Mon Jul 16 14:57:50 CEST 2007 active/idle
Mon Jul 16 15:08:31 CEST 2007 standby
Mon Jul 16 15:25:52 CEST 2007 active/idle
Mon Jul 16 15:40:21 CEST 2007 standby
Mon Jul 16 16:29:54 CEST 2007 active/idle
Mon Jul 16 16:40:27 CEST 2007 standby
Mon Jul 16 17:29:54 CEST 2007 active/idle
Mon Jul 16 17:48:14 CEST 2007 standby
Mon Jul 16 20:29:54 CEST 2007 active/idle
Mon Jul 16 20:40:27 CEST 2007 standby
Mon Jul 16 21:29:53 CEST 2007 active/idle
Mon Jul 16 21:40:28 CEST 2007 standby
Mon Jul 16 23:29:54 CEST 2007 active/idle
Mon Jul 16 23:40:25 CEST 2007 standby
Tue Jul 17 02:29:54 CEST 2007 active/idle
Tue Jul 17 02:40:28 CEST 2007 standby
Tue Jul 17 03:29:54 CEST 2007 active/idle
Tue Jul 17 03:40:24 CEST 2007 standby
Tue Jul 17 04:29:53 CEST 2007 active/idle
Tue Jul 17 04:40:25 CEST 2007 standby
Tue Jul 17 05:29:54 CEST 2007 active/idle
Tue Jul 17 05:40:26 CEST 2007 standby
Tue Jul 17 06:25:07 CEST 2007 active/idle
Tue Jul 17 06:40:28 CEST 2007 standby
Tue Jul 17 07:29:53 CEST 2007 active/idle
Tue Jul 17 07:40:34 CEST 2007 standby
Tue Jul 17 08:29:54 CEST 2007 active/idle
Tue Jul 17 08:40:29 CEST 2007 standby
Tue Jul 17 10:15:06 CEST 2007 active/idle
Après quelques recherches, il apparaît que
cron n'a rien à
voir avec ces réveils, mais que c'est
ntpd le fautif :
# ls -al /var/lib/ntp/ntp.drift
-rw-r--r-- 1 ntp ntp 8 2007-07-17 08:29 /var/lib/ntp/ntp.drift
En effet,
ntpd met régulièrement à jour (toutes les heures,
par défaut) la valeur de dérive de l'horloge dans le
driftfile. Déplacer ce fichier dans
/var/log (que
l'on a monté en
tmpfs) permet d'éviter un réveil du disque
inutile.
/etc/ntp.conf :
# Put the drift file on /var/log (tmpfs partition)
driftfile /var/log/ntp.drift