Czy Committed_AS w / proc / meminfo naprawdę jest poprawną liczbą dla przydzielonej pamięci wirtualnej w systemie Linux? Jest to mniej niż MemTotal-MemAvailable tutaj

0

Zbieram liczby do monitorowania serwerów HPC i debatuję nad zasadami wydawania pamięci (nadmiernie lub nie). Chciałem pokazać użytkownikom liczbę o ile pamięci wirtualnej zażądali ich procesy (cała maszyna) w porównaniu do tego, ile faktycznie zostało wykorzystane.

Myślałem, że uzyskam interesujące wartości z / proc / meminfo przy użyciu pól MemTotal, MemAvailable i Committed_AS. Ten ostatni ma pokazać, ile pamięci zostało zajęte przez jądro, a najgorszy przypadek, ile pamięci naprawdę byłoby potrzebne do wykonania uruchomionych zadań.

Ale Committed_AS jest oczywiście za mały. Jest mniejszy niż obecnie używana pamięć! Obserwuj dwa przykładowe systemy. Jeden serwer administracyjny:

# cat /proc/meminfo 
MemTotal:       16322624 kB
MemFree:          536520 kB
MemAvailable:   13853216 kB
Buffers:             156 kB
Cached:          9824132 kB
SwapCached:            0 kB
Active:          4854772 kB
Inactive:        5386896 kB
Active(anon):      33468 kB
Inactive(anon):   412616 kB
Active(file):    4821304 kB
Inactive(file):  4974280 kB
Unevictable:       10948 kB
Mlocked:           10948 kB
SwapTotal:      16777212 kB
SwapFree:       16777212 kB
Dirty:               884 kB
Writeback:             0 kB
AnonPages:        428460 kB
Mapped:            53236 kB
Shmem:             26336 kB
Slab:            4144888 kB
SReclaimable:    3863416 kB
SUnreclaim:       281472 kB
KernelStack:       12208 kB
PageTables:        38068 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:    24938524 kB
Committed_AS:    1488188 kB
VmallocTotal:   34359738367 kB
VmallocUsed:      317176 kB
VmallocChunk:   34358947836 kB
HardwareCorrupted:     0 kB
AnonHugePages:     90112 kB
CmaTotal:              0 kB
CmaFree:               0 kB
HugePages_Total:       0
HugePages_Free:        0
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB
DirectMap4k:      144924 kB
DirectMap2M:     4988928 kB
DirectMap1G:    13631488 kB

Jest to w przybliżeniu 1,5 G popełnione, a 2,5 G jest używane bez pamięci podręcznej. Węzeł obliczeniowy:

ssh node390 cat /proc/meminfo
MemTotal:       264044768 kB
MemFree:        208603740 kB
MemAvailable:   215043512 kB
Buffers:           15500 kB
Cached:           756664 kB
SwapCached:            0 kB
Active:         44890644 kB
Inactive:         734820 kB
Active(anon):   44853608 kB
Inactive(anon):   645100 kB
Active(file):      37036 kB
Inactive(file):    89720 kB
Unevictable:           0 kB
Mlocked:               0 kB
SwapTotal:      134216700 kB
SwapFree:       134216700 kB
Dirty:                 0 kB
Writeback:           140 kB
AnonPages:      44918876 kB
Mapped:            52664 kB
Shmem:            645408 kB
Slab:            7837028 kB
SReclaimable:    7147872 kB
SUnreclaim:       689156 kB
KernelStack:        8192 kB
PageTables:        91528 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:    345452512 kB
Committed_AS:   46393904 kB
VmallocTotal:   34359738367 kB
VmallocUsed:      797140 kB
VmallocChunk:   34224733184 kB
HardwareCorrupted:     0 kB
AnonHugePages:  41498624 kB
CmaTotal:              0 kB
CmaFree:               0 kB
HugePages_Total:       0
HugePages_Free:        0
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB
DirectMap4k:      312640 kB
DirectMap2M:     7966720 kB
DirectMap1G:    262144000 kB

Jest to około 47G użytych vs. 44G zaangażowanych. Omawiany system to klaster CentOS 7:

uname-a
Linux adm1 3.10.0-862.14.4.el7.x86_64 #1 SMP Wed Sep 26 15:12:11 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux

Na moim pulpicie Linuksa za pomocą jądra wanilii widzę więcej „rozsądnych” liczb przy zatwierdzonym 32G w porównaniu z 15,5G. Na serwerze Debian widzę 0,4G w użyciu vs. 1,5G zatwierdzone.

Czy ktoś może mi to wyjaśnić? Jak uzyskać prawidłowy numer dla zatwierdzonej pamięci? Czy to błąd w jądrze CentOS / RHEL, który należy zgłosić?

