Pomocny byłby wgląd kogoś, kto ma trochę doświadczenia w systemie Linux IO. Oto moja historia:
Niedawno pojawił się klaster sześciu Dell PowerEdge rx720xds do obsługi plików przez Ceph. Te maszyny mają 24 rdzenie na dwóch gniazdach z dwiema strefami num i 70 nieparzystymi gigabajtami pamięci. Dyski są formatowane jako rajdy na jeden dysk każdy (inaczej nie moglibyśmy znaleźć sposobu na ich bezpośrednie ujawnienie). Sieć zapewnia mellanox infiniband IP przez IB (pakiety IP zamieniane są w IB na ziemi jądra, a nie sprzętowo).
Każdy z naszych dysków SAS jest zamontowany w następujący sposób:
# 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
IO przechodzące przez te maszyny pęka z szybkością kilkuset MB / s, ale przez większość czasu jest dość bezczynne z wieloma małymi „zaczepkami”:
# 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
Problem:
Po około 48 godzinach później ciągłe strony są tak rozdrobnione, że powiększenie czterech (16 stron, 65536 bajtów) przydziałów zaczyna się nie powieść i zaczynamy upuszczać pakiety (z powodu awarii kalloc, gdy rośnie SLAB).
Tak wygląda względnie „zdrowy” serwer:
# 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
Kiedy fragmentacja staje się znacznie gorsza, system zaczyna wirować w przestrzeni jądra i wszystko po prostu się rozpada. Jedną z anomalii podczas tej awarii jest to, że xfsaild wydaje się używać dużo procesora i utknie w nieprzerwanym stanie uśpienia. Nie chcę jednak wyciągać żadnych dziwnych wniosków podczas całkowitej awarii systemu.
Obejście do tej pory.
Aby zapewnić, że alokacje te nie zawiodą, nawet przy fragmentacji, ustawiam:
vm.min_free_kbytes = 16777216
Po obejrzeniu milionów buforów blkdev_requests w pamięciach podręcznych SLAB, próbowałem zmniejszyć liczbę brudnych stron poprzez:
vm.dirty_ratio = 1
vm.dirty_background_ratio = 1
vm.min_slab_ratio = 1
vm.zone_reclaim_mode = 3
Możliwe, że jednocześnie zmieniam zbyt wiele zmiennych, ale na wypadek, gdyby inody i dentraty powodowały fragmentację, postanowiłem ograniczyć je do minimum:
vm.vfs_cache_pressure = 10000
I to chyba pomogło. Fragmentacja jest jednak wciąż wysoka, a zredukowane problemy z igłami i zębami spowodowały, że zauważyłem coś dziwnego, co prowadzi mnie ...
Moje pytanie:
Dlaczego mam tak wiele żądań blkdev_request (które są nie mniej aktywne), które po prostu znikają po upuszczeniu pamięci podręcznej?
Oto co mam na myśli:
# 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
To mówi mi, że tworzenie blkdev_request nie jest w rzeczywistości powiązane z brudnymi stronami, a ponadto, że aktywne obiekty nie są tak naprawdę aktywne? Jak można uwolnić te obiekty, jeśli w rzeczywistości nie są używane? Co tu się dzieje?
Na tle, oto co robi drop_caches:
http://lxr.free-electrons.com/source/fs/drop_caches.c
Aktualizacja:
Przekonali się, że mogą to nie być blkdev_requests, ale mogą to być wpisy xfs_buf wyświetlane pod tym „nagłówkiem”? Nie jestem pewien, jak to działa:
/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/
Nadal nie wiem, dlaczego są one usuwane przez „drop_slabs”, ani jak dowiedzieć się, co powoduje tę fragmentację.
Pytanie dodatkowe: Jaki jest lepszy sposób na uzyskanie źródła tej fragmentacji?
Jeśli czytasz tak daleko, dziękuję za uwagę!
Dodatkowe wymagane informacje:
Informacje o pamięci i xfs: https://gist.github.com/christian-marie/f417cc3134544544a8d1
Błąd przydziału strony: https://gist.github.com/christian-marie/7bc845d2da7847534104
Kontynuacja: informacje o perf i rzeczy związane z zagęszczaniem
http://ponies.io/raw/compaction.png
Kod zagęszczania wydaje się trochę nieefektywny, co? Zebrałem trochę kodu, aby spróbować zreplikować nieudane zagęszczenia: https://gist.github.com/christian-marie/cde7e80c5edb889da541
To wydaje się odtwarzać problem.
Zauważę również, że śledzenie zdarzeń mówi mi, że istnieje wiele nieudanych reklamacji, w kółko:
<...>-322 [023] .... 19509.445609: mm_vmscan_direct_reclaim_end: nr_reclaimed=1
Dotyczy również wyjścia Vmstat. Podczas gdy system znajduje się w stanie wysokiego obciążenia, zagęszczania przechodzą przez dach (i w większości nie działają):
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
Naprawdę jest coś nie tak z odzyskiwaniem / zagęszczaniem.
W tej chwili zamierzam zmniejszyć alokacje wysokich zamówień poprzez dodanie obsługi SG do naszej konfiguracji ipoib. Wydaje się, że prawdziwy problem dotyczy vmscan.
Jest to interesujące i odnosi się do tego pytania: http://marc.info/?l=linux-mm&m=141607142529562&w=2
źródło
/proc/buddyinfo
i wynikifree -m
? Żądania blockdev są prawdopodobnie reprezentowane jako bufory wfree
. Aha, a dystrybucja, której używasz, też byłaby dobra. Dodatkowo, czy masz jakieśpage allocation failure
wiadomościdmesg
? Jeśli tak, proszę podać wynik oraz odpowiedni kontekst.mkfs.xfs
wiersza poleceń? Włączone strony informacyjne?/proc/meminfo
Odpowiedzi:
Myślałem, że odpowiem swoimi spostrzeżeniami, ponieważ jest wiele komentarzy.
Na podstawie wyników uzyskanych na https://gist.github.com/christian-marie/7bc845d2da7847534104
Możemy ustalić, co następuje:
Fragmentacja strefy to lokalizacja tutaj:
Wykorzystanie pamięci w tym momencie jest tutaj:
Fragmentacja każdej strefy jest niepoprawna w wyniku niepowodzenia alokacji strony. Istnieje wiele stron z bezpłatnym zamówieniem 0, ze znacznie mniejszą liczbą stron o wyższym zamówieniu. „Dobry” wynik to obfite bezpłatne strony wzdłuż każdego zamówienia, stopniowo zmniejszające się wraz ze wzrostem kolejności. Posiadanie 0 stron wysokiego rzędu 5 i wyższych wskazuje na fragmentację i głód przydziałów wysokiego rzędu.
Obecnie nie widzę przekonujących dowodów na to, że fragmentacja w tym okresie ma cokolwiek wspólnego z buforami płyt. W wynikowych statystykach pamięci możemy zobaczyć następujące
Nie ma żadnych dużych stron przypisanych z przestrzeni użytkownika, a zatem przestrzeń użytkownika zawsze będzie żądać pamięci rzędu 0. Zatem w obu strefach jest ponad 22 GB pamięci defragmentowalnej.
Zachowania, których nie potrafię wyjaśnić
Kiedy przydziały wysokiego rzędu kończą się niepowodzeniem, rozumiem, że zawsze próbuje się zagęścić pamięć , aby umożliwić regionom przydziału pamięci wysokiego rzędu, aby odniosła sukces. Dlaczego tak się nie dzieje? Jeśli tak się stanie, dlaczego nie może znaleźć żadnej pamięci do defragmentacji, gdy 22GiB jest gotowe do zmiany kolejności?
Zachowania, które myślę, że potrafię wyjaśnić
Aby poprawnie zrozumieć, potrzeba więcej badań, ale uważam, że możliwość automatycznego zamiany / upuszczenia części pamięci podręcznej na sukces prawdopodobnie nie ma tutaj zastosowania, ponieważ wciąż jest dużo wolnej pamięci, więc nie ma możliwości odzyskania. Po prostu za mało w wyższych rzędach.
Chociaż w każdej strefie pozostało dużo wolnej pamięci i kilka żądań 4 zamówień w każdej strefie, problem „suma całej wolnej pamięci dla każdego zamówienia i odliczenia od rzeczywistej wolnej pamięci” powoduje „wolną pamięć” poniżej znaku wodnego „min”, który jest co prowadzi do faktycznego niepowodzenia alokacji.
źródło
numad
działa w tym systemie?numad
usługę i zanotuj działania w/var/log/numad.log
. Może być także konieczne zainstalowanie libcgroup.