#la #psi #linux #perfomance #monitoring
Знали ли вы что LA давным-давно уже не модно?
Теперь модно Pressure Stall Information (PSI), метрики, которые доступны начиная с 4.20 ядра.
Показывают отдельно страдания процессов по CPU/MEM/IO.
Если у вас cgroupsv2, то покажут еще данную информацию по контейнерам.
Очень понятно что это за метрики рассказано тут.
Эти метрики уже есть в новых версиях atop (строка PSI).
Если есть кратко, в каждом из файлов (/proc/pressure/[cpu|memory|io]) есть две строчки:
- some - сколько процентов времени один или больше процессов испытывали проблемы с ресурсом.
- full - сколько процентов времени все процессы в системе испытывали проблемы с ресурсом.
(Для cpu строчка full оставлена только для совместимости)
Ну то есть если у вас в файле io в строчке full написано 50 на avg300, то это означает что 150 секунд все процессы в системе ждали IO.
Есть еще параметр total: растущий счетчик в микросекундах.
Более длинно можно почитать еще и тут
Знали ли вы что LA давным-давно уже не модно?
Теперь модно Pressure Stall Information (PSI), метрики, которые доступны начиная с 4.20 ядра.
Показывают отдельно страдания процессов по CPU/MEM/IO.
Если у вас cgroupsv2, то покажут еще данную информацию по контейнерам.
Очень понятно что это за метрики рассказано тут.
Эти метрики уже есть в новых версиях atop (строка PSI).
Если есть кратко, в каждом из файлов (/proc/pressure/[cpu|memory|io]) есть две строчки:
- some - сколько процентов времени один или больше процессов испытывали проблемы с ресурсом.
- full - сколько процентов времени все процессы в системе испытывали проблемы с ресурсом.
(Для cpu строчка full оставлена только для совместимости)
Ну то есть если у вас в файле io в строчке full написано 50 на avg300, то это означает что 150 секунд все процессы в системе ждали IO.
Есть еще параметр total: растущий счетчик в микросекундах.
Более длинно можно почитать еще и тут
facebookmicrosites.github.io
Getting Started with PSI · PSI
This page describes Pressure Stall Information (PSI), how to use it, tools and components that work with PSI, and some case studies showing how PSI is used in production today for resource control in large data centers.
👍7
#dentry #linux #perfomance
Как большой размер dentry может жестко мешать работе контейнера.
Проблема в статье уже не актуальна для новых ядер, но будет полезна всем интересующимся тем, как докапываться до корня проблем.
Как большой размер dentry может жестко мешать работе контейнера.
Проблема в статье уже не актуальна для новых ядер, но будет полезна всем интересующимся тем, как докапываться до корня проблем.
Sysdig
Container isolation gone wrong | Sysdig
A detailed troubleshooting story that covers both simple and complex tales of container isolation. Read this terrific guide for insight from A-Z.
👍2
#cgroups #linux
Искал в интернете сведения про iocost и наткнулся на совершенно фееричный по своей полезности ресурс от FB.
В серии статей они рассказывают как с помощью механизмов cgroups добиваться большей утилизации на сервере не вредя основной нагрузке на сервере.
В цикле затрагиваются CPU/MEM/IO.
Советую прочитать всем кто интересуются перфоманс инжинирингом.
Искал в интернете сведения про iocost и наткнулся на совершенно фееричный по своей полезности ресурс от FB.
В серии статей они рассказывают как с помощью механизмов cgroups добиваться большей утилизации на сервере не вредя основной нагрузке на сервере.
В цикле затрагиваются CPU/MEM/IO.
Советую прочитать всем кто интересуются перфоманс инжинирингом.
facebookmicrosites.github.io
Resource Control Demo Overview | Resource Control Demo
We all want our workloads to utilize our machines as much as possible.
👍2
#CFS #linux
Читал тут главу System Performance посвященную процессору и наткнулся на полиси шедулинга.
Ну вы все их знаете:
- RR
- FIFO
- NORMAL
- BATCH
- IDLE
- DEADLINE
Меня заинтересовало описание BATCH (говорят что это тоже самое что и NORMAL (OTHER), но всегда считается что это CPU-bound задача)
Но что это означает для шедулера CFS (Completely Fair Scheduler)?
Хоть и в 6 ядре говорят появился новый шедулер, разобраться до конца как работает CFS мне все же было интересно. Поэтому я зарылся в инет на несколько часов.
Для себя я вынес следующее:
- Каждый процессор имеет свою очередь шедулинга.
- выбирается процесс с меньшим vruntime
- vruntime - это виртуальное время проведенное на процессоре
- следовательно - процессы потребляющие CPU работают реже, а процессы потребляющие IO - чаще
- Использует красно-черные деревья для шедулинга процессов
- Учитывает nice
- Если у процесса nice = 0 - vruntime не изменяется.
- Если у процесса nice < 0 - vruntime становится меньше
- Если у процесса nice > 0 - vruntime становится больше
- Есть групповой шедулинг. Это когда группе процессов может быть назначена группа, и другой группе процессов может быть назначена группа. И CFS пытается сделать так чтобы эти две группы процессов получили равное количество процессорного времени, не смотря на то что в одной группе может быть 5 процессов, а в другой 50.
Итого, чем же BATCH отличается от NORMAL (OTHER)?
В моем понимании, так как все batch процессы считаются CPU-bound по умолчанию, они сразу помещаются в правую сторону красно-черного дерева очереди процессов и соответственно вызываются реже.
В процессе изысканий наиболее полезными оказались следующие ресурсы
- Статья по CFS
- Видео про шедулинг в Linux курса SE 350
Читал тут главу System Performance посвященную процессору и наткнулся на полиси шедулинга.
Ну вы все их знаете:
- RR
- FIFO
- NORMAL
- BATCH
- IDLE
- DEADLINE
Меня заинтересовало описание BATCH (говорят что это тоже самое что и NORMAL (OTHER), но всегда считается что это CPU-bound задача)
The difference is that this policy will cause the scheduler to always assume that the thread is CPU-intensive
Но что это означает для шедулера CFS (Completely Fair Scheduler)?
Хоть и в 6 ядре говорят появился новый шедулер, разобраться до конца как работает CFS мне все же было интересно. Поэтому я зарылся в инет на несколько часов.
Для себя я вынес следующее:
- Каждый процессор имеет свою очередь шедулинга.
- выбирается процесс с меньшим vruntime
- vruntime - это виртуальное время проведенное на процессоре
- следовательно - процессы потребляющие CPU работают реже, а процессы потребляющие IO - чаще
- Использует красно-черные деревья для шедулинга процессов
- Учитывает nice
- Если у процесса nice = 0 - vruntime не изменяется.
- Если у процесса nice < 0 - vruntime становится меньше
- Если у процесса nice > 0 - vruntime становится больше
- Есть групповой шедулинг. Это когда группе процессов может быть назначена группа, и другой группе процессов может быть назначена группа. И CFS пытается сделать так чтобы эти две группы процессов получили равное количество процессорного времени, не смотря на то что в одной группе может быть 5 процессов, а в другой 50.
Итого, чем же BATCH отличается от NORMAL (OTHER)?
В моем понимании, так как все batch процессы считаются CPU-bound по умолчанию, они сразу помещаются в правую сторону красно-черного дерева очереди процессов и соответственно вызываются реже.
В процессе изысканий наиболее полезными оказались следующие ресурсы
- Статья по CFS
- Видео про шедулинг в Linux курса SE 350
👍7
#linux #mem
Как вы думаете какое максимальное количество виртуальной памяти может выделить себе процесс в Linux?
Говорят примерно до 128 TB на x86_64
https://www.kernel.org/doc/Documentation/arch/x86/x86_64/mm.rst
И 256TB на ARM64
https://www.kernel.org/doc/Documentation/arch/arm64/memory.rst
Я решил проверить :)
Вот программка с помощью которой я это проверял:
А вот что получилось:
Что в итоге?
На ARM64 памяти выделили 170TB, а обещали 256TB.
Как вы думаете какое максимальное количество виртуальной памяти может выделить себе процесс в Linux?
Говорят примерно до 128 TB на x86_64
https://www.kernel.org/doc/Documentation/arch/x86/x86_64/mm.rst
И 256TB на ARM64
https://www.kernel.org/doc/Documentation/arch/arm64/memory.rst
Я решил проверить :)
Вот программка с помощью которой я это проверял:
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
int main() {
char *chars;
size_t nbytes;
while(chars != MAP_FAILED) {
nbytes += 0x39999999; // almost 1GB
chars = mmap(
NULL,
nbytes,
PROT_READ | PROT_WRITE,
MAP_SHARED | MAP_ANONYMOUS,
-1,
0
);
munmap(chars, nbytes);
}
printf("Allocated %ld total GB\n", nbytes/1024/1024/1024);
exit(EXIT_FAILURE);
}
А вот что получилось:
5.14.0-362.18.1.el9_3.x86_64 #1 SMP PREEMPT_DYNAMIC
# free -m
total used free shared buff/cache available
Mem: 1031182 7334 1026066 82 2273 1023847
Swap: 0 0 0
# echo 0 > /proc/sys/vm/overcommit_memory - ОС смотрит на сколько памяти в системе + добавляет своп
# ./main.out
Allocated 1007 total GB
# echo 1 > /proc/sys/vm/overcommit_memory - ОС "не ограничивает" выделение памяти
# ./main.out
Allocated 130859 total GB
# echo 2 > /proc/sys/vm/overcommit_memory - ОС не дает больше чем в реальности сможет выделить
# ./main.out
Allocated 503 total GB - почему тут получилось 503GB мне не до конца ясно.
5.15.0-1034-raspi #37-Ubuntu SMP PREEMPT
# free -m
total used free shared buff/cache available
Mem: 905 198 346 3 360 616
(тут я немного модифицировал программу чтобы учесть что у меня всего 1GB оперативной памяти)
# echo 0 > /proc/sys/vm/overcommit_memory
# ./main.out
Allocated 906 total MB
# echo 1 > /proc/sys/vm/overcommit_memory
# ./main.out
Allocated 170 total TB
# echo 2 > /proc/sys/vm/overcommit_memory
root@raspberrypi-1:/home/azalio# ./main.out
Allocated 921 total MB
Что в итоге?
На ARM64 памяти выделили 170TB, а обещали 256TB.
🔥4
Azalio_tech
На ARM64 памяти выделили 170TB, а обещали 256TB.
#linux #mem #aslr
В итоге дело оказалось в ASLR и дырках в адресном пространстве.
Указание опции компилятору
Рассказали мне об этом на стековерфлоу :)
В итоге дело оказалось в ASLR и дырках в адресном пространстве.
Указание опции компилятору
-no-pie позволило выделить 255ТB виртуальной памяти. Рассказали мне об этом на стековерфлоу :)
👍4🔥1
#THP #linux #mem
Зашла в одном из рабочих чатов речь про Transparent Hugepages, которые заметно влияют на производительность систем и я пошел разбираться.
Грегг "святой" Брендан в книге System performance говорит:
Перкона проводила тест для PostgreSQL и тест показал что чуть хуже становится при включении THP.
Но в тоже время почти все дистрибутивы включают их по-умолчанию. На SO тоже задались этим вопросом и получили очевидные ответы.
На куберах у нас эта опция включена, но на некоторых нодах по запросу продукта была переведена в madvise.
А должна она быть включена или нет в кубере, видимо, без глубоких тестов так и останется неизвестным.
Зашла в одном из рабочих чатов речь про Transparent Hugepages, которые заметно влияют на производительность систем и я пошел разбираться.
Грегг "святой" Брендан в книге System performance говорит:
"Обратите внимание, что прозрачным огромным страницам традиционно сопутствовали
проблемы производительности, сдерживавшие их использование. Надеемся, что эти
проблемы были исправлены."
Перкона проводила тест для PostgreSQL и тест показал что чуть хуже становится при включении THP.
Но в тоже время почти все дистрибутивы включают их по-умолчанию. На SO тоже задались этим вопросом и получили очевидные ответы.
На куберах у нас эта опция включена, но на некоторых нодах по запросу продукта была переведена в madvise.
А должна она быть включена или нет в кубере, видимо, без глубоких тестов так и останется неизвестным.
Percona Database Performance Blog
Settling the Myth of Transparent HugePages for Databases
Transparent HugePages are reputed to cause performance degradation in database applications. Ibrar Ahmed sets out to discover if the rumors have foundation.
👍1
#perfomance #linux #haproxy
Прекрасный пост-ретроспектива о том, как искали утечку памяти в haproxy.
Прекрасный пост-ретроспектива о том, как искали утечку памяти в haproxy.
Рестарт haproxy приводил к порождению нового процесса, который в свою очередь активно аллоцировал память под свои нужды (напомню что старые не завершались). Следующий рестарт добавлял еще один процесс и так по кругу, пока критический объем памяти не активировал OOM Killer.
Linkedin
haproxy и утечка памяти
На днях диагностировал утечку памяти в кластере haproxy, в процессе исследования допустил несколько ошибок, что привело к более долгой локализации проблемы. На примере данного кейса хочу провести небольшое ретро.
👍3🔥2
😠 Агент-лимитер “слепнет” после появления новых PV? Раз и навсегда разбираемся с `mountPropagation` в Kubernetes!
Недавно писал I/O-лимитер для LVM-томов: агент читает маунты подов, чтобы вычислить
Почему так происходит
* Каждый контейнер стартует в своём *privаte* mount-namespace -> изменения на хосте туда не пролетают.
* В Kubernetes это равно
Как починить?
Параметр
* None - полная изоляция (`rprivate`), дефолт.
* HostToContainer - маунты летят *с хоста -> в контейнер* (`rslave`). Нам нужен именно он.
* Bidirectional - маунты ходят в обе стороны (`rshared`). Работает *только* в `privileged`-контейнере, иначе Pod не стартует.
Спека
Теперь каждое *новое* bind-mount событие внутри
Что происходит под капотом
1. Kubelet видит
2. CRI-shim (containerd/CRI-O) делает каталог
3. Все будущие маунты, созданные kubelet’ом на хосте, автоматически “проливаются” в контейнер.
На заметку
*
* В Kubernetes 1.10 было краткое время, когда дефолтом неожиданно стал
* Cilium тоже использует этот трюк чтобы следить за bpf мапами.
Полезные ссылки
• Документация
• CRI интерфейс
• man mount
#kubernetes #k8s #mountPropagation #linux #devops #storage
Недавно писал I/O-лимитер для LVM-томов: агент читает маунты подов, чтобы вычислить
MAJOR:MINOR для добавления в io.max, и всё ок… пока на узел не приедет новый Pod. Его маунта агент уже не видит. Перезапуск помогает, но это же костыль!Почему так происходит
* Каждый контейнер стартует в своём *privаte* mount-namespace -> изменения на хосте туда не пролетают.
* В Kubernetes это равно
mountPropagation: None.Как починить?
Параметр
mountPropagation у volumeMounts имеет 3 режима:* None - полная изоляция (`rprivate`), дефолт.
* HostToContainer - маунты летят *с хоста -> в контейнер* (`rslave`). Нам нужен именно он.
* Bidirectional - маунты ходят в обе стороны (`rshared`). Работает *только* в `privileged`-контейнере, иначе Pod не стартует.
Спека
spec:
containers:
- name: my-agent
image: my-agent-image
volumeMounts:
- name: kubelet-pods
mountPath: /var/lib/kubelet/pods
mountPropagation: HostToContainer
volumes:
- name: kubelet-pods
hostPath:
path: /var/lib/kubelet/pods
type: Directory
Теперь каждое *новое* bind-mount событие внутри
/var/lib/kubelet/pods мгновенно видно агенту - без рестартов.Что происходит под капотом
1. Kubelet видит
HostToContainer и пишет в CRI PROPAGATION_HOST_TO_CONTAINER. 2. CRI-shim (containerd/CRI-O) делает каталог
rslave. 3. Все будущие маунты, созданные kubelet’ом на хосте, автоматически “проливаются” в контейнер.
На заметку
*
Bidirectional опасен в мульти-тенант окружениях: контейнер может пролить маунты *на хост*. * В Kubernetes 1.10 было краткое время, когда дефолтом неожиданно стал
HostToContainer. Если админите древний кластер - проверьте (хотя боюсь вам уже ничего не поможет...). * Cilium тоже использует этот трюк чтобы следить за bpf мапами.
Полезные ссылки
• Документация
• CRI интерфейс
• man mount
#kubernetes #k8s #mountPropagation #linux #devops #storage
GitHub
Private mount propagation by jsafrane · Pull Request #62462 · kubernetes/kubernetes
This PR changes the default mount propagation from "rslave" (newly added in 1.10) to "private" (default in 1.9 and before). "rslave" as default...
👍12