Zaktualizuj, dodając więcej danych i porównanie systemów

Lista pamięci używanej / zatwierdzonej dla różnych systemów, do których mogłem uzyskać dostęp, z notatką o rodzaju obciążenia:

  • SLES 11.4 (jądro 3.0.101-108.71-domyślne)
    • 17.6G / 17,4G , interaktywny HPC dla wielu użytkowników (np. MATLAB, GIS)
  • CentOS 7.4 / 7.5 (jądro 3.10.0-862.11.6.el7 lub 3.10.0-862.14.4.el7)
    • 1.7G / 1.3G , serwer administracyjny, klaster mgmt, DHCP, TFTP, rsyslog,…
    • 8.6G / 1.7G , system wsadowy SLURM, 7.2G RSS dla samego slurmdbd
    • 5.1G / 0.6G , serwer NFS (400 klientów)
    • 26,8G / 32,6G, 16-rdzeniowy węzeł HPC załadowany 328 (trzeba porozmawiać z użytkownikiem) procesami GNU R
    • 6,5G / 8,1G, 16-rdzeniowy węzeł HPC z 16 procesami MPI
  • Ubuntu 16.04 (jądro 4.15.0-33-generic)
    • 1.3G / 2.2G, 6-rdzeniowy węzeł HPC, 6-wątkowa aplikacja naukowa (1.1G RSS)
    • 19,9G / 20,3G, 6-rdzeniowy węzeł HPC, 6-wątkowa aplikacja naukowa (19G RSS)
    • 1.0G / 4.4G, 6-rdzeniowy węzeł logowania z serwerem metadanych / mgmt BeeGFS
  • Ubuntu 14.04 (jądro 3.13.0-161-ogólne)
    • 0,7G / 0,3G , maszyna wirtualna serwera HTTP
  • Kompilacja niestandardowa (jądro wanilii 4.4.163)
    • 0,7G / 0,04G , głównie bezczynny serwer Subversion
  • Kompilacja niestandardowa (jądro wanilii 4.14.30)
    • 14,2G / 31,4G, długo działający pulpit
  • Alpine (jądro 4.4.68-0-grsec)
    • 36,8M / 16,4M , niektóre serwery (sieciowe)
  • Ubuntu 12.04 (jądro 3.2.0-89-generic)
    • 1.0G / 7.1G, jakiś serwer
  • Ubuntu 16.04 (jądro 4.4.0-112-ogólne)
    • 0,9G / 1,9G, jakiś serwer
  • Debian 4.0 (jądro 2.6.18-6-686, 32-bitowy x86, oczywiście)
    • 1.0G / 0.8G , jakiś niezawodny serwer
  • Debian 9.5 (jądro 4.9.0-6)
    • 0.4G / 1.5G, różne usługi sieciowe, oczywiście lekkie obciążenie
  • Debian 9.6 (jądro 4.9.0-8-amd64)
    • 10,9G / 17,7G, komputer stacjonarny
  • Ubuntu 13.10 (jądro 3.11.0-26-generic)
    • 3.2G / 5.4G, stary pulpit
  • Ubuntu 18.04 (jądro 4.15.0-38-generic)
    • 6,4 G / 18,3 G, komputer stacjonarny

NIEZastosowanie dla SLES i CentOS raczej duże… 0,5G do 1G nie jest rzadkie, więcej, jeśli nie opróżnianie pamięci podręcznych od czasu do czasu. Ale nie wystarczy, aby wyjaśnić brakującą pamięć w Committed_AS. Maszyny Ubuntu zazwyczaj mają mniej niż 100 mln SUnreclaim. Z wyjątkiem wersji 14.04, ta ma małe Committed_AS i 0,4G SUnreclaim. Uporządkowanie jądra jest trudne, ponieważ jądro 3.10 z CentOS ma wiele funkcji jądra 4.x przeniesionego z powrotem. Ale wydaje się, że istnieje linia między 4,4 a 4,9, która wpłynęła na dziwnie niskie wartości Committed_AS. Dodane serwery od niektórych moich rówieśników sugerują, że Committed_AS dostarcza również dziwne liczby dla starszych jąder. Czy zostało to zepsute i naprawione wiele razy?

Czy ludzie mogą to potwierdzić? Czy jest to po prostu błędne / bardzo niedokładne zachowanie jądra przy określaniu wartości w / proc / meminfo, czy też istnieje historia błędów (poprawek)?

Niektóre wpisy na liście są naprawdę dziwne. Posiadanie jednego procesu slurmdbd z czterokrotnym kanałem RSS Committed_AS nie może być poprawne. Kusi mnie, aby przetestować jądro wanilii na tych systemach z takim samym obciążeniem, ale nie mogę wycofać z produkcji najbardziej interesujących maszyn dla takich gier.

