Accélérer le temps de démarrage de Linux : analyse et optimisation des dépendances des unités systemd
Utilisez systemd-analyze, critical-chain et le nettoyage des dépendances des unités pour trouver et corriger les chemins de démarrage lents sous Linux.
Accélérer le temps de démarrage de Linux : analyse et optimisation des dépendances des unités systemd
L'optimisation du temps de démarrage de Linux commence par une question : qu'est-ce qui bloque réellement votre machine pour qu'elle devienne utilisable ? Sur la plupart des distributions modernes, systemd démarre les services en parallèle, mais une unité lente ou une règle d'ordonnancement inutile peut encore retarder le chemin de démarrage.
En vérifiant quelles unités prennent du temps et lesquelles se trouvent sur la chaîne critique, vous pouvez décider de les ajuster, de les retarder ou de les désactiver. Les exemples ci-dessous se concentrent sur systemd-analyze et de petites modifications de dépendances qui maintiennent la prévisibilité de votre système.
Comprendre le processus de démarrage de systemd
Systemd gère le processus de démarrage en exécutant les services en parallèle chaque fois que possible. Cependant, un service ne peut démarrer que lorsque toutes ses dépendances explicites et implicites sont satisfaites. Si l'unité A nécessite que l'unité B soit complètement active avant de pouvoir continuer, l'unité A est bloquée par l'unité B. Identifier ces dépendances bloquantes est la première étape vers l'accélération.
Outils d'analyse clés de systemd
Systemd fournit plusieurs utilitaires en ligne de commande puissants pour diagnostiquer les performances de démarrage. Les outils suivants sont essentiels pour identifier les goulots d'étranglement :
1. systemd-analyze (Vue d'ensemble)
Cette commande fournit un aperçu de haut niveau du temps total pris par le noyau, l'initialisation de l'espace utilisateur et le temps passé à charger les cibles disponibles.
systemd-analyze
Interprétation de l'exemple de sortie :
| Composant | Temps pris |
|---|---|
| Noyau | 1.234s |
| Initrd | 0.500s |
| Espace utilisateur | 5.789s |
| Total | 7.523s |
Cela montre rapidement si le goulot d'étranglement se trouve dans la phase du noyau (chargement du firmware/des pilotes) ou dans la phase de l'espace utilisateur (démarrage des services).
2. systemd-analyze blame (Identification des unités lentes)
Cette commande liste les unités triées par le temps qu'elles ont passé à s'activer, les plus longues en haut.
systemd-analyze blame
Concentrez-vous : Regardez les 10 premières entrées. Ce sont les services qui consomment activement du temps lors du démarrage. Notez qu'un temps d'initialisation long peut simplement signifier que le service fait beaucoup de travail ; l'objectif est de voir si ce travail doit être effectué pendant le démarrage.
3. systemd-analyze critical-chain (Analyse des dépendances)
Cette commande affiche la chaîne de dépendances qui mène à la cible de démarrage (généralement graphical.target ou multi-user.target). Elle met en évidence la séquence d'unités qui doivent se terminer avant que le système ne soit considéré comme complètement démarré.
systemd-analyze critical-chain
Les unités listées dans la chaîne critique sont des cibles principales pour l'optimisation car les retarder retarde l'ensemble du démarrage du système.
4. systemd-analyze plot (Visualisation de la séquence de démarrage)
Pour une représentation graphique du parallélisme et du blocage, utilisez la commande plot, qui génère un fichier SVG :
systemd-analyze plot > boot_analysis.svg
# Ouvrez boot_analysis.svg dans un navigateur web
Ce graphique montre visuellement quels services s'exécutent en parallèle et lesquels attendent les autres, rendant les problèmes de dépendance immédiatement apparents.
Techniques d'optimisation : Modification des fichiers d'unité
Une fois que vous avez identifié les unités lentes ou bloquantes à l'aide des outils ci-dessus, l'optimisation consiste soit à accélérer l'unité elle-même, soit à modifier quand elle doit s'exécuter.
1. Traitement des unités lentes identifiées par blame
Si un service apparaissant en haut de la sortie blame (par exemple, slow-database.service prend 10 secondes) n'est pas immédiatement nécessaire pour le fonctionnement de base du système (comme la connexion ou le réseau de base), envisagez de le retarder.
Action : Modifiez son niveau de dépendance de démarrage.
- S'il démarre actuellement à
multi-user.target, vérifiez s'il peut démarrer à partir d'un minuteur, d'une socket, d'une unité de chemin ou d'une commande manuelle à la place. - Si le service est optionnel, le désactiver est généralement plus sûr que de modifier le comportement de dépendance principal. Utilisez
DefaultDependencies=nouniquement lorsque vous comprenez l'ordonnancement par défaut que systemd ajouterait normalement pour ce type d'unité.
2. Optimisation des dépendances avec Wants, Requires et After
Les fichiers d'unité contrôlent l'ordre d'exécution à l'aide de directives de dépendance. Une mauvaise configuration ici est une source courante d'exécution séquentielle inutile.
Types de dépendances :
Requires=: Une dépendance forte. Si l'unité requise échoue, cette unité échouera également.Wants=: Une dépendance faible. Cette unité démarre si l'unité souhaitée est disponible, mais tentera toujours de démarrer si l'unité souhaitée échoue.After=: Directive d'ordonnancement. Cette unité ne démarrera qu'après que l'unité spécifiée ait fini de démarrer (indépendamment du succès).Before=: Directive d'ordonnancement. Cette unité doit démarrer avant l'unité spécifiée.
Conseil de bonne pratique : Privilégiez Wants à Requires pour les relations optionnelles. Wants= modifie le comportement en cas d'échec, pas l'ordonnancement en soi. Une unité souhaitée peut toujours démarrer en parallèle à moins que vous n'ajoutiez également une règle d'ordonnancement comme After=.
Suppression des contraintes After= inutiles
Le moyen le plus efficace d'accélérer le temps de démarrage est d'éliminer les contraintes d'ordonnancement inutiles. Si l'unité A ne dépend pas fonctionnellement du fait que l'unité B soit démarrée avant que l'unité A ne commence, supprimez la ligne After=unit-b.service de la définition de l'unité A.
Exemple de modification (conceptuel) :
Supposons que votre unité d'application personnalisée app.service attende inutilement le service de configuration réseau :
# /etc/systemd/system/app.service
[Unit]
Description=Mon Application
Requires=network.target
After=network.target <-- Attente potentiellement inutile !
[Service]
ExecStart=/usr/bin/myapp
Si votre application n'a besoin que d'une interface de boucle locale ou seulement d'établir un verrou de fichier local, attendre la pile réseau complète (network.target) pourrait gaspiller plusieurs secondes. Si vous confirmez que l'application n'a pas vraiment besoin du réseau externe, supprimez la ligne After=network.target. Systemd tentera alors de démarrer app.service dès que possible en parallèle de la configuration réseau.
3. Masquage des services inutiles
Si systemd-analyze blame montre un service en cours d'exécution dont vous n'avez absolument pas besoin (par exemple, un support Bluetooth inutile sur un serveur, ou un moniteur matériel spécifique), le désactiver ou le masquer l'empêche complètement de démarrer.
- Désactiver :
systemctl disable <unité>(L'empêche de démarrer lors des prochains démarrages). - Masquer (plus fort) :
systemctl mask <unité>(Lie l'unité à/dev/null, empêchant également les tentatives de démarrage manuelles).
# Exemple : Masquer ModemManager si aucun modem cellulaire n'est présent
sudo systemctl mask ModemManager.service
Rechargement et vérification des modifications
Après avoir modifié un fichier d'unité (en particulier ceux placés dans /etc/systemd/system/), vous devez dire à systemd de recharger son démon de configuration avant de redémarrer pour tester :
sudo systemctl daemon-reload
# Ensuite, vérifiez les dépendances ou l'état avant de redémarrer
systemctl list-dependencies myapp.service
Enfin, redémarrez toujours le système pour mesurer l'impact réel sur la séquence de démarrage.
sudo reboot
Après le redémarrage, exécutez immédiatement systemd-analyze à nouveau pour quantifier les gains de temps obtenus grâce à vos optimisations.
À retenir
Considérez le réglage du démarrage comme une petite boucle de modification : mesurez avec systemd-analyze, trouvez les unités sur le chemin critique, supprimez uniquement les règles d'ordonnancement que vous pouvez justifier, puis redémarrez et mesurez à nouveau. Les gains les plus sûrs proviennent généralement de la désactivation des services inutiles, de la conversion du travail en minuteurs ou en activation par socket, et de la suppression des lignes After= inutiles de vos propres unités.