Causa della frammentazione della pagina sul server "grande" con xfs, 20 dischi e Ceph


18

Qualsiasi approfondimento da parte di qualcuno con un po 'di esperienza nel sistema IO Linux sarebbe utile. Ecco la mia storia:

Recentemente ha creato un cluster di sei Dell PowerEdge rx720xds per servire i file tramite Ceph. Queste macchine hanno 24 core su due socket con due zone numa e 70 gigabyte di memoria dispari. I dischi sono formattati come incursioni di un disco ciascuno (non potremmo vedere un modo per esporli direttamente altrimenti). Il networking è fornito da mellanox infiniband IP over IB (i pacchetti IP vengono trasformati in IB in kernel kernel, non in hardware).

Ciascuno dei nostri dischi SAS è montato in questo modo:

# 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

L'IO che passa attraverso queste macchine esplode a poche centinaia di MB / s, ma la maggior parte delle volte è piuttosto inattiva con un sacco di piccoli "poke":

# 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

Il problema:

Dopo circa 48 ore dopo, le pagine contigue sono così frammentate che le allocazioni di magniutde quattro (16 pagine, 65536 byte) iniziano a fallire e iniziamo a far cadere i pacchetti (a causa del fallimento di kalloc quando viene sviluppato uno SLAB).

Ecco come appare un server relativamente "sano":

# 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 

Quando la frammentazione peggiora considerevolmente, il sistema sembra iniziare a girare nello spazio del kernel e tutto cade a pezzi. Un'anomalia durante questo errore è che xfsaild sembra usare molta CPU e rimane bloccato nello stato di sospensione ininterrotto. Tuttavia, non voglio saltare a nessuna conclusione con stranezze durante un guasto totale del sistema.

Soluzione alternativa finora.

Al fine di garantire che queste allocazioni non falliscano, anche in caso di frammentazione, ho impostato:

vm.min_free_kbytes = 16777216

Dopo aver visto milioni di richieste di blkdev nelle cache SLAB, ho provato a ridurre le pagine sporche tramite:

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

Forse cambiando troppe variabili contemporaneamente, ma nel caso in cui gli inode e gli odontoiatri stessero causando la frammentazione, ho deciso di ridurli al minimo:

vm.vfs_cache_pressure = 10000

E questo sembrava aiutare. Tuttavia, la frammentazione è ancora elevata e i problemi di inode e dentatura ridotti hanno fatto sì che notassi qualcosa di strano che mi porta a ...

La mia domanda:

Perché ho così tante richieste blkdev (che sono attive non meno), che scompaiono semplicemente quando faccio cadere cache?

Ecco cosa intendo:

# 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           

Questo mi dice che l'accumulo di blkdev_request non è in realtà correlato a pagine sporche e inoltre che gli oggetti attivi non sono realmente attivi? Come possono essere liberati questi oggetti se non sono effettivamente in uso? Cosa sta succedendo qui?

Per alcuni retroscena, ecco cosa sta facendo il drop_caches:

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

Aggiornare:

Hai capito che potrebbero non essere richieste blkdev, ma potrebbero essere voci xfs_buf che compaiono sotto quella "voce"? Non sono sicuro di come funzioni:

/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/

Non so ancora perché questi siano eliminati dai 'drop_slabs', o come capire cosa sta causando questa frammentazione.

Domanda bonus: qual è il modo migliore per arrivare alla fonte di questa frammentazione?

Se leggi così lontano, grazie per la tua attenzione!

Informazioni extra richieste:

Informazioni su memoria e xfs: https://gist.github.com/christian-marie/f417cc3134544544a8d1

Errore di allocazione della pagina: https://gist.github.com/christian-marie/7bc845d2da7847534104

Follow-up: informazioni perf e cose relative alla compattazione

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

Il codice di compattazione sembra un po 'inefficiente eh? Ho messo insieme un po 'di codice per tentare di replicare le compattazioni fallite: https://gist.github.com/christian-marie/cde7e80c5edb889da541

Questo sembra riprodurre il problema.

Noterò anche che una traccia di evento mi dice che ci sono molti reclami falliti, ancora e ancora e ancora:

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

Anche l'output di Vmstat riguarda. Mentre il sistema si trova in questo stato di carico elevato, le compattazioni attraversano il tetto (e per lo più falliscono):

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

C'è davvero qualcosa di sbagliato nel recupero / compattazione.

Al momento sto cercando di ridurre le allocazioni di ordini elevati aggiungendo il supporto SG alla nostra configurazione di ipoib. Il vero problema sembra probabilmente legato a vmscan.

Questo è interessante e fa riferimento a questa domanda: http://marc.info/?l=linux-mm&m=141607142529562&w=2


