Causa de la fragmentación de la página en el servidor "grande" con xfs, 20 discos y Ceph

18

Cualquier idea de alguien con un poco de experiencia en el sistema Linux IO sería útil. Aquí está mi historia:

Recientemente saqué un grupo de seis Dell PowerEdge rx720xds para servir archivos a través de Ceph. Estas máquinas tienen 24 núcleos en dos zócalos con dos zonas numa y 70 gigabytes impares de memoria. Los discos están formateados como incursiones de un disco cada uno (de lo contrario, no podríamos ver una manera de exponerlos directamente). La conexión en red es proporcionada por mellanox infiniband IP sobre IB (los paquetes IP se convierten en IB en la tierra del kernel, no en el hardware).

Tenemos cada una de nuestras unidades SAS montadas así:

# 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

El IO que pasa por estas máquinas explota a unos pocos cientos de MB / s, pero la mayoría de las veces está inactivo con muchos pequeños 'pokes':

# 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

El problema:

Después de aproximadamente 48 horas más tarde, las páginas contiguas están tan fragmentadas que magniutde cuatro (16 páginas, 65536 bytes) las asignaciones comienzan a fallar y comenzamos a soltar paquetes (debido a la falla de kalloc cuando crece una SLAB).

Así es como se ve un servidor relativamente "saludable":

# 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 

Cuando la fragmentación empeora considerablemente, el sistema parece comenzar a girar en el espacio del núcleo y todo se desmorona. Una anomalía durante esta falla es que xfsaild parece usar mucha CPU y se queda atascado en el estado de suspensión ininterrumpible. Sin embargo, no quiero sacar conclusiones extrañas durante una falla total del sistema.

Solución alternativa hasta ahora.

Para garantizar que estas asignaciones no fallen, incluso bajo fragmentación, establecí:

vm.min_free_kbytes = 16777216

Después de ver millones de blkdev_requests en cachés SLAB, intenté reducir las páginas sucias a través de:

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

Posiblemente cambiando demasiadas variables a la vez, pero en caso de que los inodes y dentries estuvieran causando fragmentación, decidí mantenerlos al mínimo:

vm.vfs_cache_pressure = 10000

Y esto pareció ayudar. Sin embargo, la fragmentación sigue siendo alta, y los problemas reducidos de inodo y nebulización significaron que noté algo extraño que me lleva a ...

Mi pregunta:

¿Por qué tengo tantas blkdev_requests (que están activas no menos), que simplemente desaparecen cuando suelto cachés?

Esto es lo que quiero decir:

# 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           

Esto me dice que la acumulación de blkdev_request no está relacionada con páginas sucias y, además, que los objetos activos no están realmente activos. ¿Cómo se pueden liberar estos objetos si de hecho no están en uso? ¿Que esta pasando aqui?

Para algunos antecedentes, esto es lo que está haciendo drop_caches:

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

Actualizar:

¿Resolvió que podrían no ser blkdev_requests, pero pueden ser entradas xfs_buf que aparecen debajo de ese 'encabezado'? No estoy seguro de cómo funciona esto:

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

Todavía no sé por qué estos son eliminados por 'drop_slabs', o cómo averiguar qué está causando esta fragmentación.

Pregunta adicional: ¿Cuál es una mejor manera de llegar al origen de esta fragmentación?

Si lees hasta aquí, ¡gracias por tu atención!

Información adicional solicitada:

Información de memoria y xfs: https://gist.github.com/christian-marie/f417cc3134544544a8d1

Error de asignación de página: https://gist.github.com/christian-marie/7bc845d2da7847534104

Seguimiento: información de rendimiento y cosas relacionadas con la compactación

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

El código de compactación parece un poco ineficiente, ¿eh? He improvisado un código para intentar replicar las compactaciones fallidas: https://gist.github.com/christian-marie/cde7e80c5edb889da541

Esto parece reproducir el problema.

Notaré también que un seguimiento de evento me dice que hay muchas reclamaciones fallidas, una y otra vez:

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

La salida de Vmstat también es preocupante. Mientras el sistema se encuentra en este estado de alta carga, las compactaciones están atravesando el techo (y fallando principalmente):

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

De hecho, hay algo mal con la recuperación / compactación.

Por el momento, estoy buscando reducir las asignaciones de alto orden al agregar soporte SG a nuestra configuración de ipoib. El problema real parece probablemente relacionado con vmscan.

Esto es interesante y hace referencia a esta pregunta: http://marc.info/?l=linux-mm&m=141607142529562&w=2

