Файловое окружение джобов: слои и файлы

Этот раздел описывает работу с файловым окружением джобов в YTsaurus. Вы узнаете, что такое слои и отдельные файлы, как задать их в спецификации операции, как подготовить и загрузить их в Кипарис, а также как ускорить чтение слоёв и диагностировать проблемы.

Что такое файловое окружение

Файловое окружение джоба — это набор директорий и файлов, в которых выполняется пользовательский процесс. Окружение представлено как корневая файловая система: дерево директорий и файлов, аналогичное любой Unix-системе.

Для запуска кода нужны зависимости: интерпретаторы, библиотеки, бинарные файлы, конфиги и данные. Если пользовательский код обратится к зависимости — директории или файлу, которой нет в окружении, то произойдёт ошибка. Поэтому окружение собирается под конкретную задачу.

Файловое окружение собирается из двух частей:

  • Корневая файловая система — собирается из слоёв, которые перечислены в параметре layer_paths. Подходит для постоянного окружения, переносимого от операции к операции.
  • Отдельные файлы — артефакты в поддереве /slot/sandbox, которые перечисляются в параметре file_paths. Подходят для разовой передачи в джоб конкретных файлов, например бинарников или конфигов.

Файловое окружение формирует среда исполнения — программное окружение, в котором запускается джоб. Среда исполнения предоставляет доступ к файловой системе и запускает в ней пользовательский код. Какие бывают среды и чем они отличаются — в разделе Среды исполнения.

Слои

Что такое слой

Слой — это файл, который содержит подмножество корневой файловой системы. Подмножество — это одно или несколько поддеревьев директорий и файлов с сохранённой структурой вложенности. Физически слой хранится как один файл, который загружается в YTsaurus.

Самый простой пример слоя — архив. Вы заранее готовите окружение на своей машине, упаковываете его в архив и загружаете в YTsaurus. Во время выполнения операции система разворачивает архив и формирует из него файловое окружение для джоба.

Как из слоёв собирается окружение

Корневую файловую систему можно собрать как из одного слоя, так и из нескольких. Слои из layer_paths объединяются в единую корневую файловую систему с помощью overlayfs — механизма ядра Linux, который объединяет несколько файловых систем в единую файловую систему.

Корневая файловая система собирается на exec-ноде на этапе подготовки джоба, перед запуском пользовательского кода. Контейнеризация — Porto или CRI — делает собранную файловую систему корнем / контейнера и запускает в нём пользовательский код. Без контейнеризации слои как корневая файловая система не применяются.

Как слой ложится в дерево

Каждый слой воспроизводит часть дерева — от верхнего уровня к нижним. Верхний уровень слоя — это папки и файлы, которые лежат в нём напрямую и не вложены в другие папки. После сборки они располагаются непосредственно в корне /.

Всё, что вложено в них, оказывается на нижних уровнях — внутри соответствующих папок корня.

Например, если в архиве на верхнем уровне лежат папки usr, bin, home, то после раскрытия они станут /usr, /bin, /home, а их вложенное содержимое — /usr/lib, /bin/bash и так далее.

Один слой может содержать сразу несколько поддеревьев. Например, в одном архиве могут быть и /usr, и /var.

Базовые и дельта-слои

Чаще всего окружение собирают по схеме «базовый слой + дельта». Она разделяет неизменную основу и собственные файлы:

  • Базовый слой — слой с основной частью окружения: системными утилитами и библиотеками, например /bin/bash и libc6. Чаще всего это образ какого-либо дистрибутива Linux, например Ubuntu, с установленными пакетами и библиотеками.
  • Дельта-слой — дополнение к базовому слою с собственными библиотеками или бинарными артефактами.

Распространённая конфигурация — один базовый слой и один или несколько дельта-слоёв: в качестве базового берут готовый образ, а собственные файлы помещают в дельту.

Форматы слоёв

