Оригинальная ссылка:Глубокое понимание серии Linux Cgroup (3): память
пройти черезПредыдущая статья, мы научились просматривать текущую информацию cgroup, как работать/sys/fs/cgroup
каталог для динамической настройки контрольных групп, а также научился устанавливать доли ЦП и квоты ЦП для управленияslice
внутри и разныеslice
Время использования ЦП между. Эта статья будет посвящена памяти и продемонстрирует, как ограничить использование памяти с помощью контрольных групп на конкретных примерах.
1. Найдите потерянную память
В прошлой статье нам рассказали, что контроллер ЦП предоставляет два метода ограничения времени использования ЦП, среди которыхCPUShares
используется для установки относительных весов,CPUQuota
Процент процессорного времени, используемый для ограничения пользователя, службы или виртуальной машины. Например: если пользователь устанавливает и CPUShares, и CPUQuota, предположим, что для CPUQuota установлено значение50%
, затем, пока загрузка ЦП пользователя не достигнет 50%, ЦП можно использовать в соответствии с настройкой CPUShares.
Что касается памяти, в CentOS 7 systemd помог нам связать память с /sys/fs/cgroup/memory.systemd
предоставляется только один параметрMemoryLimit
Чтобы управлять им, этот параметр представляет собой общий объем физической памяти, который может использовать пользователь или служба. В качестве примера возьмем предыдущего пользователя tom, его UID равен 1000, что можно установить с помощью следующей команды:
$ systemctl set-property user-1000.slice MemoryLimit=200M
используя пользователя сейчасtom
войти в систему черезstress
Команда порождает 8 дочерних процессов, и каждый процесс выделяет 256 МБ памяти:
$ stress --vm 8 --vm-bytes 256M
Как и ожидалось, использование памяти стрессовым процессом превысило предел, что должно вызватьoom-killer
, но процесс на самом деле все еще запущен, почему? Посмотрим на занятую в данный момент память:
$ cd /sys/fs/cgroup/memory/user.slice/user-1000.slice
$ cat memory.usage_in_bytes
209661952
Странно, занятой памяти меньше 200М, куда девается остальная память? Не паникуйте, помните ли вы, что использование памяти в системе Linux включает не только физическую память, но и раздел подкачки, который является подкачкой, давайте посмотрим, является ли подкачка призраком. Прямо сейчас остановите процесс стресса, подождите 30 секунд и наблюдайте за занятостью пространства подкачки:
$ free -h
total used free shared buff/cache available
Mem: 3.7G 180M 3.2G 8.9M 318M 3.3G
Swap: 3.9G 512K 3.9G
Повторно запустите стресс-процесс:
$ stress --vm 8 --vm-bytes 256M
Проверьте использование памяти:
$ cat memory.usage_in_bytes
209637376
Установлено, что использование памяти находится всего в пределах 200M. Посмотрите на использование пространства подкачки:
$ free
total used free shared buff/cache available
Mem: 3880876 407464 3145260 9164 328152 3220164
Swap: 4063228 2031360 2031868
По сравнению с тем, что было сейчас, более2031360-512=2030848k
, теперь в основном очевидно, что когда использование процесса достигает предела, ядро попытается переместить данные из физической памяти в пространство подкачки, чтобы выделение памяти прошло успешно. Мы можем точно рассчитать общий объем физической памяти + пространство подкачки, используемое пользователем tom.Во-первых, нам нужно отдельно проверить использование физической памяти и пространства подкачки пользователем tom:
$ egrep "swap|rss" memory.stat
rss 209637376
rss_huge 0
swap 1938804736
total_rss 209637376
total_rss_huge 0
total_swap 1938804736
Вы можете видеть, что использование физической памяти209637376
байт, использование пространства подкачки1938804736
байт, всего(209637376+1938804736)/1024/1024=2048
М. Общий объем памяти, необходимый стресс-процессу, равен256*8=2048
м, оба равны.
В этот момент, если вы будете проверять каждые несколько секундmemory.failcnt
файл, вы обнаружите, что значение в этом файле увеличивается:
$ cat memory.failcnt
59390293
Из вышеприведенных результатов видно, что при нехватке физической памяти число в memory.failcnt будет увеличено на 1, но процесс в это время не обязательно будет убит, ядро попытается переместить данные в физическую память в середину пространства подкачки.
2. Закрыть своп
Чтобы лучше наблюдать за контролем памяти со стороны cgroup, мы можем использовать пользователя tom, чтобы не использовать пространство подкачки.Для этого есть несколько способов:
-
будет
memory.swappiness
Значение файла изменено на 0:$ echo 0 > /sys/fs/cgroup/memory/user.slice/user-1000.slice/memory.swappiness
После завершения этой настройки текущая контрольная группа не будет использовать пространство подкачки, даже если система включила пространство подкачки.
-
Закройте пространство Swap System непосредственно:
$ swapoff -a
Если вы хотите сделать его постоянным, также закомментируйте
/etc/fstab
обмен в файле.
Первый метод, приведенный выше, проблематичен, если вы не хотите закрывать пространство подкачки системы, но также хотите, чтобы он не использовал пространство подкачки:
- Вы можете изменить его только тогда, когда пользователь tom вошел в систему.
memory.swappiness
файл, потому что если пользователь tom не войдет в систему, текущая контрольная группа исчезнет. - даже если вы измените
memory.swappiness
Значение файла также будет недействительным после повторного входа в систему.
Если мы решим эту проблему в соответствии с традиционным мышлением, это может быть очень сложно, мы можем найти другой путь и начать с PAM.
Linux PAM(Pluggable Authentication Modules) представляет собой инфраструктуру аутентификации пользователей на системном уровне, PAM разделяет методы разработки программ и методы аутентификации, а программа вызывает дополнительный модуль «аутентификации» для завершения своей работы во время выполнения. Локальный системный администратор настраивает, какие модули аутентификации использовать, где/etc/pam.d/
Каталог специально используется для хранения конфигурации PAM, которая используется для установки независимых методов аутентификации для определенных приложений. Например, когда пользователь входит в систему через ssh, он загружает/etc/pam.d/sshd
стратегия внутри.
от/etc/pam.d/sshd
Для начала мы можем начать с создания сценария оболочки:
$ cat /usr/local/bin/tom-noswap.sh
#!/bin/bash
if [ $PAM_USER == 'tom' ]
then
echo 0 > /sys/fs/cgroup/memory/user.slice/user-1000.slice/memory.swappiness
fi
затем в/etc/pam.d/sshd
вызвать скрипт через pam_exec в/etc/pam.d/sshd
В конце добавьте строку следующего содержания:
$ session optional pam_exec.so seteuid /usr/local/bin/tom-noswap.sh
Теперь войдите в систему с пользователем tom, и вы обнаружите, чтоmemory.swappiness
значение становится 0.
Здесь есть предпосылка, на которую следует обратить внимание: существует по крайней мере одна сессия входа в систему для пользователя tom, и
systemctl set-property user-1000.slice MemoryLimit=200M
Команда устанавливает лимит,/sys/fs/cgroup/memory/user.slice/user-1000.slice
каталог существует. Поэтому для всех вышеперечисленных операций обязательно сохраните хотя бы один сеанс входа пользователя tom.
3. Контролируйте использование памяти
После закрытия свопа мы можем строго контролировать использование памяти процессом. Все еще используя пример, упомянутый в начале, войдите в систему как пользователь tom и сначала выполните следующую команду в первом окне оболочки:
$ journalctl -f
Откройте второе окно оболочки (по-прежнему пользователь tom) и создайте 8 дочерних процессов с помощью команды stress, каждому из которых выделено 256 МБ памяти:
$ stress --vm 8 --vm-bytes 256M
stress: info: [30150] dispatching hogs: 0 cpu, 0 io, 8 vm, 0 hdd
stress: FAIL: [30150] (415) <-- worker 30152 got signal 9
stress: WARN: [30150] (417) stress: FAIL: [30150] (415) <-- worker 30151 got signal 9
stress: WARN: [30150] (417) now reaping child worker processes
stress: FAIL: [30150] (415) <-- worker 30154 got signal 9
stress: WARN: [30150] (417) now reaping child worker processes
stress: FAIL: [30150] (415) <-- worker 30157 got signal 9
stress: WARN: [30150] (417) now reaping child worker processes
stress: FAIL: [30150] (415) <-- worker 30158 got signal 9
stress: WARN: [30150] (417) now reaping child worker processes
stress: FAIL: [30150] (451) failed run completed in 0s
Теперь вы можете видеть, что стресс-процесс быстро убит, и обратно в первое окно оболочки будет выведена следующая информация:
Видно, что лимит памяти cgroup сработал, использование памяти стресс-процессом превышает лимит, что приводит к срабатыванию oom-killer и уничтожению процесса.
4. Дополнительная документация
Добавьте небольшой эпизод, если вы хотите получить дополнительную документацию о CGroups, вы можете установить его через yumkernel-doc
Мешок. После завершения установки вы можете войти/usr/share/docs
подкаталоги, см. подробную документацию для каждого контроллера cgroup.
$ cd /usr/share/doc/kernel-doc-3.10.0/Documentation/cgroups
$ ll
总用量 172
4 -r--r--r-- 1 root root 918 6月 14 02:29 00-INDEX
16 -r--r--r-- 1 root root 16355 6月 14 02:29 blkio-controller.txt
28 -r--r--r-- 1 root root 27027 6月 14 02:29 cgroups.txt
4 -r--r--r-- 1 root root 1972 6月 14 02:29 cpuacct.txt
40 -r--r--r-- 1 root root 37225 6月 14 02:29 cpusets.txt
8 -r--r--r-- 1 root root 4370 6月 14 02:29 devices.txt
8 -r--r--r-- 1 root root 4908 6月 14 02:29 freezer-subsystem.txt
4 -r--r--r-- 1 root root 1714 6月 14 02:29 hugetlb.txt
16 -r--r--r-- 1 root root 14124 6月 14 02:29 memcg_test.txt
36 -r--r--r-- 1 root root 36415 6月 14 02:29 memory.txt
4 -r--r--r-- 1 root root 1267 6月 14 02:29 net_cls.txt
4 -r--r--r-- 1 root root 2513 6月 14 02:29 net_prio.txt
В следующей статье мы обсудим, как использовать контрольные группы для ограничения ввода-вывода, так что следите за обновлениями~