pingu
fuente
2
Diablos si !! No recibimos muchas de estas buenas preguntas. Sin embargo, veré qué podemos hacer.
Ewwhite
1
¿Puede proporcionar el resultado /proc/buddyinfoy los resultados de free -m? Las solicitudes blockdev probablemente se representan como buffers en free. Ah, y la distribución que estás usando también sería buena. Además, ¿ page allocation failureaparece algún mensaje dmesg? Si es así, proporcione el resultado más cualquier contexto relevante.
Matthew Ife
1
Además, ¿usaste una mkfs.xfslínea de comando específica ? ¿Grandes páginas habilitadas?
Ewwhite
También la salida de/proc/meminfo
Matthew Ife
Intenté deshabilitar las páginas enormes transparentes por sí mismas (configurándolas para que nunca), el fallo aún ocurrió. No probé esto junto con otras 'soluciones'.
pingu

Respuestas:

4

Pensé en poner una respuesta con mis observaciones porque hay muchos comentarios.

Basado en su salida en https://gist.github.com/christian-marie/7bc845d2da7847534104

Podemos determinar lo siguiente:

  1. El GFP_MASK para la asignación de memoria intentada puede hacer lo siguiente.
    • Puede acceder a las piscinas de emergencia (creo que esto significa acceder a los datos debajo de la marca de agua alta para una zona)
    • No use reservas de emergencia (creo que esto significa no permitir el acceso a la memoria debajo de la marca de agua mínima)
    • Asignar desde una de las zonas normales.
    • Puede intercambiar para hacer espacio.
    • Puede soltar cachés para hacer espacio.

La fragmentación de zona es la ubicación aquí:

[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

Y la utilización de la memoria en ese momento está aquí:

[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 fragmentación de cada zona es mala en la salida de falla de asignación de página. Hay muchas páginas de pedido gratis 0 con páginas de pedido mucho menor o ninguna. Un "buen" resultado será una gran cantidad de páginas gratuitas a lo largo de cada pedido, disminuyendo gradualmente su tamaño a medida que avanza el pedido. Tener 0 páginas de orden superior 5 y superiores indica fragmentación e inanición para asignaciones de orden superior.

Actualmente no veo un grado convincente de evidencia que sugiera que la fragmentación durante este período tenga algo que ver con los escondites de losas. En las estadísticas de memoria resultantes, podemos ver lo siguiente

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

No hay grandes páginas asignadas desde el espacio de usuario, y el espacio de usuario siempre reclamará memoria de orden 0. Por lo tanto, en ambas zonas hay más de 22 GiB de memoria desfragmentable.

Comportamientos que no puedo explicar

Cuando las asignaciones de alto orden fallan, tengo entendido que la compactación de memoria siempre se intenta para permitir que las regiones de asignación de memoria de alto orden tengan lugar y tengan éxito. ¿Por qué esto no sucede? Si sucede, ¿por qué no puede encontrar memoria para desfragmentar cuando hay 22 GiB de capacidad para reordenar?

Comportamientos que creo que puedo explicar

Esto necesita más investigación para comprenderlo correctamente, pero creo que la capacidad de la asignación de intercambiar / soltar automáticamente un caché de página para tener éxito probablemente no se aplique aquí porque todavía hay mucha memoria libre disponible, por lo que no se producen reclamos. Simplemente no es suficiente en las órdenes superiores.

Si bien hay mucha memoria libre y quedan pocas solicitudes de 4 pedidos en cada zona, el problema "total de memoria libre para cada pedido y deducir de la memoria libre real" da como resultado una "memoria libre" debajo de la marca de agua "min", que es lo que lleva a la falla de asignación real.

Matthew Ife
fuente
Parece extraño que una caché SLAB relativamente pequeña (hasta la memoria libre total) fragmente todas las memorias. Hubiera esperado que con todas esas páginas de desalojo gratuitas simplemente desalojara algunas y terminara. Sospecho que NUMA podría tener algo que ver con esta rareza.
pingu
¿Se está numadejecutando en este sistema?
ewwhite
@ewwhite numad no se está ejecutando, no.
pingu
@pingu Si este comportamiento es reproducible, intente habilitar el numadservicio y tome nota de las acciones en /var/log/numad.log. También es posible que necesite instalar libcgroup.
Ewwhite
@ewwhite Bien, tengo uno corriendo ahora. No estoy seguro de qué espero que haga o qué información podríamos obtener de él. ¿Qué esperas que pase?
pingu