В YTsaurus есть два формата слоёв: tar-архив и SquashFS. Для SquashFS дополнительно поддерживается доступ по сети — NBD. Чем форматы отличаются и когда какой выбрать — в таблице:

Формат

Что это

Когда использовать

Tar-архив

Классический архив с подмножеством файловой системы

Когда производительность не важна и нужно собрать слой максимально просто

SquashFS

Образ файловой системы, монтируется без распаковки

Когда важна производительность: ускоряется подготовка джоба, снижается нагрузка на диск

SquashFS по NBD

Чтение SquashFS-образа по сети, без скачивания на exec-ноду

Когда нужен самый быстрый старт джобов и большие образы не нужно копировать целиком

Tar-архив

Tar-архив — слой в виде архива .tar, .tar.gz, .tar.xz или .tar.zstd с подмножеством файловой системы.

Архив удобен по нескольким причинам:

  • Его просто собрать стандартной утилитой tar.
  • Его содержимое легко посмотреть: скачайте архив и распакуйте.
  • Он работает в любом контейнерном окружении.

При подготовке джоба архив скачивается на exec-ноду и распаковывается на диск. Распаковка нагружает CPU и Disk I/O, а распакованный слой занимает место на диске.

SquashFS

SquashFS — образ файловой системы, который монтируется на exec-ноде без распаковки. Точка монтирования затем используется как слой в overlayfs. Монтирование выполняется значительно быстрее распаковки архива.

SquashFS-слой даёт следующие преимущества по сравнению с tar-архивом:

  • Ускоряет подготовку джоба — образ не нужно распаковывать.
  • Снижает нагрузку на диск — ценный ресурс на кластерах.
  • Экономит место на диске — образ не хранится в распакованном виде.

SquashFS по NBD

NBD — Network Block Device — способ использовать SquashFS-образ по сети. Данные образа читаются с data-нод по мере необходимости, без предварительного скачивания на exec-ноду.

Локальный SquashFS-слой сначала целиком скачивается на exec-ноду. NBD читает с data-нод только те блоки, к которым обращается джоб. За счёт этого NBD не тратит ресурсы, которые нужны локальному слою:

  • CPU и Disk I/O на запись образа на диск.
  • Место на диске для хранения образа.
  • Network I/O на передачу частей образа, которые джоб не читает.

Уже прочитанные блоки кешируются на нескольких уровнях: в page cache ядра, в кешах читателя чанков и в кешах на data-нодах. Повторные обращения к тем же данным обслуживаются из кеша без новых сетевых чтений. Благодаря этому NBD-слои могут оказаться значительно быстрее обычных слоёв.

NBD работает поверх образа в формате SquashFS. Этот формат сжимает данные и доступен только для чтения, что соответствует назначению слоя: слой не изменяется во время работы джоба.

Важно

NBD работает только в порто-окружении.

Среды исполнения

Набор доступных форматов слоёв зависит от среды исполнения, настроенной на кластере в параметре exec_node/slot_manager/job_environment/type:

Среда

Описание

Поддерживаемые форматы слоёв

simple

Без контейнеризации

cri

Docker-контейнеры

Docker-образы

porto

Порто-окружение

Tar-архивы, SquashFS, SquashFS по NBD, Docker-образы

Примечание

В средах simple и cri SquashFS и NBD не поддерживаются.

Отдельные файлы

Что такое отдельный файл

Отдельный файл — это артефакт из Кипариса, который доставляется в джоб напрямую, без сборки слоя. Файлы передаются через параметр file_paths и попадают в поддерево /slot/sandbox корневой файловой системы. По сути файлы дополняют файловое окружение корневой файловой системы.

Отдельные файлы подходят для передачи в джоб: конфигов, бинарников, моделей. Пользователь сам кладёт файл и знает, по какому пути обратиться к нему из кода.

Размещение файлов в /slot/sandbox

Каждый файл из file_paths попадает в поддерево /slot/sandbox корневой файловой системы. По умолчанию файл становится доступен джобу по пути /slot/sandbox/<имя файла>, где имя файла совпадает с оригинальным именем из Кипариса.

