Qualquer insight de alguém com um pouco de experiência no sistema linux IO seria útil. Aqui está a minha história:
Recentemente, criou um cluster de seis Dell PowerEdge rx720xds para servir arquivos via Ceph. Essas máquinas têm 24 núcleos em dois soquetes com duas zonas numa e 70 gigabytes ímpares de memória. Os discos são formatados como invasões de um disco cada (não poderíamos ver uma maneira de expô-los diretamente de outra forma). A rede é fornecida pelo mellanox infiniband IP over IB (os pacotes IP são transformados em IB no kernel, não em hardware).
Cada um dos nossos drives SAS é montado da seguinte forma:
# 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
O IO passando por essas máquinas explode em algumas centenas de MB / s, mas a maior parte do tempo é bastante ocioso com um monte de pequenas 'cutucadas':
# 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
O problema:
Após cerca de 48 horas depois, as páginas contíguas são tão fragmentadas que as quatro alocações de magniutde (16 páginas, 65536 bytes) começam a falhar e começamos a eliminar pacotes (devido à falha do kalloc quando um SLAB é desenvolvido).
É assim que um servidor relativamente "saudável" se parece:
# 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 a fragmentação fica consideravelmente pior, o sistema parece começar a girar no espaço do kernel e tudo simplesmente se desfaz. Uma anomalia durante essa falha é que o xfsaild parece usar muita CPU e fica preso no estado de suspensão ininterrupta. Eu não quero tirar conclusões precipitadas com estranheza durante a falha total do sistema.
Solução até o momento.
Para garantir que essas alocações não falhem, mesmo com a fragmentação, defino:
vm.min_free_kbytes = 16777216
Depois de ver milhões de blkdev_requests em caches SLAB, tentei reduzir páginas sujas por meio de:
vm.dirty_ratio = 1
vm.dirty_background_ratio = 1
vm.min_slab_ratio = 1
vm.zone_reclaim_mode = 3
Possivelmente alterando muitas variáveis de uma só vez, mas apenas no caso de inodes e dentries estarem causando fragmentação, decidi mantê-los no mínimo:
vm.vfs_cache_pressure = 10000
E isso pareceu ajudar. A fragmentação ainda é alta, e os problemas reduzidos de inode e dentry fizeram com que eu notasse algo estranho que me leva a ...
Minha pergunta:
Por que eu tenho tantos blkdev_requests (que não estão ativos), que simplesmente desaparecem quando eu deixo caches?
Eis o que quero dizer:
# 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
Isso me diz que o acúmulo de blkdev_request não é relacionado a páginas sujas e, além disso, que os objetos ativos não são realmente ativos? Como esses objetos podem ser liberados se não estiverem de fato em uso? O que está acontecendo aqui?
Para algum contexto, veja o que o drop_caches está fazendo:
link
Atualização:
Trabalhou que eles podem não ser blkdev_requests, mas podem ser entradas xfs_buf aparecendo sob esse título? Não tenho certeza de como isso funciona:
/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/
Eu ainda não sei por que eles são limpos pelo 'drop_slabs', ou como descobrir o que está causando essa fragmentação.
Pergunta bônus: qual é a melhor maneira de chegar à fonte dessa fragmentação?
Se você leu até aqui, obrigado pela sua atenção!
Informações solicitadas extra:
Informação de memória e xfs:
link
Falha na alocação de página:
link
Acompanhamento: informações relacionadas à compactação e coisas relacionadas à compactação
link
O código de compactação parece um pouco ineficiente, né? Eu montei um código para tentar replicar as compactações com falha: link
Isso parece reproduzir o problema.
Também observarei que um rastreamento de eventos informa que há várias recuperações com falha, repetidas vezes:
<...>-322 [023] .... 19509.445609: mm_vmscan_direct_reclaim_end: nr_reclaimed=1
A saída do Vmstat também é preocupante. Enquanto o sistema está nesse estado de carga alta, as compactações estão passando pelo telhado (e na maioria das vezes falhando):
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
Existe de fato algo errado com recuperação / compactação.
No momento, estou olhando para reduzir as altas alocações de pedidos, adicionando o suporte do SG à nossa configuração do ipoib. A questão real parece provável vmscan relacionado.
Isso é interessante e faz referência a essa pergunta: link