Подбор памяти для джобов
Под памятью имеется в виду RAM - оперативная память, потребляемая джобами операций.
Для всех операций по умолчанию работает механизм подбора фактического резерва памяти для запускаемых джобов.
Контроллер операции собирает для всех успешно завершившихся джобов информацию о потребленной памяти. Данная информация сохраняется в специальный digest, на основании которого подбирается фактический резерв памяти для вновь запускаемых джобов.
Основные аспекты работы digest-а:
- Собирает действительные значения (как правило, в диапазоне от 0.0 до 1.0), описывающие долю от
memory_limit
, которую потребил джоб. - Учитываются только успешно завершившиеся джобы и джобы, которые были прерваны по причине превышения резерва памяти.
- Для джобов, которые были прерваны по причине превышения резерва, в digest добавляется точка с долей потребления памяти этого джоба, умноженной на определенную константу, немного превышающую единицу (по умолчанию 1.1).
- В качестве резерва для вновь запущенного джоба берется
memory_limit * percentile(digest, P)
(по умолчаниюP
равно 0.95). - Внутри себя digest не хранит все точки, а используют некоторую структуру данных, позволяющую приближенно вычислять перцентили.
Выделенный джобу резерв памяти используется планировщиком для учёта потребления в качестве нижней границы. В случае превышения значения резерва и отсутствия свободной памяти на узле кластера джоб может быть прерван с указанием причины resource_overdraft
. При наличии дополнительной свободной памяти на узле кластера джоб может превысить выделенный ему резерв и успешно завершиться. В случае же превышения лимита по памяти, указанного пользователем в спецификации операции, джоб будет прерван с ошибкой Memory limit exceeded
.
Важно понимать, что помимо процесса пользователя в джобе также присутствует процесс job_proxy
, являющийся прослойкой между пользовательским процессом и YTsaurus. В зависимости от разных обстоятельств, job proxy может потреблять существенный объём оперативной памяти под компрессию, механизм колоночного чтения/записи, erasure и иные нужды. Контроллер операции поддерживает отдельные digest для процесса пользователя (user_job
) и для процесса job_proxy
. В случае процесса job_proxy
контроллер делает предположение относительно ожидаемого использования памяти, исходя из числа входных/выходных таблиц и их настроек. На основании сделанного предположения digest подбирает резерв (в диапазоне от 0.5 до 2.0 по умолчанию).
Кроме того, у выделяемого резерва памяти пользовательскому процессу есть нижняя граница. По умолчанию она указывается в спецификации и равна 0.05. Однако, если джоб заказывает tmpfs
, то резерв памяти не может быть меньше, чем tmpfs_size / memory_limit
, то есть система стремится не допускать оверкоммита по tmpfs
, так как он может приводить к блокировке работы планировщика.
Статистики
В статистиках операций есть ряд значений, которые позволяют провести анализ зарезервированной памяти:
user_job/memory_reserve
иjob_proxy/memory_reserve
(байты) - резерв памяти, выданной соответствующему процессу джоба;user_job/max_memory
иjob_proxy/max_memory
(байты) - потребление памяти соответствующего процесса джоба. Максимум в течение работы конкретного джоба;job_proxy/estimated_memory
(байты) - оценка планировщика на память процессаjob_proxy
данного джоба;user_job/memory_limit
(байты) - указанный пользователем лимит на память джоба;user_job/cumulative_memory_reserve
,job_proxy/cumulative_memory_reserve
,user_job/cumulative_max_memory
,job_proxy/cumulative_max_memory
,job_proxy/cumulative_estimated_memory
(байты * секунды) - соответствующие кумулятивные метрики с учетом длительности джобов.
Настройки digest
Доступные пользователю опции в спецификации операции:
user_job_memory_digest_default_value
- исходное предположение для выбора резерва памяти (по умолчанию 0.5).user_job_memory_digest_lower_bound
- граница, ниже которой не может опускаться резерв (по умолчанию 0.05). Не рекомендуется менять значение по умолчанию.memory_reserve_factor
- алиас для опцииuser_job_memory_digest_lower_bound
иuser_job_memory_digest_default_value
одновременно. Не рекомендуется использовать данную опцию.