Чтобы разместить файл в другом месте корневой файловой системы — например, в /bin или /usr/lib — придётся добавить его через слой. Подробнее — в разделе Отличие файлов от слоёв.

Отличие файлов от слоёв

Файлы и слои решают разные задачи:

  • Файлы через file_paths подходят для передачи несистемных конфигов, моделей, бинарников. С помощью файлов не получится передать, например, шаренные C/C++ библиотеки или системные конфиги: файлы попадают в поддерево /slot/sandbox и не могут быть размещены в произвольном месте корневой файловой системы.
  • Слои через layer_paths нужны для создания системного окружения. Сюда входит всё, что нужно для запуска пользовательской программы: системные библиотеки, динамический линковщик, системные конфиги, приложения. Слой может содержать файлы в любой директории корневой файловой системы — /usr, /bin, /lib и других.

Если нужно разместить файл вне /slot/sandbox — например, библиотеку в /usr/lib — соберите дельта-слой и укажите его в layer_paths. Библиотека часто не может находиться в произвольном месте: система требует положить её по определённому пути, иначе она не заработает.

Как задать файловое окружение в спецификации

Файловое окружение джоба задаётся в спецификации операции двумя параметрами: layer_paths — для слоёв корневой файловой системы, file_paths — для отдельных файлов.

Параметр layer_paths

Слои передаются в операцию через параметр layer_paths — список путей к слоям в Кипарисе. Минимальный пример — окружение из одного слоя:

import yt.wrapper as yt

spec = {
    "mapper": {
        "layer_paths": [
            "//path/to/my_layer",
        ]
    }
}

yt.run_map(mapper, source_table, destination_table, spec=spec)

Порядок слоёв

Слои в layer_paths перечисляются от верхнего к нижнему: дельта-слои указываются первыми, базовый слой — последним.

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

Именно поэтому файлы из дельты перекрывают файлы базового слоя, даже если файл с тем же путём есть в обоих.

Если пересечений нет, порядок не имеет значения. Например, когда один слой содержит /usr, а другой — /var.

"layer_paths": [
    "//path/to/delta_layer",   # Верхний слой, дельта
    "//path/to/base_layer",    # Нижний слой, базовый
]

Если файл по одному пути есть в обоих слоях, используется файл из delta_layer. Из верхнего слоя берётся не только содержимое файла, но и его метаданные: права доступа, владелец и группа, временные метки.

Атрибуты слоёв

Формат слоя и способ доступа к нему определяются атрибутами файла в Кипарисе:

Атрибут

Значения

Описание

filesystem

archive, squashfs

Формат слоя: archive — tar-архив, squashfs — образ файловой системы SquashFS

access_method

local, nbd

Способ доступа к образу

Для SquashFS-слоя с доступом по NBD можно указать access_method прямо в пути слоя:

spec = {
    "mapper": {
        "layer_paths": [
            "<access_method=nbd>//path/to/my_layer.squashfs",  # SquashFS по NBD
            "//path/to/porto_layer",  # Базовый tar-слой
        ]
    }
}

Атрибут access_method в спецификации доступен начиная с версии 25.1. Он удобен, когда один слой нужно использовать с разными методами доступа или когда нет прав на изменение атрибутов файла.

Значение по умолчанию

Если layer_paths не указан, используется образ по умолчанию, настроенный на кластере. Как правило, это минимальный базовый образ Ubuntu.

Параметр file_paths

Файлы передаются в операцию через параметр file_paths — список путей к файлам в Кипарисе с атрибутами. Каждый файл попадает в поддерево /slot/sandbox.

Конфликты имён

Если два файла в file_paths имеют одинаковое имя и атрибут file_name не задан, последний файл перезапишет предыдущий. Задавайте уникальный file_name для каждого файла.

Атрибуты файлов

У каждого файла в file_paths можно задать атрибуты:

