Lorsque des requêtes d'E/S longues se bloquent, le système peut devenir instable ou tomber en panne avant que vous ne disposiez d'assez d'informations pour diagnostiquer la cause. Alibaba Cloud Linux 2 et Alibaba Cloud Linux 3 étendent les structures de données principales du noyau pour exposer les compteurs de blocage par périphérique, les détails par requête et les informations d'attente par processus, le tout avec une faible surcharge. Cette rubrique décrit les interfaces disponibles et montre comment les utiliser.
Fonctionnement
Le noyau suit chaque requête d'E/S, de sa soumission à son achèvement. Lorsqu'une requête dépasse le seuil de blocage configuré, le noyau la marque comme bloquée. Interrogez les interfaces dans l'ordre suivant pour diagnostiquer un blocage d'E/S :
Vérifiez
/sys/block/<device>/hang— confirmez si des blocages d'E/S se sont produits sur le périphérique.Vérifiez
/sys/kernel/debug/block/<device>/rq_hang— obtenez des détails sur chaque requête bloquée.Vérifiez
/proc/<pid>/wait_resou/proc/<pid>/task/<tid>/wait_res— identifiez quel processus ou thread est bloqué et ce qu'il attend.
Interfaces
| Interface | Description | Unité |
|---|---|---|
/sys/block/<device>/queue/hang_threshold |
Interrogez ou définissez le seuil de blocage des E/S. Valeur par défaut : 5000. | ms |
/sys/block/<device>/hang |
Interrogez le nombre d'opérations d'E/S ayant dépassé le seuil de blocage. Format de sortie : <read_count> <write_count>. |
— |
/sys/kernel/debug/block/<device>/rq_hang |
Interrogez les détails des requêtes d'E/S bloquées. | — |
/proc/<pid>/wait_res |
Interrogez les ressources attendues par un processus. | — |
/proc/<pid>/task/<tid>/wait_res |
Interrogez les ressources attendues par un thread. | — |
Le tableau suivant décrit les variables présentes dans les chemins d'accès aux interfaces.
| Variable | Description |
|---|---|
<device> |
Nom du périphérique de stockage de blocs |
<pid> |
ID de processus |
<tid> |
ID de thread |
Définir le seuil de blocage
Le seuil de blocage par défaut est de 5 000 ms. Ajustez-le pour qu'il corresponde à la latence d'E/S attendue de votre charge de travail.
-
Écrivez le nouveau seuil dans l'interface. Cet exemple définit le seuil sur le disque
vdbà 10 000 ms.echo 10000 > /sys/block/vdb/queue/hang_threshold -
Vérifiez la modification.
cat /sys/block/vdb/queue/hang_thresholdSortie attendue :
10000
Vérifier le nombre de blocages
Lisez l'interface hang pour voir combien d'opérations de lecture et d'écriture ont dépassé le seuil sur un périphérique. Cet exemple utilise le disque vdb.
cat /sys/block/vdb/hang
Exemple de sortie :
0 1
La sortie contient deux valeurs séparées par des espaces :
| Champ | Description |
|---|---|
| Valeur de gauche | Nombre d'opérations de lecture ayant provoqué des blocages d'E/S |
| Valeur de droite | Nombre d'opérations d'écriture ayant provoqué des blocages d'E/S |
Dans cette sortie, 0 blocage en lecture et 1 blocage en écriture ont été enregistrés.
Inspecter les requêtes bloquées
Lisez l'interface rq_hang pour obtenir des détails sur chaque requête bloquée. Cet exemple utilise le disque vdb.
cat /sys/kernel/debug/block/vdb/rq_hang
Exemple de sortie :
ffff9e50162fc600 {.op=WRITE, .cmd_flags=SYNC, .rq_flags=STARTED|ELVPRIV|IO_STAT|STATS, .state=in_flight, .tag=118, .internal_tag=67, .start_time_ns=1260981417094, .io_start_time_ns=1260981436160, .current_time=1268458297417, .bio = ffff9e4907c31c00, .bio_pages = { ffffc85960686740 }, .bio = ffff9e4907c31500, .bio_pages = { ffffc85960639000 }, .bio = ffff9e4907c30300, .bio_pages = { ffffc85960651700 }, .bio = ffff9e4907c31900, .bio_pages = { ffffc85960608b00 }}
Chaque entrée représente une requête d'E/S bloquée. Les champs clés sont :
| Champ | Description |
|---|---|
.op |
Type d'opération d'E/S, tel que READ ou WRITE |
.cmd_flags |
Indicateurs de commande pour la requête, tels que SYNC |
.rq_flags |
Indicateurs d'état de la requête, tels que STARTED et IO_STAT |
.state |
État actuel de la requête dans la couche de bloc, tel que in_flight |
.tag |
Tag de file d'attente matérielle attribué à la requête |
.internal_tag |
Tag de file d'attente logicielle attribué en interne |
start_time_ns |
Heure de soumission de la requête à la couche de bloc (nanosecondes) |
io_start_time_ns |
Heure de début de la requête d'E/S (nanosecondes). Une valeur non nulle signifie que la requête d'E/S n'a pas été traitée rapidement, indiquant un temps d'E/S prolongé. |
current_time |
Heure de l'instantané (nanosecondes). Soustrayez io_start_time_ns de current_time pour obtenir la durée écoulée du blocage. |
.bio |
Adresse de la structure bio associée |
.bio_pages |
Adresses des pages référencées par la bio |
Identifier les processus bloqués
Lisez /proc/<pid>/wait_res pour savoir quelles ressources un processus attend. Cet exemple vérifie le processus 577.
cat /proc/577/wait_res
Exemple de sortie :
1 0000000000000000 4310058496 4310061448
La sortie contient quatre champs séparés par des espaces :
| Champ | Description |
|---|---|
| Champ 1 | Type de ressource attendue par le processus. 1 = cache de page dans le système de fichiers. 2 = couche d'E/S de bloc. |
| Champ 2 | Adresse de la ressource (entrée de cache de page ou couche d'E/S de bloc) attendue par le processus |
| Champ 3 | Heure à laquelle le processus a commencé à attendre la ressource |
| Champ 4 | Heure actuelle lors de la lecture du fichier. Soustrayez le champ 3 du champ 4 pour obtenir le temps d'attente total. |
Pour vérifier un thread spécifique, utilisez /proc/<pid>/task/<tid>/wait_res avec le même format de sortie.