Les systèmes Linux en cours d'exécution depuis longtemps peuvent subir une fragmentation de la mémoire, source de variations de performances lors des allocations d'ordre élevé. Appliquez les méthodes suivantes pour réduire cette fragmentation de manière proactive.
Symptômes
Les services hébergés sur l'instance subissent des temps de réponse longs et intermittents, ou des pics de latence des appels système. L'utilisation CPU sys augmente. Le buddy system signale une pénurie de mémoire d'ordre élevé (blocs avec order > 3). Exécutez cat /proc/buddyinfo pour vérifier : à partir de la quatrième colonne, chaque colonne indique le nombre de pages libres pour cet order :
cat /proc/buddyinfo
Node 0, zone DMA 1 0 0 1 2 1 1 0 1 1 3
Node 0, zone DMA32 3173 856 529 0 0 0 0 0 0 0 0
Node 0, zone Normal 19030 8688 7823 0 0 0 0 0 0 0 0
Cause
Avec le temps, les grands blocs contigus de mémoire physique se fragmentent en blocs plus petits et non contigus. Lorsqu'un service demande une allocation contiguë importante, le noyau déclenche une compaction de la mémoire. Ce processus lent provoque des variations de performances. Voici un exemple typique de trace de pile du noyau liée à la fragmentation :
0xffffffff8118f9cb compaction_alloc ([kernel.kallsyms])
0xffffffff811c88a9 migrate_pages ([kernel.kallsyms])
0xffffffff811901ee compact_zone ([kernel.kallsyms])
0xffffffff8119041b compact_zone_order ([kernel.kallsyms])
0xffffffff81190735 try_to_compact_pages ([kernel.kallsyms])
0xffffffff81631cb4 __alloc_pages_direct_compact ([kernel.kallsyms])
0xffffffff811741d5 __alloc_pages_nodemask ([kernel.kallsyms])
0xffffffff811b5a79 alloc_pages_current ([kernel.kallsyms])
0xffffffff811c0005 new_slab ([kernel.kallsyms])
0xffffffff81633848 __slab_alloc ([kernel.kallsyms])
0xffffffff811c5291 __kmalloc_node_track_caller ([kernel.kallsyms])
0xffffffff8151a8c1 __kmalloc_reserve.isra.30 ([kernel.kallsyms])
0xffffffff8151b7cd alloc_sib ([kernel.kallsyms])
0xffffffff815779e9 sk_stream_alloc_skb ([kernel.kallsyms])
0xffffffff8157872d tcp_sendmsg ([kernel.kallsyms])
0xffffffff815a26b4 inet_sendmsg ([kernel.kallsyms])
0xffffffff81511017 sock_aio_write ([kernel.kallsyms])
0xffffffff811df729 do_sync_readv_writev ([kernel.kallsyms])
0xffffffff811e0cfe do_readv_writev ([kernel.kallsyms])
Solutions
utilisez les méthodes suivantes pour atténuer la fragmentation de la mémoire :
-
Ajustez le watermark min
Définissez le watermark min entre 1 % et 3 % de la mémoire totale (2 % recommandé). Cela déclenche une récupération asynchrone plus tôt lorsque la mémoire libre est faible. Exécutez la commande suivante :
sysctl -w vm.min_free_kbytes = memtotal_kbytes * 2%Remplacez
memtotal_kbytes * 2%par 2 % de la mémoire totale de votre instance en Ko. -
Modifiez l'écart entre les watermarks min et low
Le paramètre du noyau
watermark_scale_factorcontrôle l'écart entre les watermarks min et low, ce qui aide à absorber les allocations soudaines. Écart par défaut : 0,1 % de la mémoire totale ; minimum : la moitié du watermark min. Pour ajusterwatermark_scale_factor, exécutez la commande suivante :sysctl -w vm.watermark_scale_factor = valuevalueest un facteur d'échelle qui ajuste l'écart entre lemin watermarket lelow watermark. -
Effectuez périodiquement une compaction de la mémoire
Pendant les heures creuses, déclenchez manuellement une
memory compactionasynchrone :echo 1 > /proc/sys/vm/compact_memory -
Videz régulièrement le cache
Si les méthodes précédentes s'avèrent insuffisantes, videz le cache pendant une fenêtre de maintenance planifiée. Cette opération libère des pages mémoire pour une réallocation et réduit efficacement la fragmentation, mais elle peut causer des variations temporaires de performance. Exécutez la commande suivante :
echo 3 > /proc/sys/vm/drop_caches