Атрибут

Тип

Описание

file_name

строка

Имя файла в поддереве /slot/sandbox. По умолчанию — оригинальное имя файла из Кипариса. Поддерживает вложенные пути, например nv_tmpfs/sys/static/bundle.tar.gz

executable

bool

Установить флаг исполняемости. По умолчанию — false

bypass_artifact_cache

bool

Не кешировать файл в артефактном кеше exec-ноды. По умолчанию — false. Может быть удобно, например, когда нужно копировать файл сразу в tmpfs

copy_file

bool

Копировать файл вместо создания жёсткой ссылки. По умолчанию — false

Из атрибутов ключевые два. Атрибут $value задаёт путь в Кипарисе, откуда взять файл. Атрибут file_name задаёт путь в файловом окружении джоба, куда его положить.

Пример спецификации с атрибутами файлов:

spec = {
    "file_paths": [
        {
            "$value": "//path/to/nirvana-bundle.tar.gz",
            "$attributes": {
                "file_name": "nv_tmpfs/sys/static/nirvana-bundle.tar.gz",
                "executable": False,
                "bypass_artifact_cache": True,
            }
        },
        {
            "$value": "//path/to/job_launcher_native",
            "$attributes": {
                "file_name": "nv_tmpfs/sys/static/job_launcher_native",
                "executable": True,
                "bypass_artifact_cache": True,
            }
        },
    ],
    "mapper": {
        "layer_paths": [
            "//path/to/porto_layer",
        ]
    }
}

В этом примере nirvana-bundle.tar.gz будет доступен по пути /slot/sandbox/nv_tmpfs/sys/static/nirvana-bundle.tar.gz. Файл job_launcher_native — по пути /slot/sandbox/nv_tmpfs/sys/static/job_launcher_native с правом на выполнение.

Значение по умолчанию

Если file_paths не указан, поддерево /slot/sandbox остаётся без пользовательских файлов.

Порядок подготовки окружения

Окружение джоба собирается в два этапа:

  1. Подготовка корневой файловой системы. Система скачивает слои из layer_paths, монтирует их с помощью overlayfs и формирует корневую файловую систему.
  2. Доставка файлов. Система скачивает файлы из file_paths и размещает их в поддереве /slot/sandbox корневой файловой системы.

Пользовательский код запускается только после завершения обоих этапов.

Примеры спецификаций

Слои и файлы можно комбинировать в одной спецификации. Пример — базовый tar-слой в layer_paths и дополнительные артефакты в file_paths:

spec = {
    "file_paths": [
        {
            "$value": "//path/to/executor-config.yaml",
            "$attributes": {
                "file_name": "executor-config.yaml",
                "bypass_artifact_cache": True,
            }
        },
        {
            "$value": "//path/to/my_binary",
            "$attributes": {
                "file_name": "my_binary",
                "executable": True,
            }
        },
    ],
    "mapper": {
        "layer_paths": [
            "//path/to/porto_layer",
        ]
    }
}

Файлы будут доступны по путям /slot/sandbox/executor-config.yaml и /slot/sandbox/my_binary.

Подготовка и загрузка слоёв и файлов в Кипарис

Подготовка слоёв

Сборка tar-архива

Соберите архив, например, с помощью команды tar:

tar czf delta_layer.tar.gz configs data bins

Создание SquashFS-образа

Отдельного «NBD-образа» не существует: для доступа по NBD используется тот же SquashFS-образ. Формат слоя и способ доступа определяются не расширением файла, а атрибутами при загрузке в Кипарис. Подробнее — в разделе Загрузка слоёв в Кипарис.

Соберите образ из папки с помощью mksquashfs:

sudo apt install squashfs-tools
mkdir ~/mnt
# Наполните ~/mnt нужным содержимым
mksquashfs ~/mnt /tmp/my_layer.squashfs

Если у вас уже есть tar-слой, его можно сконвертировать в SquashFS с помощью tar2sqfs:

