Управление ресурсами СУБД

Ресурсные группы перекладывают разграничение ресурсов на ядро ОС Linux с его механизмом cgroups. По факту, SQL-команды управления ресурсными группами являются обертками над виртуальной файловой системой /sys/fs/cgroup хостов кластера ADB. Из всех возможных ресурсов ADB умеет управлять через ресурсные группы только памятью и процессором с помощью подкаталогов cgroups: memory, cpu и cpuset. При этом ресурсы процессора можно распределять как по полосе загрузки в процентах (cpu), так и по ядрам между различными группами (cpuset).

Логика управления ресурсами напоминает конструкцию из ящиков, вложенных друг в друга (Рис.7.).

../_images/intro_resources_logic.png

Рис. 7. Логика управления ресурсами

Управления памятью

Управление памятью делится по уровням разграничения.

Первый уровень разграничения ресурсов памяти определяется параметром gp_resource_group_memory_limit. Параметр указывает ядру ОС, сколько процентов памяти на каждом хосте принадлежит запущенным процессам ADB. Указанная память делится поровну между всеми сегментами на хосте. На рисунке в блоке “Segment Host Memory” показана вся память хоста, где зеленым отмечена память под ADB, поровну разделенная между четырьмя сегментами.

Important

При установке значения параметра важно оставить память для самой ОС. При этом процессы ADB не могут получить больше памяти, чем задано. Так же никакие другие внешние процессы не имеют возможности забрать память из зарезервированной для ADB

Следующий уровень вложенности – память, выделенная отдельному сегменту. В “ящик” памяти блока “Segment N” на рисунке вкладываются “ящики” поменьше, каждый из которых является отдельной ресурсной группой. На картинке приведено три ресурсные группы – admin_group, default_group и rg_sample.

Important

Процент памяти ресурсной группы задается параметром memory_limit, который всегда меньше или равен 100%. Сумма memory_limit по всем ресурсным группам так же не должна превышать 100% (в ином случае ADB выдает ошибку)

Параметр memory_limit гарантирует, что ресурсная группа получает свой процент памяти. В случае если сумма параметров memory_limit по всем ресурсным группам менее 100% (т.е. в наличии имеется свободная память), то в момент выполнения тяжелых запросов любая ресурсная группа может позаимствовать данную свободную память.

В примере на картинке ресурсной группе rg_sample выделено 60% памяти от доступной сегменту, у которого 25% памяти (так как память делится поровну между сегментами) от gp_resource_group_memory_limit, составляющей 80% от всей памяти хоста (5 равных секций в блоке “Segment Host Memory”).

Для предотвращения активной утилизации памяти тяжелыми запросами можно указать параметр memory_spill_ratio, который не позволяет запросу использовать более указанного процента памяти от доступного ресурсной группе. В результате, если планировщик видит, что запрос должен потребить более memory_spill_ratio процентов памяти в ресурсной группе, то его данные сбрасываются на диск. При этом статистика должна быть актуальной во избежание ошибки планировщика (иначе запрос отменяется из-за нехватки памяти). Интересная особенность в том, что memory_spill_ratio можно менять внутри сессии.

Управление ЦПУ

Существует два взаимодополняющих друг друга сценария управления ресурсами ЦПУ через ресурсные группы: по ядрам или по полосе пропускания.

Если обрабатываются долгие тяжелые запросы в ресурсной группе малым количеством одновременных потоков, а в других ресурсных группах выполняется много более легковесных запросов, то на ядрах процессора, обслуживающих тяжелые запросы, происходят частые переключения контекста. Это сильно замедляет производительность и для такой ресурсной группы можно зарезервировать определенные ядра ЦПУ с помощью cpuset. В результате только данная ресурсная группа использует указанные ядра (их номера должны присутствовать на всех хостах). Для остальных ресурсных групп данные ядра недоступны даже в случае их простаивания – поэтому следует резервировать ядра только в крайних случаях и в минимальном количестве. Так же следует понимать, что планировщик ОС может использовать ядра и для других программ, а не только для СУБД ADB.

Возможно выделять полосу загрузки ЦПУ. Существует параметр gp_resource_group_cpu_limit, указывающий максимальный процент ресурсов ЦПУ, который может потребить ADB со всеми ресурсными группами внутри. Он используется в первую очередь для того, чтобы защитить саму ОС и другие программы на хосте при высоких нагрузках ADB.

Important

Рекомендуется не выставлять параметр gp_resource_group_cpu_limit выше значения 0.9 (90%)

Для управления полосой загрузки ЦПУ для ресурсной группы используется параметр cpu_rate_limit. При этом сумма cpu_rate_limit по всем ресурсным группам не должна превышать 100%. Если в других ресурсных группах нет выделенных ядер (cpuset), то cpu_rate_limit показывает доступный данной ресурсной группе процент от присущих базе данных ресурсов ЦПУ на хосте (gp_resource_group_cpu_limit). В случае если для части ресурсных групп используются выделенные ядра, то доступные ресурсы определяются как минимальное из двух значений:

  • Незарезервированные ядра ЦПУ / все ядра ЦПУ;
  • gp_resource_group_cpu_limit.

Пример

Для примера используется профиль нагрузки на кластер, который единовременно загружен:

  • 50 “легкими” запросами SQL1, извлекающими единственную строку по первичному ключу;
  • 20 “средними” запросами SQL2, содержащими 2-3 соединения и возвращающими несколько десятков строк;
  • 2 “тяжелыми” запросам SQL3, считающими витрины со множеством соединений и по большим объемам данных (минимизация времени выполнения критична);
  • 1 “сверхтяжелый” запрос SQL4, загружающий данные из ETL системы через gpfdist.

Тогда можно использовать разделение ресурсов в кластере, представленное в таблице.

Табл. 1. Пример разделения ресурсов в кластере
Ресурсная
группа
Запросы concurrency cpu
rate
limit
cpuset memory
limit
memory
shared
quota
memory
spill ratio
g1 SQL1 50 35
20 20 20
g2 SQL2 20 25
15 10 20
g3 SQL3 2
1-16 40 0 40
g4 SQL4 1 30
15 0 20
default_group
20 5
5 50 20
admin_group
10 5
5 50 20

Для “тяжелых” запросов SQL3 с перестройкой витрин используются выделенные ядра 1-16 на каждом хосте (из 72 физических в наличии), что минимизирует переключения контекста на них и сильно увеличивает скорость запроса под высококонкурентной нагрузкой. Для “сверхтяжелого” запроса SQL4 нет необходимости в выделенных ядрах, так как при загрузке данных из ETL переключение контекста не оказывает сильного влияния на производительность. А правильная стратегия с выделенными ядрами под ресурсную группу заключается в использовании данного решения только тогда, когда не остается других вариантов (выделенные ядра ЦПУ “невидимы” для остальных ресурсных групп).