Wydaje mi się, że odpowiedź na moje pytanie jest wskaźnikiem poprawki w historii zatwierdzeń jądra, która ponownie umożliwiła dobre oszacowania w Committed_AS. W przeciwnym razie proszę, oświeć mnie ;-)

drhpc
źródło
Niedawno zredagowałem Pytanie z kilkoma dodatkowymi danymi (w dwóch krokach). Obraz pozostawia mnie nieco potwierdzoną w moim przekonaniu, że coś jest nie tak z oszacowaniem Committed_AS w niektórych zakresach wersji jądra.
drhpc

Odpowiedzi:

0

Te pola nie podlegają znacznej presji pamięci. Paging ( SwapFree) również nie jest . Drugie pudełko to ~ 47 GB, z łącznej pojemności 250 GB. 200 GB to dużo do zabawy.

W praktyce zwiększaj rozmiar obciążenia aż do wystąpienia jednego z następujących zdarzeń:

  • Czas odpowiedzi użytkownika (aplikacji) ulega pogorszeniu
  • Wskaźnik stronicowania jest wyższy, niż się czujesz
  • Zabójca OOM morduje niektóre procesy

Relacje między licznikami pamięci są nieintuicyjne, różnią się znacznie między obciążeniami i prawdopodobnie są naprawdę zrozumiałe dla programistów jądra. Nie przejmuj się tym zbytnio, skup się na pomiarze oczywistej presji pamięci.


Inne opisy Comitted_AS na liście linux-mm jakiś czas temu podkreślają, że jest to oszacowanie :

Committed_AS: An estimate of how much RAM you would need to make a
              99.99% guarantee that there never is OOM (out of memory)
              for this workload. Normally the kernel will overcommit
              memory. That means, say you do a 1GB malloc, nothing
              happens, really. Only when you start USING that malloc
              memory you will get real memory on demand, and just as
              much as you use. So you sort of take a mortgage and hope
              the bank doesn't go bust. Other cases might include when
              you mmap a file that's shared only when you write to it
              and you get a private copy of that data. While it normally
              is shared between processes. The Committed_AS is a
              guesstimate of how much RAM/swap you would need
              worst-case.
John Mahowald
źródło
Nie chodzi o kłopoty z maszynami. Służy to do monitorowania wykorzystania zasobów naukowych zadań obliczeniowych zajmujących cały węzeł (stąd nie ma do czynienia z jednym procesem). Wzorzec użycia różni się nieco od typowego serwera. Ponieważ pamięć jest rzeczywiście przeznaczona do wykorzystania przez zadania użytkownika, może być normalne, że zadanie żąda 300G lub więcej, a następnie zaczyna wypełniać je danymi. Chcę móc powiedzieć użytkownikom, że zbyt dużo przydzielili, zanim rozpocznie się zabijanie OOM, lub powiedzieć, że mogą przekroczyć taki limit podczas skalowania rozmiaru problemu.
drhpc
O tym, że Committed_AS jest oszacowaniem: nie oczekuję, że będzie dokładny. To może być wyłączone z pewnym marginesem. Ale to, że może to być około połowa zużytej pamięci, której nie można odzyskać, co oczywiście jest błędne, doprowadziło mnie do założenia, że ​​coś mi brakuje. Masz jakiś pomysł oprócz czytania kodu źródłowego jądra i próby uzyskania odpowiedzi na temat LKML?
drhpc
Zależny od obciążenia, dodaj do pytania, czy zestaw danych jest plikiem, pamięcią współużytkowaną (wiele systemów DBMS korzysta z buforów pamięci współużytkowanej), prywatnymi stronami, jeśli używane są ogromne strony ... Możesz odczytać lub zmapować pamięć o rozmiarze TB plik na takim polu, a tworzenie kopii zapasowej pliku raczej nie zajmie dużo pamięci. Ale jeśli włożycie 1 TB na prywatne strony, przejdzie do OOM.
John Mahowald
O to mi chodzi: chcę wiedzieć, czy np. Mapowania dużych plików są liczone w Committed_AS (myślę, że powinny). Zobacz moją aktualizację pytania dotyczącą większej liczby przykładów serwerów i niektórych wskazań obciążenia.
drhpc
Dlaczego mapowania plików miałyby się liczyć z zatwierdzonymi? Opróżnij dysk i zwolnij pamięć, podobnie jak pamięć podręczna systemu plików. Możesz przeanalizować mapy / proc / * / *, aby uzyskać szczegółowe informacje, ale rzetelne rozliczenie pamięci współdzielonej nie jest trywialne. W praktyce migruj użytkowników do mniejszych węzłów, aż wskaźnik „wolny” zbliży się do zera.
John Mahowald