sudo apt install squashfs-tools-ng
tar2sqfs ~/dict.squashfs < ~/dict.tar.gz

При сборке образа можно задать размер блока SquashFS — ключевой параметр для производительности при доступе по NBD. Подробнее — в разделе Оптимизация NBD слоёв.

Важно

При конвертации tar-слоёв в SquashFS убедитесь, что нет ошибок переноса расширенных атрибутов trusted.overlay.*. Такие ошибки могут привести к некорректной работе overlayfs.

Загрузка слоёв в Кипарис

И для tar-слоёв, и для SquashFS-образов можно задать медиум хранения ssd_blobs и число реплик — это ускоряет скачивание слоя на exec-ноды. Подробнее — в разделе Как ускорить чтение слоёв.

Загрузка tar-слоя

yt write-file //path/to/layer.tar.gz < ~/layer.tar.gz

Если формат файловой системы не указан, слой считается tar-архивом.

Загрузка SquashFS-образа

При загрузке SquashFS-образа укажите формат файловой системы атрибутом @filesystem:

yt write-file //path/to/layer.squashfs < ~/layer.squashfs
yt set //path/to/layer.squashfs/@filesystem squashfs
yt set //path/to/layer.squashfs/@access_method local

Примечание

Если файл имеет расширение .squashfs, атрибут @filesystem определяется автоматически.

Чтобы использовать SquashFS-образ по сети, задайте атрибут @access_method со значением nbd:

yt write-file //home/user/layers/base.squashfs < ~/base.squashfs
yt set //home/user/layers/base.squashfs/@filesystem squashfs
yt set //home/user/layers/base.squashfs/@access_method nbd

После этого слой можно использовать в операциях:

map_spec = {"mapper": {"layer_paths": ["//home/user/layers/base.squashfs"]}}

yt.wrapper.run_map(
    Mapper(),
    source_table=args.input_table,
    destination_table=args.output_table,
    spec=map_spec,
)

Способы доступа:

  • access_method=local — образ скачивается на exec-ноду и монтируется локально.
  • access_method=nbd — образ читается по сети через NBD.

В каждый момент времени образ используется только в одном режиме: local или nbd.

Подготовка файлов

Перед загрузкой файлов в Кипарис подготовьте их на локальной машине:

  • Соберите нужные файлы: скрипты, бинарники, конфиги, модели.
  • Проверьте целостность файлов: сверьте хеши или контрольные суммы, если файлы скачивались из внешних источников.
  • Проверьте права доступа: файлы для запуска должны быть исполняемыми.
  • Организуйте файлы в логичную структуру каталогов, например /scripts, /configs, /models.

Загрузка файлов в Кипарис

Файлы для file_paths загружаются в Кипарис так же, как и слои. Дополнительно можно настроить параметры хранения.

Выбор медиума

Скорость скачивания файлов можно увеличить с помощью используемого медиума, задав атрибут primary_medium. Часто используемые файлы храните на SSD, редко используемые — на HDD:

yt create --type file \
    --attributes '{primary_medium=ssd_blobs;account=sys;}' \
    --path //path/to/my_file
yt write-file //path/to/my_file < ~/my_file

Для существующего файла:

yt set //path/to/my_file/@primary_medium ssd_blobs
yt set //path/to/my_file/@account sys

Число реплик

Скорость скачивания файлов можно увеличить с помощью числа реплик, задав атрибут replication_factor. По умолчанию — 3, максимум — 20:

yt create --type file \
    --attributes '{replication_factor=10;}' \
    --path //path/to/my_file
yt write-file //path/to/my_file < ~/my_file

Для существующего файла:

yt set //path/to/my_file/@replication_factor 10

Рекомендации по именованию и организации

Чтобы упростить управление файлами в Кипарисе:

  • Используйте папки по назначению или версии: //home/<пользователь>/layers/, //home/<пользователь>/configs/.
  • Давайте файлам говорящие имена, чтобы было понятно их содержимое без открытия.
  • При обновлении файла создавайте новую версию в отдельной папке, а не перезаписывайте существующую — так вы сможете откатиться при ошибке.

