Question Cause de la fragmentation de la page sur un serveur «grand» avec xfs, 20 disques et Ceph


Toute idée de quelqu'un ayant un peu d'expérience dans le système Linux IO serait utile. Voici mon histoire:

Récemment mis en place un cluster de six Dell PowerEdge rx720xds pour servir les fichiers via Ceph. Ces machines ont 24 cœurs sur deux sockets avec deux zones numa et 70 gigaoctets impairs de mémoire. Les disques sont formatés comme des raids d'un disque chacun (nous ne pourrions pas voir un moyen de les exposer directement autrement). La mise en réseau est fournie par mellanox infiniband IP over IB (les paquets IP sont transformés en IB dans le noyau, pas le matériel).

Chacun de nos disques SAS est monté comme suit:

# cat /proc/mounts | grep osd
/dev/sdm1 /var/lib/ceph/osd/ceph-90 xfs rw,noatime,attr2,inode64,noquota 0 0
/dev/sdj1 /var/lib/ceph/osd/ceph-87 xfs rw,noatime,attr2,inode64,noquota 0 0
/dev/sdu1 /var/lib/ceph/osd/ceph-99 xfs rw,noatime,attr2,inode64,noquota 0 0
/dev/sdd1 /var/lib/ceph/osd/ceph-82 xfs rw,noatime,attr2,inode64,noquota 0 0
/dev/sdk1 /var/lib/ceph/osd/ceph-88 xfs rw,noatime,attr2,inode64,noquota 0 0
/dev/sdl1 /var/lib/ceph/osd/ceph-89 xfs rw,noatime,attr2,inode64,noquota 0 0
/dev/sdh1 /var/lib/ceph/osd/ceph-86 xfs rw,noatime,attr2,inode64,noquota 0 0
/dev/sdo1 /var/lib/ceph/osd/ceph-97 xfs rw,noatime,attr2,inode64,noquota 0 0
/dev/sdc1 /var/lib/ceph/osd/ceph-81 xfs rw,noatime,attr2,inode64,noquota 0 0
/dev/sdb1 /var/lib/ceph/osd/ceph-80 xfs rw,noatime,attr2,inode64,noquota 0 0
/dev/sds1 /var/lib/ceph/osd/ceph-98 xfs rw,noatime,attr2,inode64,noquota 0 0
/dev/sdn1 /var/lib/ceph/osd/ceph-91 xfs rw,noatime,attr2,inode64,noquota 0 0
/dev/sde1 /var/lib/ceph/osd/ceph-83 xfs rw,noatime,attr2,inode64,noquota 0 0
/dev/sdq1 /var/lib/ceph/osd/ceph-93 xfs rw,noatime,attr2,inode64,noquota 0 0
/dev/sdg1 /var/lib/ceph/osd/ceph-85 xfs rw,noatime,attr2,inode64,noquota 0 0
/dev/sdt1 /var/lib/ceph/osd/ceph-95 xfs rw,noatime,attr2,inode64,noquota 0 0
/dev/sdf1 /var/lib/ceph/osd/ceph-84 xfs rw,noatime,attr2,inode64,noquota 0 0
/dev/sdr1 /var/lib/ceph/osd/ceph-94 xfs rw,noatime,attr2,inode64,noquota 0 0
/dev/sdi1 /var/lib/ceph/osd/ceph-96 xfs rw,noatime,attr2,inode64,noquota 0 0
/dev/sdp1 /var/lib/ceph/osd/ceph-92 xfs rw,noatime,attr2,inode64,noquota 0 0

Les entrées-sorties qui passent par ces machines éclatent à quelques centaines de Mo / s, mais la plupart du temps, elles sont plutôt inactives avec beaucoup de petites piqûres:

# iostat -x -m
Linux 3.10.0-123.el7.x86_64 (xxx)   07/11/14    _x86_64_    (24 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
       1.82    0.00    1.05    0.11    0.00   97.02
Device:         rrqm/s   wrqm/s     r/s     w/s    rMB/s    wMB/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
sda               0.00     0.11    0.25    0.23     0.00     0.00    27.00     0.00    2.07    3.84    0.12   0.61   0.03
sdb               0.02     0.57    3.49    2.28     0.08     0.14    77.18     0.01    2.27    2.99    1.18   1.75   1.01
sdd               0.03     0.65    3.93    3.39     0.10     0.16    70.39     0.01    1.97    2.99    0.79   1.57   1.15
sdc               0.03     0.60    3.76    2.86     0.09     0.13    65.57     0.01    2.10    3.02    0.88   1.68   1.11
sdf               0.03     0.63    4.19    2.96     0.10     0.15    73.51     0.02    2.16    3.03    0.94   1.73   1.24
sdg               0.03     0.62    3.93    3.01     0.09     0.15    70.44     0.01    2.06    3.01    0.81   1.66   1.15
sde               0.03     0.56    4.35    2.61     0.10     0.14    69.53     0.02    2.26    3.00    1.02   1.82   1.26
sdj               0.02     0.73    3.67    4.74     0.10     0.37   116.06     0.02    1.84    3.01    0.93   1.31   1.10
sdh               0.03     0.62    4.31    3.04     0.10     0.15    67.83     0.02    2.15    3.04    0.89   1.75   1.29
sdi               0.02     0.59    3.82    2.47     0.09     0.13    74.35     0.01    2.20    2.96    1.03   1.76   1.10
sdl               0.03     0.59    4.75    2.46     0.11     0.14    70.19     0.02    2.33    3.02    1.00   1.93   1.39
sdk               0.02     0.57    3.66    2.41     0.09     0.13    73.57     0.01    2.20    3.00    0.97   1.76   1.07
sdm               0.03     0.66    4.03    3.17     0.09     0.14    66.13     0.01    2.02    3.00    0.78   1.64   1.18
sdn               0.03     0.62    4.70    3.00     0.11     0.16    71.63     0.02    2.25    3.01    1.05   1.79   1.38
sdo               0.02     0.62    3.75    2.48     0.10     0.13    76.01     0.01    2.16    2.94    0.99   1.70   1.06
sdp               0.03     0.62    5.03    2.50     0.11     0.15    68.65     0.02    2.39    3.08    0.99   1.99   1.50
sdq               0.03     0.53    4.46    2.08     0.09     0.12    67.74     0.02    2.42    3.04    1.09   2.01   1.32
sdr               0.03     0.57    4.21    2.31     0.09     0.14    72.05     0.02    2.35    3.00    1.16   1.89   1.23
sdt               0.03     0.66    4.78    5.13     0.10     0.20    61.78     0.02    1.90    3.10    0.79   1.49   1.47
sdu               0.03     0.55    3.93    2.42     0.09     0.13    70.77     0.01    2.17    2.97    0.85   1.79   1.14
sds               0.03     0.60    4.11    2.70     0.10     0.15    74.77     0.02    2.25    3.01    1.10   1.76   1.20
sdw               1.53     0.00    0.23   38.90     0.00     1.66    87.01     0.01    0.22    0.11    0.22   0.05   0.20
sdv               0.88     0.00    0.16   28.75     0.00     1.19    84.55     0.01    0.24    0.10    0.24   0.05   0.14
dm-0              0.00     0.00    0.00    0.00     0.00     0.00     8.00     0.00    1.84    1.84    0.00   1.15   0.00
dm-1              0.00     0.00    0.23    0.29     0.00     0.00    23.78     0.00    1.87    4.06    0.12   0.55   0.03
dm-2              0.00     0.00    0.01    0.00     0.00     0.00     8.00     0.00    0.47    0.47    0.00   0.45   0.00

Le problème:

Après environ 48 heures plus tard, les pages contiguës sont tellement fragmentées que quatre grandes alliances (16 pages, 65 536 octets) commencent à échouer et nous commençons à supprimer des paquets (en raison de l'échec de kalloc lors de la croissance d'un SLAB).

Voici à quoi ressemble un serveur relativement "sain":

# cat /sys/kernel/debug/extfrag/unusable_index
Node 0, zone      DMA 0.000 0.000 0.000 0.001 0.003 0.007 0.015 0.031 0.031 0.096 0.225 
Node 0, zone    DMA32 0.000 0.009 0.015 0.296 0.733 0.996 0.997 0.998 0.998 1.000 1.000 
Node 0, zone   Normal 0.000 0.000 0.019 0.212 0.454 0.667 0.804 0.903 0.986 1.000 1.000 
Node 1, zone   Normal 0.000 0.027 0.040 0.044 0.071 0.270 0.506 0.772 1.000 1.000 1.000 

Lorsque la fragmentation empire considérablement, le système semble commencer à tourner dans l'espace du noyau et tout s'effondre. Une anomalie au cours de cet échec est que xfsaild semble utiliser beaucoup de ressources processeur et reste bloqué dans l'état de veille ininterruptible. Je ne veux cependant pas tirer de conclusions étranges en cas de défaillance totale du système.

Solution de contournement jusqu'à présent.

Pour que ces allocations n'échouent pas, même sous fragmentation, j'ai défini:

vm.min_free_kbytes = 16777216

Après avoir vu des millions de demandes de blkdev_ dans les caches SLAB, j'ai essayé de réduire les pages inutilisables via:

vm.dirty_ratio = 1
vm.dirty_background_ratio = 1
vm.min_slab_ratio = 1
vm.zone_reclaim_mode = 3

Peut-être changer trop de variables à la fois, mais juste au cas où les inodes et les dentiers causaient une fragmentation, j'ai décidé de les garder au minimum:

vm.vfs_cache_pressure = 10000

Et cela a semblé aider. La fragmentation est toujours élevée, et la réduction des problèmes d'inode et de dentry m'a fait remarquer quelque chose de bizarre qui m'a amené à ...

Ma question:

Pourquoi ai-je tant de demandes blkdev (qui ne sont pas moins actives), qui disparaissent tout simplement lorsque je supprime des caches?

Voici ce que je veux dire:

# slabtop -o -s c | head -20
 Active / Total Objects (% used)    : 19362505 / 19431176 (99.6%)
 Active / Total Slabs (% used)      : 452161 / 452161 (100.0%)
 Active / Total Caches (% used)     : 72 / 100 (72.0%)
 Active / Total Size (% used)       : 5897855.81K / 5925572.61K (99.5%)
 Minimum / Average / Maximum Object : 0.01K / 0.30K / 15.69K

  OBJS ACTIVE  USE OBJ SIZE  SLABS OBJ/SLAB CACHE SIZE NAME                   
2565024 2565017  99%    1.00K  80157       32   2565024K xfs_inode              
3295194 3295194 100%    0.38K  78457       42   1255312K blkdev_requests        
3428838 3399527  99%    0.19K  81639       42    653112K dentry                 
5681088 5680492  99%    0.06K  88767       64    355068K kmalloc-64             
2901366 2897861  99%    0.10K  74394       39    297576K buffer_head            
 34148  34111  99%    8.00K   8537        4    273184K kmalloc-8192           
334768 334711  99%    0.57K  11956       28    191296K radix_tree_node        
614959 614959 100%    0.15K  11603       53     92824K xfs_ili                
 21263  19538  91%    2.84K   1933       11     61856K task_struct            
 18720  18636  99%    2.00K   1170       16     37440K kmalloc-2048           
 32032  25326  79%    1.00K   1001       32     32032K kmalloc-1024           
 10234   9202  89%    1.88K    602       17     19264K TCP                    
 22152  19765  89%    0.81K    568       39     18176K task_xstate

# echo 2 > /proc/sys/vm/drop_caches                                                                                                                                                   :(
# slabtop -o -s c | head -20       
 Active / Total Objects (% used)    : 965742 / 2593182 (37.2%)
 Active / Total Slabs (% used)      : 69451 / 69451 (100.0%)
 Active / Total Caches (% used)     : 72 / 100 (72.0%)
 Active / Total Size (% used)       : 551271.96K / 855029.41K (64.5%)
 Minimum / Average / Maximum Object : 0.01K / 0.33K / 15.69K

  OBJS ACTIVE  USE OBJ SIZE  SLABS OBJ/SLAB CACHE SIZE NAME                   
 34140  34115  99%    8.00K   8535        4    273120K kmalloc-8192           
143444  20166  14%    0.57K   5123       28     81968K radix_tree_node        
768729 224574  29%    0.10K  19711       39     78844K buffer_head            
 73280   8287  11%    1.00K   2290       32     73280K xfs_inode              
 21263  19529  91%    2.84K   1933       11     61856K task_struct            
686848  97798  14%    0.06K  10732       64     42928K kmalloc-64             
223902  41010  18%    0.19K   5331       42     42648K dentry                 
 32032  23282  72%    1.00K   1001       32     32032K kmalloc-1024           
 10234   9211  90%    1.88K    602       17     19264K TCP                    
 22152  19924  89%    0.81K    568       39     18176K task_xstate            
 69216  59714  86%    0.25K   2163       32     17304K kmalloc-256            
 98421  23541  23%    0.15K   1857       53     14856K xfs_ili                
  5600   2915  52%    2.00K    350       16     11200K kmalloc-2048           

Cela me dit que l'accumulation blkdev_request est ne pas en fait lié aux pages sales, et en outre que les objets actifs ne sont pas vraiment actifs? Comment libérer ces objets s'ils ne sont pas réellement utilisés? Qu'est-ce qui se passe ici?

Voici un peu ce que fait drop_caches:

http://lxr.free-electrons.com/source/fs/drop_caches.c

Mettre à jour:

Vous avez compris qu'ils pourraient ne pas être blkdev_requests, mais que des entrées xfs_buf apparaissent sous cet "en-tête"? Je ne suis pas sûr de comment cela fonctionne:

/sys/kernel/slab # ls -l blkdev_requests(
lrwxrwxrwx 1 root root 0 Nov  7 23:18 blkdev_requests -> :t-0000384/

/sys/kernel/slab # ls -l | grep 384
lrwxrwxrwx 1 root root 0 Nov  7 23:18 blkdev_requests -> :t-0000384/
lrwxrwxrwx 1 root root 0 Nov  7 23:19 ip6_dst_cache -> :t-0000384/
drwxr-xr-x 2 root root 0 Nov  7 23:18 :t-0000384/
lrwxrwxrwx 1 root root 0 Nov  7 23:19 xfs_buf -> :t-0000384/

Je ne sais toujours pas pourquoi elles sont supprimées par les 'drop_slabs', ni comment déterminer la cause de cette fragmentation.

Question bonus: quel meilleur moyen de parvenir à la source de cette fragmentation?

Si vous lisez jusqu'à présent, merci de votre attention!

Informations supplémentaires demandées:

Informations mémoire et xfs: https://gist.github.com/christian-marie/f417cc3134544544a8d1

Échec d'allocation de page: https://gist.github.com/christian-marie/7bc845d2da7847534104

Suivi: informations sur le perf et les choses liées au compactage

http://ponies.io/raw/compaction.png

Le code de compactage semble un peu inefficace hein? J'ai bricolé du code pour tenter de répliquer les compactions échouées: https://gist.github.com/christian-marie/cde7e80c5edb889da541

Cela semble reproduire le problème.

Je noterai également qu'une trace d'événement m'indique qu'il y a beaucoup de demandes de récupération échouées, encore et encore:

<...>-322 [023] .... 19509.445609: mm_vmscan_direct_reclaim_end: nr_reclaimed=1

La sortie Vmstat est également préoccupante. Tandis que le système est dans cet état de charge élevée, les compactions passent par le toit (et échouent pour la plupart):

pgmigrate_success 38760827 pgmigrate_fail 350700119 compact_migrate_scanned 301784730 compact_free_scanned 204838172846 compact_isolated 18711615 compact_stall 270115 compact_fail 244488 compact_success 25212

Il y a effectivement quelque chose qui ne va pas avec récupération / compactage.

Pour le moment, je cherche à réduire les allocations d'ordre élevé en ajoutant le support SG à notre configuration ipoib. Le vrai problème semble lié à vmscan.

Ceci est intéressant et fait référence à cette question: http://marc.info/?l=linux-mm&m=141607142529562&w=2


18
2017-11-07 23:09


origine


Heck ouais !! Nous ne recevons pas beaucoup de ces bonnes questions. Je verrai ce que nous pouvons faire, cependant. - ewwhite
S'il vous plaît pouvez-vous fournir la sortie de /proc/buddyinfo et les résultats de free -m? Les requêtes blockdev sont Probablement représentés en tant que tampons dans free. Oh, et la distribution que vous utilisez serait bien aussi. De plus, avez-vous des page allocation failure messages apparaissant dans dmesg? Si tel est le cas, veuillez fournir le résultat, ainsi que tout contexte pertinent. - Matthew Ife
Avez-vous également utilisé un mkfs.xfs ligne de commande? Hugepages activé? - ewwhite
Aussi la sortie de /proc/meminfo - Matthew Ife
J'ai essayé de désactiver les pages gigantesques transparentes par eux-mêmes (en les réglant sur jamais), mais un échec s'est toujours produit. Je n'ai pas essayé ceci en conjonction avec d'autres 'correctifs'. - pingu


Réponses:


Je pensais mettre une réponse avec mes observations car il y avait beaucoup de commentaires.

Basé sur votre sortie à https://gist.github.com/christian-marie/7bc845d2da7847534104

Nous pouvons déterminer ce qui suit:

  1. Le GFP_MASK pour l'allocation de mémoire essayée est autorisé à effectuer les opérations suivantes.
    • Peut accéder aux piscines d’urgence (je pense cela signifie que les données d'accès en dessous du haut filigrane d'une zone)
    • Ne pas utiliser les réserves d'urgence (je pense cela signifie ne pas autoriser l'accès à la mémoire en dessous du filigrane min)
    • Allouer à partir de l'une des zones normales.
    • Peut échanger afin de faire de la place.
    • Peut laisser tomber les caches afin de faire de la place.

