Подбор памяти для джобов

Под памятью имеется в виду RAM — оперативная память, потребляемая джобами операций.
Для всех операций по умолчанию работает механизм подбора фактического резерва памяти для запускаемых джобов.

Данный механизм устроен следующим образом. Контроллер операции собирает для всех успешно завершившихся джобов информацию о потребленной памяти. Данная информация сохраняется в специальный digest, на основании которого подбирается фактический резерв памяти для вновь запускаемых джобов.

Основные аспекты работы digest-а:

  1. Собирает эффективное потребление памяти джобами, представляемое долей от memory_limit (то есть числом в диапазоне от 0.0 до 1.0).
  2. Учитываются только успешно завершившиеся джобы и джобы, которые были прерваны по причине превышения резерва памяти.
  3. Для джобов, которые были прерваны по причине превышения резерва, в digest добавляется точка с долей потребления памяти этого джоба, умноженной на определенную константу, немного превышающую единицу (по умолчанию 1.1).
  4. В качестве резерва для вновь запущенного джоба берется memory_limit * percentile(digest, P) (по умолчанию P равно 0.95).
  5. Внутри себя digest не хранит все точки, а используют некоторую структуру данных, позволяющую приближенно вычислять перцентили.

Выделенный джобу резерв памяти используется планировщиком для учёта потребления в качестве нижней границы. В случае превышения значения резерва и отсутствия свободной памяти на узле кластера джоб может быть прерван, при этом будет указана причина resource_overdraft. При наличии дополнительной свободной памяти на узле кластера джоб может превысить выделенный ему резерв и успешно завершиться. В случае же превышения memory_limit, указанного пользователем в спецификации операции, джоб будет прерван с ошибкой Memory limit exceeded.

Важно понимать, что помимо процесса пользователя в джобе также присутствует процесс job_proxy, являющийся прослойкой между пользовательским процессом и кластером. В зависимости от разных обстоятельств, 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 одновременно. Не рекомендуется использовать данную опцию.