Проверка доступности

После загрузки проверьте, что файл доступен:

yt list //path/to/
yt get //path/to/my_file/@size

Практические сценарии

Базовый слой и файлы через file_paths

Используйте этот сценарий, когда нужно добавить к стандартному окружению несколько артефактов — конфиги, бинарники или модели — без создания нового слоя.

spec = {
    "file_paths": [
        {
            "$value": "//path/to/config.yaml",
            "$attributes": {
                "file_name": "config.yaml",
            }
        },
        {
            "$value": "//path/to/my_binary",
            "$attributes": {
                "file_name": "my_binary",
                "executable": True,
            }
        },
    ],
    "mapper": {
        "layer_paths": [
            "//path/to/porto_layer",
        ]
    }
}

Файлы будут доступны по путям /slot/sandbox/config.yaml и /slot/sandbox/my_binary.

Дельта-слой вместо множества file_paths

Используйте этот сценарий, например, когда вместе с файлами нужно принести сложные зависимости: pip, apt, conda, разделяемые библиотеки.

Соберите дельта-слой из своих файлов:

mkdir -p ~/delta/usr/lib ~/delta/usr/bin
cp ~/my_library.so ~/delta/usr/lib/
cp ~/my_binary ~/delta/usr/bin/
mksquashfs ~/delta /tmp/delta_layer.squashfs
yt write-file //path/to/delta_layer.squashfs < /tmp/delta_layer.squashfs
yt set //path/to/delta_layer.squashfs/@filesystem squashfs
yt set //path/to/delta_layer.squashfs/@access_method nbd

Используйте дельта-слой в операции вместе с базовым:

spec = {
    "mapper": {
        "layer_paths": [
            "<access_method=nbd>//path/to/delta_layer.squashfs",  # Дельта-слой
            "//path/to/porto_layer",  # Базовый слой
        ]
    }
}

Файлы дельта-слоя перекрывают файлы базового слоя при совпадении путей.

Оптимизация и диагностика

Стадии подготовки окружения

Подготовка окружения джоба состоит из нескольких стадий. Каждая стадия занимает время и потребляет ресурсы. Метрики подготовки доступны в веб-интерфейсе YTsaurus:

  • На странице операции — вкладка Jobs → колонка Statistics.
  • На странице джоба — раздел Job statistics → стадия Prepare.

Ключевые стадии подготовки окружения:

Стадия

Что происходит

Что оптимизировать

Downloading artifacts

Скачивание слоёв и файлов из Кипариса на exec-ноду

Хранить на SSD, увеличить число реплик

Preparing artifacts

Подготовка скачанных артефактов: распаковка tar, проверка целостности

Перейти с tar на SquashFS

Preparing root volume

Монтирование слоёв и сборка корневой файловой системы через overlayfs

Перейти на SquashFS по NBD

Preparing tmpfs volumes

Подготовка tmpfs-томов для джоба

Зависит от размера tmpfs, настраивается на кластере

Анализ стадий

Чтобы найти узкое место, сравните время стадий между собой и проанализируйте выбросы:

  1. Откройте страницу операции и перейдите на вкладку Jobs.
  2. Найдите джобы с самым долгим временем подготовки — отсортируйте по колонке Prepare time.
  3. Откройте джоб и посмотрите разбивку по стадиям в разделе Job statistics.
  4. Сравните время стадий: стадия с максимальным временем — узкое место.
  5. Примените методы оптимизации из таблицы выше к найденной стадии.

Методы оптимизации стадий подготовки окружения

Если стадия Preparing root volume занимает больше всего времени, переход с tar на SquashFS по NBD даёт наибольший прирост. Если Downloading artifacts — увеличьте число реплик и проверьте, что слой хранится на SSD. Если Preparing artifacts — перейдите с tar на SquashFS, чтобы избежать распаковки.