La fragmentation de zone se situe ici:

[3443189.780792] Node 0 Normal: 3300*4kB (UEM) 8396*8kB (UEM) 4218*16kB (UEM) 76*32kB (UEM) 12*64kB (M) 0*128kB 0*256kB 0*512kB 0*1024kB 0*2048kB 0*4096kB = 151056kB
[3443189.780801] Node 1 Normal: 26667*4kB (UEM) 6084*8kB (UEM) 2040*16kB (UEM) 96*32kB (UEM) 22*64kB (UEM) 4*128kB (U) 0*256kB 0*512kB 0*1024kB 0*2048kB 0*4096kB = 192972kB

Et l'utilisation de la mémoire à l'époque est ici:

[3443189.780759] Node 0 Normal free:149520kB min:40952kB low:51188kB high:61428kB active_anon:9694208kB inactive_anon:1054236kB active_file:7065912kB inactive_file:7172412kB unevictable:0kB isolated(anon):5452kB isolated(file):3616kB present:30408704kB managed:29881160kB mlocked:0kB dirty:0kB writeback:0kB mapped:25440kB shmem:743788kB slab_reclaimable:1362240kB slab_unreclaimable:783096kB kernel_stack:29488kB pagetables:43748kB unstable:0kB bounce:0kB free_cma:0kB writeback_tmp:0kB pages_scanned:0 all_unreclaimable? no
[3443189.780766] Node 1 Normal free:191444kB min:45264kB low:56580kB high:67896kB active_anon:11371988kB inactive_anon:1172444kB active_file:8084140kB inactive_file:8556980kB unevictable:0kB isolated(anon):4388kB isolated(file):4676kB present:33554432kB managed:33026648kB mlocked:0kB dirty:0kB writeback:0kB mapped:45400kB shmem:2263296kB slab_reclaimable:1606604kB slab_unreclaimable:438220kB kernel_stack:55936kB pagetables:44944kB unstable:0kB bounce:0kB free_cma:0kB writeback_tmp:0kB pages_scanned:0 all_unreclaimable? no

