Интегральные гарантии
Базовый механизм предоставления гарантий на вычислительные ресурсы в системе YTsaurus предполагает выдачу константного количества ресурсов (строгая гарантия), выраженного чаще всего в ядрах CPU. Такой вид гарантии хорошо подходит для задач, способных постоянно утилизировать ресурсы. В реальности встречаются и другие сценарии, в которых требуется бо́льшая гибкость.
Например, когда продакшен процессу необходимо выполнить расчёты за сравнительно короткий промежуток времени, но в пике ему нужно много вычислительной квоты, остальное время уровень потребления может быть значительно ниже. В случае использования базового механизма предоставления гарантии, процессу необходимо выделять ресурсы по максимальному значению потребления и заказывать больше ресурсов при планировании, чем реально требуется.
Существуют процессы, для которых не столь важно получить вычислительные ресурсы в моменте, но важно, чтобы в течение некоторого длительного промежутка времени процессы смогли завершиться. В таком случае речь идёт о некотором среднем значении вычислительной квоты за продолжительное время. Например, исследовательские и аналитические задачи, эксперименты.
Механизм интегральных гарантий позволяет найти баланс между описанными сценариями.
Интегральные пулы
В системе YTsaurus существует возможность включить накопление ресурсов для пула. В такие пулы с постоянной скоростью поступает некоторый объём виртуальных ресурсов — accumulated_resource_ratio_volume
. Объём ресурса хранится в доле кластера в секунду — fair_share*sec
, но для простоты можно считать, что значение приведено в ядрах в секунду — cpu*sec
. Пул может расходовать виртуальный ресурс, чтобы запускать операции, а может накапливать его до определённого лимита.
Пример: пусть в пуле накопилось accumulated_resource_ratio_volume = 60 fair_share*sec
, на кластере 1000 ядер, и доминантный ресурс пользовательского процесса — CPU. Данный объём можно пересчитать в ядра * секунды
— 60000 cpu*sec
. Операция, потребляющая в моменте 100 CPU, истратит данный объём за 10 минут, а потребляющая 50 CPU — за 20 минут. В данном примере не учитывается, что с течением времени объём виртуального ресурса в пуле пополняется.
Скорость накопления ресурса настраивается в атрибуте пула integral-guarantees/resource_flow
. В значении атрибута должен быть указан тип ресурса и его объём:
$ yt set //sys/pools/root-pool/burst/@integral-guarantees/resource_flow "{cpu=100}"
Поскольку resource_flow
— это скорость увеличения accumulated_resource_ratio_volume
, который представляет собой мгновенное количество ресурса умноженное на время, то resource_flow/cpu
измеряется в ядрах, проще говоря, cpu*sec/sec = cpu
. Например, resource_flow/cpu = 100
позволяет бесконечно долго выполняться операции, потребляющей 100 CPU в моменте.
Накопление accumulated_resource_ratio_volume
происходит до определённого предела, который равен k*resource_flow_ratio
, где k
— единый для всех пулов параметр планировщика, а resource_flow_ratio
— resource_flow
как доля от всех ресурсов кластера. Значение для параметра k
настраивается администратором кластера.
Описанная идея накопления и расходования ресурсов во многом похожа на алгоритм Token bucket. Не стоит путать с Leaky bucket.
Виды гарантий
В системе YTsaurus существует три вида гарантий на вычислительные ресурсы:
- strong_guarantee — строгая гарантия доли ресурсов кластера. Выставляется в том числе в абсолютном значении (в ядрах), автоматически пересчитывается в долю кластера. Позволяет в любой момент времени получить гарантию и использовать её бесконечно долго;
- burst_integral — гарантия в моменте («пиковая гарантия») в ядрах, позволяет получать фиксированную гарантию в течение промежутка времени. Например, получать 2000 ядер в течение двух часов в сутки;
- relaxed_integral — интегральная гарантия (в ядрах) позволяет получить фиксированный объём ресурса в среднем за сутки.
Типы интегральных пулов
Для поддержки двух сценариев, описанных в начале раздела, в системе YTsaurus реализованы два типа интегральных пулов:
-
Burst pool — пул, который имеет приоритет при расходовании
accumulated_resource_ratio_volume
. У таких пулов должны быть указаныresource_flow
иburst_guarantee_resources
. При наличии операций в пуле, требующих ресурсов (demand), планировщик обязан выдать не менееburst_guarantee_resources
пулу, если в пуле накоплено достаточноaccumulated_resource_ratio_volume
. Данный тип пулов обеспечиваетburst_integral
гарантию.Пример конфигурации burst пула:
yt set //sys/pools/root-pool/burst/@integral-guarantees " { guarantee_type=burst; resource_flow={cpu=1000}; burst_guarantee_resources={cpu=2000} }"
В приведённом примере пользователь может рассчитывать, что пулу гарантированы 1000 ядер всегда или 2000 "половину" времени (например, 12 часов в сутки), если в течение второй половины ничего не запускается.
Burst гарантия одновременно является и ограничением скорости потребления накопленного ресурса. Если гарантия burst_gurantee_resources/cpu равна 2000, то по умолчанию планировщик не даст пулу потребить более 2000 ядер в моменте. Такое поведение обеспечивает защиту от случайного быстрого расходования накопленного интегрального ресурса.
-
Relaxed pool — пул, для которого нет гарантии получить все ресурсы за
accumulated_resource_ratio_volume
в заданный момент, но есть гарантия получить их в итоге (в течение суток). Для relaxed пула можно задать толькоresource_flow
. Предполагается, что в таких пулах будут запускаться операции, которые не требуют мгновенного получения ресурсов, которые им полагаются. Данный тип пулов обеспечиваетrelaxed_integral
гарантию.
Пример конфигурации relaxed пула:Листинг 3
yt set //sys/pools/root-pool/relaxed/@integral-guarantees " { guarantee_type=relaxed; resource_flow={cpu=1000} }"
В relaxed пулах, также как и в burst пулах, существует ограничение на потребление ресурсов. В случае relaxed пулов ограничение в три раза превышает значение flow гарантии. Например, при гарантии resource_flow/cpu равной 1000, планировщик по умолчанию ограничит потребление пула тремя тысячами ядер в моменте.
Описанные типы пулов дополняют друг друга, позволяя использовать одни и те же ресурсы и приоритетным процессам, требующим значительных гарантий на ограниченные промежутки времени, и менее значимым процессам, для которых допустимо подождать выделения ресурсов.
Пример
Пусть есть продакшен процесс, требующий 2000 CPU 12 часов в сутки, и исследовательский (research) процесс, которому достаточно 1000 CPU в среднем. С помощью механизма интегральных гарантий можно сконфигурировать для таких процессов burst и relaxed пулы, и для обеспечения гарантий потребуется 2000 ядер. Указанные пулы должны находиться в одном дереве пулов, других ограничений нет. При использовании базового механизма выдачи гарантий (строгая гарантии) для строго соблюдения таких гарантий пришлось бы заказать 3000 ядер.
На рисунке приведён график потребления (usage) и потребности (demand) в CPU для burst пула, для которого burst_integral
гарантия равна 500 CPU, а resource_flow
равен 100 CPU.
На рисунке ниже приведён график объёма накопленного ресурса для того же пула. Видно, как объём виртуального ресурса уменьшается при запущенных операциях в пуле, а после ресурс вновь накапливается до заданного предела.
Сочетание со строгими гарантиями
Оба вида интегральных пулов естественным образом совместимы со строгими гарантиями. При выдаче ресурсов планировщик сперва будет выдавать ресурсы в счёт строгих гарантий. Если их достаточно для покрытия текущей потребности пула, то accumulated_resource_ratio_volume
расходоваться не будет. Если потребность в ресурсах превышает строгие гарантии, то для удовлетворения превышающей части будет потрачен accumulated_resource_ratio_volume
.
Интегральные пулы наравне с соседними пулами участвуют в получении ресурсов сверх своих гарантий от пулов выше по иерархии пропорционально выставленным весам.
Дополнительные атрибуты интегральных пулов
Существует возможность запрашивать у планировщика значение служебных атрибутов, которые доступны в специальном поддереве Кипариса, называемом Орхидеей.
accumulated_resource_ratio_volume
— накопленные интегральные ресурсы в терминах доли кластера * секунду;accumulated_resource_volume
—accumulated_resource_ratio_volume
в виде словаря со всеми ресурсами. Например,accumulated_resource_volume/cpu
— это объём накопленного интегрального ресурса, выраженного в ядро * секунду;integral_pool_capacity
— предел накопленияaccumulated_resource_ratio_volume
;specified_burst_ratio
—burst_guarantee_resources
, переведённые в долю кластера;specified_resource_flow_ratio
—resource_flow
, переведённый в долю кластера;total_burst_ratio
— суммаspecified_burst_ratio
по всем потомкам (включая текущий пул);total_resource_flow_ratio
— суммаspecified_resource_flow_ratio
по всем потомкам (включая текущий пул);estimated_burst_usage_duration_seconds
— предполагаемый промежуток времени, на который хватит накопленного ресурса (с учётом продолжающегося поступления ресурсов со скоростьюresource_flow
), при потребленииburst_guarantee_resources
(есть только у burst пулов).
Пример запроса атрибута представлен в листинге 4.
Листинг 4
yt get //sys/scheduler/orchid/scheduler/scheduling_info_per_pool_tree/physical/fair_share_info/pools/pool_name/integral_pool_capacity
Внимание
Орхидея планировщика не является частью стабильного API и может изменяться без анонсов.