2
Cavolo sì !! Non riceviamo molte di queste buone domande. Vedrò cosa possiamo fare, però.
ewwhite,

1
Potete fornire l'output /proc/buddyinfoe i risultati di free -m? Le richieste blockdev sono probabilmente rappresentate come buffer in free. Oh, e anche la distribuzione che stai usando sarebbe buona. Inoltre, hai qualche page allocation failuremessaggio che appare in dmesg? In tal caso, fornire l'output e qualsiasi contesto pertinente.
Matthew Ife,

1
Inoltre, hai usato una mkfs.xfsriga di comando specifica ? Hugepages abilitato?
ewwhite,

Anche l'uscita di/proc/meminfo
Matthew Ife il

Ho provato a disabilitare gli hugepage trasparenti (impostandoli su mai), si sono ancora verificati dei guasti. Non ho provato questo insieme ad altre "correzioni".
pingu,

Risposte:


4

Ho pensato di dare una risposta con le mie osservazioni perché ci sono molti commenti.

Basato sull'output su https://gist.github.com/christian-marie/7bc845d2da7847534104

Possiamo determinare quanto segue:

  1. GFP_MASK per l'allocazione della memoria tentata è autorizzato a fare quanto segue.
    • Può accedere ai pool di emergenza (penso che questo significhi accedere ai dati al di sotto della filigrana alta per una zona)
    • Non utilizzare le riserve di emergenza (penso che ciò significhi non consentire l'accesso alla memoria al di sotto della filigrana minima)
    • Assegna da una delle zone normali.
    • Può scambiare per fare spazio.
    • Può far cadere le cache per fare spazio.

La frammentazione della zona è la posizione qui:

[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

E l'utilizzo della memoria al momento è qui:

[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 frammentazione di ciascuna zona è errata nell'output dell'errore di allocazione della pagina. Esistono molte pagine di ordine 0 gratuite con un numero di pagine di ordine molto inferiore o nullo. Un risultato 'buono' saranno le pagine libere in abbondanza lungo ciascun ordine, che gradualmente ridurranno le dimensioni più alto sarà l'ordine. Avere 0 pagine di ordine superiore 5 e superiori indica la frammentazione e la fame per allocazioni di ordine elevato.

Al momento non vedo prove convincenti che suggeriscano che la frammentazione durante questo periodo abbia a che fare con le cache delle lastre. Nelle risultanti statistiche di memoria, possiamo vedere quanto segue

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

Non ci sono pagine enormi assegnate da userspace, e quindi userspace rivendicherà sempre la memoria dell'ordine 0. Pertanto, in entrambe le zone, vi è una memoria deframmentabile di oltre 22GiB.

Comportamenti che non posso spiegare

Quando le allocazioni di ordine elevato non riescono, è mia comprensione che la compattazione della memoria viene sempre tentata al fine di consentire che le regioni di allocazione della memoria di ordine elevato abbiano luogo e abbiano esito positivo. Perché questo non succede? Se succede, perché non riesce a trovare alcun ricordo da deframmentare quando ci sono 22GiB maturi per il riordino?

Comportamenti penso di poter spiegare

Ciò richiede ulteriori ricerche per comprendere correttamente, ma credo che la capacità dell'allocazione di scambiare / rilasciare automaticamente alcune pagecache per avere successo probabilmente non si applica qui perché c'è ancora molta memoria libera disponibile, quindi non si verificano reclami. Solo non abbastanza negli ordini superiori.

Sebbene ci sia molta memoria libera e poche richieste di ordine 4 rimaste in ogni zona, il problema "totale di tutta la memoria libera per ogni ordine e detrazione dalla memoria libera reale" provoca una "memoria libera" sotto la filigrana "min" che è cosa porta all'effettivo fallimento dell'allocazione.


Sembra strano che una piccola cache SLAB relativamente (rispetto alla memoria libera totale) frammenterebbe tutte le memorie. Mi sarei aspettato che con tutte quelle pagine libere evitabili sarebbe semplicemente sfrattato e finito. Sospetto che NUMA potrebbe avere qualcosa a che fare con questa stranezza.
pingu,

È numadin esecuzione su questo sistema?
ewwhite,

@ewwhite numad non è in esecuzione, no.
pingu,

@pingu Se questo comportamento è riproducibile, provare ad abilitare il numadservizio e prendere nota delle azioni in /var/log/numad.log. Potrebbe anche essere necessario installare libcgroup.
ewwhite

@ewwhite Okay, ne ho uno in esecuzione ora. Non sono sicuro di cosa mi aspetto che faccia o quali informazioni potremmo ottenere da esso. Cosa speri possa succedere?
pingu,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.