Диагностика и устранение проблем

RootVolumePreparationFailed

Возникает при ошибке монтирования слоя во время подготовки корневой файловой системы. Возможные причины:

  • Повреждённый образ слоя.
  • Неверный формат файловой системы — @filesystem.
  • NBD-сервер недоступен или не настроен на кластере.

Причины, специфичные для NBD, — в разделе Частые ошибки при работе с NBD.

NbdError

Возникает при ошибке чтения из NBD-устройства во время выполнения джоба, например при разрыве соединения с data-нодой. Джоб автоматически абортируется и перезапускается. Если ошибки повторяются, операция завершается с ошибкой.

Ошибка создания NBD-тома

Возникает при ошибке создания NBD-тома на exec-ноде. Возможные причины:

  • NBD-сервер не запущен или недоступен на exec-ноде.
  • Превышен лимит NBD-устройств на exec-ноде.
  • Недостаточно ресурсов для создания тома.

Обратитесь к администратору кластера для диагностики.

Ошибка прав доступа к файлу

Если файл попал в /slot/sandbox, но пользовательский код не может его запустить, проверьте атрибут executable. По умолчанию он равен false. Установите executable: true для исполняемых файлов.

Конфликт имён в /slot/sandbox

Если два файла в file_paths имеют одинаковое имя и атрибут file_name не задан, последний файл перезапишет предыдущий. Задавайте уникальный file_name для каждого файла.

Нехватка дискового пространства

Распакованные tar-слои занимают место на диске exec-ноды. Перейдите на SquashFS: образ монтируется без распаковки и не хранится в распакованном виде.

Таймаут загрузки артефактов

Если стадия Downloading artifacts занимает слишком долго, увеличьте replication_factor и проверьте, что слой хранится на SSD. Большее число реплик позволяет читать данные параллельно с разных data-нод.

Проблемы с квотами и ресурсами

Если джоб завершается с ошибкой нехватки ресурсов — CPU, памяти или диска — проверьте лимиты в спецификации операции. Увеличьте параметры cpu_limit, memory_limit или disk_request при необходимости. Также проверьте, что распакованные tar-слои не занимают слишком много места: перейдите на SquashFS, чтобы не хранить образ в распакованном виде.

Как ускорить чтение слоёв

Хранить слои на SSD

Чтение с SSD значительно быстрее, чем с HDD. Это особенно важно для NBD: данные читаются интерактивно с data-нод по мере обращения джоба, а HDD-диски для этого слишком медленные.

# При создании файла
yt create --type file \
    --attributes '{primary_medium=ssd_blobs;account=sys;}' \
    --path //path/to/layer.squashfs
yt write-file //path/to/layer.squashfs < ~/layer.squashfs

# Для существующего файла
yt set //path/to/layer.squashfs/@primary_medium ssd_blobs
yt set //path/to/layer.squashfs/@account sys

Переезд на SSD происходит в фоновом режиме и может занять время.

Увеличить число реплик

Для NBD три реплики могут стать узким местом, когда слой используют много джобов одновременно. Большее число реплик позволяет читать данные параллельно с разных data-нод. За увеличение числа реплик приходится платить местом.

# При создании файла
yt create --type file \
    --attributes '{replication_factor=20;}' \
    --path //path/to/layer.squashfs
yt write-file //path/to/layer.squashfs < ~/layer.squashfs

# Для существующего файла
yt set //path/to/layer.squashfs/@replication_factor 20

По умолчанию replication_factor=3, максимум — 20.

Использовать чанковый кеш

Для tar и локальных SquashFS-слоёв с access_method=local exec-нода кеширует скачанные слои в чанковом кеше. При повторном запуске джобов с теми же слоями они берутся из кеша без скачивания с data-нод.

На эффективность кеша влияют два фактора:

  • Стандартные базовые слои с высокой вероятностью уже закешированы на exec-нодах.
  • Изменение файла слоя инвалидирует кеш — закешированная копия перестаёт использоваться.

