связь между container_memory_working_set_bytes и process_resident_memory_bytes и total_rss

Я хочу понять отношения

container_memory_working_set_bytes vs process_resident_memory_bytes vs total_rss (container_memory_rss) + file_mapped, чтобы лучше оснащенная система для предупреждения о возможности OOM.

введите описание изображения здесь

Это кажется противоречащим моему пониманию (что меня сейчас озадачивает), учитывая, если в контейнере / модуле выполняется один процесс, выполняющий скомпилированную программу, написанную на Go.

Почему разница между container_memory_working_set_bytes такая большая (почти в 10 раз) по сравнению с process_resident_memory_bytes

Также отношения между container_memory_working_set_bytes и container_memory_rss + file_mapped здесь странные, чего я не ожидал, прочитав здесь

Общий объем анонимной кэш-памяти и кеш-памяти подкачки (включая прозрачные огромные страницы), равен значению total_rss из файла memory.status. Это не следует путать с истинным размером резидентного набора или объемом физической памяти, используемой контрольной группой. rss + file_mapped даст вам размер резидентного набора cgroup. Он не включает память, которая выгружена. Он действительно включает память из разделяемых библиотек, если страницы из этих библиотек действительно находятся в памяти. Он включает всю стековую и кучную память.

Итак, cgroup общий размер резидентного набора равен rss + file_mapped, почему это значение меньше container_working_set_bytes для контейнера, который работает в данной контрольной группе

Что заставляет меня чувствовать что-то с этой статистикой, что я не прав.

Ниже приведены PROMQL, использованные для построения приведенного выше графика.

  • process_resident_memory_bytes {контейнер = sftp-загрузчик}
  • container_memory_working_set_bytes {container = sftp-downloader}
  • go_memstats_heap_alloc_bytes {контейнер = sftp-downloader}
  • container_memory_mapped_file {container = sftp-downloader} + container_memory_rss {container = sftp-downloader}

person Noobie    schedule 07.07.2021    source источник
comment
как насчет go_memstats_heap_inuse_bytes? В любом случае container_memory_working_set_bytes более надежная метрика.   -  person suiwenfeng    schedule 19.07.2021
comment
Согласен, но люди имеют в виду следить за container_memory_rss и working_set как для OOM kill. И подчеркивание, думаю, я намерен понять отношения rss vs working_set   -  person Noobie    schedule 19.07.2021
comment
К вашему сведению, medium.com/@eng.mohamed.m.saeed/   -  person suiwenfeng    schedule 20.07.2021
comment
Видно, что это бесполезно с точки зрения того, какой вопрос я ищу   -  person Noobie    schedule 20.07.2021


Ответы (1)


Не совсем ответ, но все же два разных пункта.

Помогает ли это разобраться в диаграмме?

Здесь, на моем $ dayjob, мы столкнулись с различными проблемами, связанными с тем, как различные инструменты, внешние по отношению к среде выполнения Go, подсчитывают и отображают использование памяти процессом, выполняющим программу, написанную на Go.
В сочетании с Фактически, сборщик мусора Go в Linux фактически не передает освобожденные страницы памяти ядру, а просто madvise(2) то, что такие страницы являются MADV_FREE, цикл GC, который освободил довольно большой объем памяти, не приводит к какому-либо заметному изменению показаний RSS процесса, принимаемых внешними инструментами (обычно cgroups статистика).

Следовательно, мы экспортируем наши собственные метрики, полученные путем периодического вызова runtime.ReadMemStatsruntime/debug.ReadGCStats) в любом основная служба написана на Go - с помощью простого пакета, написанного специально для этого. Эти показания отражают истинное представление среды выполнения Go о памяти, находящейся под ее контролем.

Между прочим, поле NextGC статистики памяти очень полезно для просмотра, если у вас установлены ограничения памяти для ваших контейнеров, потому что как только это чтение достигает или превышает ваш предел памяти, процесс в контейнере наверняка обречен на то, чтобы в конечном итоге быть сбитым oom_killer.

person kostix    schedule 07.07.2021
comment
Основываясь на этой статье, я подумал, что container_memory_rss + mapped_file будет истинным RSS для cgroup, который, как я предполагал, выше, чем container_memory_working_set_bytes, но на самом деле это не так. - person Noobie; 08.07.2021
comment
Также, если я прав, golang 1.16 откажется от поддержки madvice. - person Noobie; 16.07.2021
comment
@Noobie, нет, он использует другой флаг с madvise(2): MADV_DONTNEED вместо MADV_FREE - по сути возврат к поведению, введенному в Go 1.12. К сожалению, на странице руководства не совсем ясно, что происходит с наблюдаемым чтением RSS процесса, который пометил страницу с помощью madvise(MADV_DONTNEED). - person kostix; 16.07.2021
comment
Если я читаю это правильно, в нем говорится об этом On Linux, the runtime now defaults to releasing memory to the operating system promptly (using MADV_DONTNEED), rather than lazily when the operating system is under memory pressure (using MADV_FREE). Это означает, что статистика памяти на уровне процессов, такая как RSS, будет более точно отражать объем физической памяти, используемой процессами Go и The resident set size (RSS) of the calling process will be immediately reduced, однако. - person Noobie; 16.07.2021