La fragmentation de chaque zone est incorrecte dans la sortie d'échec d'allocation de page. Il y a beaucoup de pages de commande gratuites 0 avec beaucoup moins à aucune page d'ordre supérieur. Un bon résultat correspond à de nombreuses pages gratuites le long de chaque commande. Plus la taille de la commande est élevée, plus sa taille diminue progressivement. Le fait d'avoir 0 pages d'ordre supérieur 5 et supérieures indique une fragmentation et une famine pour les allocations d'ordre élevé.

À l'heure actuelle, je ne vois pas suffisamment d'éléments probants pour suggérer que la fragmentation au cours de cette période a tout à voir avec les caches de dalles. Dans les statistiques de mémoire résultantes, nous pouvons voir ce qui suit

Node 0 = active_anon:9694208kB inactive_anon:1054236kB
Node 1 = active anon:11371988kB inactive_anon:1172444kB

Il n'y a pas de pages énormes attribuées depuis l'espace utilisateur, et l'espace utilisateur réclamera donc toujours l'ordre 0 mémoire. Ainsi, dans les deux zones, il y a plus de 22 Go de mémoire défragmentable.

Comportements que je ne peux pas expliquer

Quand les allocations d’ordre élevé échouent, je crois comprendre que le compactage de la mémoire est toujours essayé afin de permettre aux régions d’allocation de mémoire d’ordre élevé d’avoir lieu et de réussir. Pourquoi cela n'arrive-t-il pas? Si cela se produit, pourquoi ne trouve-t-il pas de mémoire à défragmenter alors qu'il y a 22 Go de mémoire prête à être réorganisée?