NBD слои

Оптимизация NBD слоёв

Размер блока SquashFS

Файловая система SquashFS оперирует блоками. По умолчанию размер блока — 128 КБ. Чем больше блок, тем больше данных ядро читает за один раз и тем меньше NBD-запросов к data-нодам.

Размер блока задаётся при сборке образа:

mksquashfs ~/mnt /tmp/my_layer.squashfs -b 1M

Например, для беспилотников переход с блока 128 КБ на 1 МБ ускорил вычисление md5sum большого бинарника с 250–350 секунд до 40 секунд.

Примечание

Слишком большой блок увеличивает объём чтения при обращении к небольшим файлам: приходится читать «почти пустые» блоки. Кроме того, в текущей реализации SquashFS в Linux увеличение размера блока повышает потребление RAM при монтировании образа. Оптимальный размер зависит от паттерна доступа к файлам в слое.

Размер блока чанков

Не путайте размер блока SquashFS с размером блока чанков. Файл в Кипарисе состоит из чанков, а чанк читается с data-нод блоками. По умолчанию размер блока чанков — 16 МБ.

Ядро читает данные с NBD-устройств небольшими порциями, обычно не более 8 КБ. Поэтому при доступе по NBD меньший размер блока чанков — 512K, 1M или 2M — сокращает объём лишних чтений.

Размер блока задаётся при загрузке файла:

yt write-file \
    --file-writer '{block_size=2097152;}' \
    //path/to/layer.squashfs < ~/layer.squashfs

Например, для тасклетов уменьшение размера блока чанков с 16 МБ до 2 МБ заметно снизило объём чтений.

Важно

block_size задаётся один раз при записи файла. Чтобы изменить его, перезапишите файл.

Мониторинг и диагностика NBD

Solomon-сенсоры

На exec-нодах доступны следующие метрики NBD.

Серверные метрики:

Метрика

Описание

nbd/server/count

Текущее число NBD-серверов

nbd/server/created

Число созданных NBD-серверов

Метрики устройств. Тег file_path — путь к файлу слоя:

Метрика

Описание

nbd/device/count

Текущее число NBD-устройств

nbd/device/created / nbd/device/removed

Создано и удалено устройств

nbd/device/read_count

Число read-запросов

nbd/device/read_bytes

Прочитано байт

nbd/device/read_time

Время чтения, гистограмма

nbd/device/read_block_bytes_from_cache

Прочитано из блочного кеша

nbd/device/read_block_bytes_from_disk

Прочитано с диска data-нод

Метрики томов. Тег type=nbd или type=squashfs:

Метрика

Описание

volumes/count

Текущее число томов

volumes/created

Создано томов

volumes/create_errors

Ошибки создания томов

Метрики кеша томов:

Метрика

Описание

exec_node/ronbd_volume_cache/missed_count

Промахи кеша RO NBD-томов

exec_node/ronbd_volume_cache/hit_count

Попадания в кеш. Тег hit_type=sync\|async

exec_node/squashfs_volume_cache/missed_count

Промахи кеша SquashFS-томов

exec_node/squashfs_volume_cache/hit_count

Попадания в кеш SquashFS-томов

Частые ошибки при работе с NBD

Ниже — ошибки, специфичные для NBD. Общие ошибки подготовки окружения RootVolumePreparationFailed и NbdError описаны в разделе Диагностика и устранение проблем.

NBD server is not present

Возникает при попытке использовать NBD на кластере, где он не включён, или в среде, отличной от порто-окружения. Обратитесь к администратору кластера, чтобы включить NBD.

Неверные атрибуты слоя

Для доступа по NBD у слоя должны быть заданы атрибуты @filesystem=squashfs и @access_method=nbd. Если формат файловой системы указан неверно, монтирование слоя завершится ошибкой RootVolumePreparationFailed.

Предыдущая