Романо Гущин (программист из Facebook) отправил в список рассылки разработчиков ядра Linux набор патчей для приложения распределения памяти драйвера slab (контроллера памяти) .
Новый драйвер примечателен тем, что учет блоков памяти перенесен с уровня страниц памяти на уровень объектов ядра, что позволяет совместно использовать страницы блоков памяти различными группами c, вместо выделения отдельных кэшей блоков памяти для каждой группы c.
Роман обнаружил то, что он назвал «очень серьезным недостатком» в существующем контроллере памяти slab, который в наши дни приводит к низкому использованию cgroups.
«Настоящая причина, по которой существующий дизайн приводит к низкому использованию slab, проста: страницы slab используются исключительно пулом памяти.
Если cgroup делает только несколько распределений определенного размера, или если после удаления cgroup осталось несколько активных объектов, или cgroup содержит однопоточное приложение, которое почти не выделяет какие-либо объекты ядра, но каждый раз новый ЦП: во всех этих случаях результирующая загрузка плиты очень низка.
Если учет kmem отключен, ядро может использовать свободное пространство на страницах slab для других распределений. «
Предложенный Романо Гущином в прошлом году контроллер памяти Slab оказался весьма перспективным, поскольку позволяет повысить эффективность использования памяти Slab, уменьшить объем памяти, используемой для Slab, на 30-45% и значительно снизить общее потребление памяти ядром.
Кроме того, внедренные патчи показали , что Facebook уже использует этот код в производственной среде на своих серверах и экономит около 650-700 МБ и более ресурсов для фронтенд-серверов , кэширования баз данных и DNS-серверов, а также получает другие преимущества.
Сокращение количества неподвижных блоков также положительно влияет на фрагментацию памяти. Новый контроллер памяти значительно упрощает код учета блоков и устраняет необходимость в сложных алгоритмах динамического создания и удаления кэшей блоков для каждой группы c.
Все cgroups для памяти в новой реализации используют общий набор кэшей slab, и срок жизни кэшей slab больше не привязан к продолжительности жизни ограничений памяти, установленных через cgroup.
Реализованный в новом контроллере slab более точный учет ресурсов должен теоретически больше нагружать CPU, но на практике различия оказались незначительными.
В частности, новый контроллер нагрузки использовался в течение нескольких месяцев на работающих серверах Facebook, обрабатывающих различные типы нагрузок, и до сих пор существенных регрессий не обнаружено.
Патч содержит пару полунезависимых частей, которые также могут найти свое применение вне контроллера памяти slab:
- API загрузки подстраницы, который можно использовать в будущем для подсчета других объектов, размер которых не соответствует размеру страницы, например выделения percpu
- API mem_cgroup_ptr, в котором подсчитываются указатели на memcg, можно повторно использовать для эффективного повторного родительства других объектов, например кэша страниц.
Одновременно с этим наблюдается значительное снижение потребления памяти : на некоторых хостах удалось сэкономить до 1 ГБ памяти, но этот показатель во многом зависит от характера нагрузки, общего объема ОЗУ, объема ЦП и особенностей работы с памятью.
Вместо создания отдельного набора kmem_caches для каждой контрольной группы памяти используются два глобальных набора: корневой набор для неучтенных и назначений контрольной группы корневой группы, а второй набор для всех остальных назначений. Это позволяет упростить управление временем жизни отдельных kmem_cache.
Наконец, если вас интересует информация о новом наборе из 19 патчей, вы можете найти её в списке рассылки ядра.