Comportements que je pense pouvoir expliquer

Cela nécessite davantage de recherche pour bien comprendre, mais je pense que la capacité de l'allocation de permuter / supprimer automatiquement certains pagecache pour réussir ne s'applique probablement pas ici car il reste encore beaucoup de mémoire libre, donc aucune récupération n'est effectuée. Juste pas assez dans les ordres supérieurs.

Bien qu'il y ait beaucoup de mémoire libre et il reste quelques demandes d'ordre 4 dans chaque zone; le problème "total de la mémoire libre pour chaque commande et déduction de la mémoire libre réelle" donne lieu à une "mémoire libre" en dessous du filigrane "min", ce qui conduit à l'échec de l'allocation réelle .


4
2017-11-08 02:01



Il semble étrange qu'un cache SLAB relativement petit (à la mémoire totale totale) fragmente toutes les mémoires. Je me serais attendu à ce que toutes ces pages gratuites et expulsables en expulsent simplement quelques unes. Je pense que NUMA pourrait avoir quelque chose à voir avec cette étrangeté. - pingu
Est numad en cours d'exécution sur ce système? - ewwhite
@ewwhite numad ne fonctionne pas, non. - pingu
@pingu Si ce comportement est reproductible, essayez d'activer le numad service et prendre note des actions en /var/log/numad.log. Vous devrez peut-être aussi installer libcgroup. - ewwhite
@ewwhite Ok, j'en ai un en cours d'exécution maintenant. Je ne suis pas sûr de ce que je m'attends à faire ou des informations que nous pourrions en tirer. Qu'espérez-vous pouvoir arriver? - pingu