---
metadata:
  - name: generator
    content: Diplodoc Platform v5.50.6
  - property: og:title
    content: 'Файловое окружение джобов: слои и файлы'
  - property: og:description
    content: Этот раздел описывает работу с файловым окружением джобов в YTsaurus.
  - property: og:type
    content: article
  - property: og:url
    content: https://ytsaurus.tech/docs/ru/user-guide/data-processing/layers/nbd-squashfs-layers
  - property: article:tag
    content: user-guide/data-processing/layers/nbd-squashfs-layers
  - property: article:modified_time
    content: '2026-08-11T17:00:00+03:00'
  - property: article:author
    content: Захар Телух
alternate:
  - https://ytsaurus.tech/docs/ru/user-guide/data-processing/layers/nbd-squashfs-layers.md
---
> **Documentation Index:** Fetch the complete configuration index at https://ytsaurus.tech/docs/ru/llms.txt


<!-- source: ru/_includes/user-guide/data-processing/layers/nbd-squashfs-layers.md -->
# Файловое окружение джобов: слои и файлы

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

## Что такое файловое окружение { #file-environment }

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

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

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

- Корневая файловая система — собирается из слоёв, которые перечислены в параметре [layer_paths](https://ytsaurus.tech/docs/ru/user-guide/data-processing/layers/layer-paths.md#job_rootfs). Подходит для постоянного окружения, переносимого от операции к операции.
- Отдельные файлы — артефакты в поддереве `/slot/sandbox`, которые перечисляются в параметре [file_paths](https://ytsaurus.tech/docs/ru/user-guide/data-processing/operations/operations-options.md#user_script_options). Подходят для разовой передачи в джоб конкретных файлов, например бинарников или конфигов.

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

## Слои { #layers }

### Что такое слой { #what-is-layer }

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

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

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

Корневую файловую систему можно собрать как из одного слоя, так и из нескольких. Слои из `layer_paths` объединяются в единую корневую файловую систему с помощью [overlayfs](https://wiki.archlinux.org/title/Overlay_filesystem) — механизма ядра Linux, который объединяет несколько файловых систем в единую файловую систему.

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

#### Как слой ложится в дерево { #rootfs-tree }

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

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

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

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

#### Базовые и дельта-слои { #base-delta }

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

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

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

### Форматы слоёв { #layer-formats }

В YTsaurus есть два формата слоёв: tar-архив и SquashFS. Для SquashFS дополнительно поддерживается доступ по сети — [NBD](https://ytsaurus.tech/docs/ru/admin-guide/nbd.md#how-it-works). Чем форматы отличаются и когда какой выбрать — в таблице:

#|
||**Формат**|**Что это**|**Когда использовать**||
||Tar-архив|Классический архив с подмножеством файловой системы|Когда производительность не важна и нужно собрать слой максимально просто||
||SquashFS|Образ файловой системы, монтируется без распаковки|Когда важна производительность: ускоряется подготовка джоба, снижается нагрузка на диск||
||SquashFS по NBD|Чтение SquashFS-образа по сети, без скачивания на exec-ноду|Когда нужен самый быстрый старт джобов и большие образы не нужно копировать целиком||
|#

#### Tar-архив { #tar-layer }

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

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

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

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

#### SquashFS { #squashfs-layer }

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

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

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

#### SquashFS по NBD { #nbd-layer }

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. Этот формат сжимает данные и доступен только для чтения, что соответствует назначению слоя: слой не изменяется во время работы джоба.

{% note warning %}

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

{% endnote %}

## Среды исполнения { #environments }

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

#|
||**Среда**|**Описание**|**Поддерживаемые форматы слоёв**||
||`simple`|Без контейнеризации|—||
||`cri`|Docker-контейнеры|[Docker-образы](https://ytsaurus.tech/docs/ru/user-guide/data-processing/layers/layer-paths.md#docker_images)||
||`porto`|Порто-окружение|Tar-архивы, SquashFS, SquashFS по NBD, Docker-образы||
|#

{% note info %}

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

{% endnote %}

## Отдельные файлы { #files }

### Что такое отдельный файл { #what-is-file }

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

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

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

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

Чтобы разместить файл в другом месте корневой файловой системы — например, в `/bin` или `/usr/lib` — придётся добавить его через слой. Подробнее — в разделе [Отличие файлов от слоёв](#files-vs-layers).

### Отличие файлов от слоёв { #files-vs-layers }

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

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

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

## Как задать файловое окружение в спецификации { #set-environment }

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

### Параметр layer_paths { #layer-paths }

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

```python
import yt.wrapper as yt

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

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

#### Порядок слоёв { #layer-order }

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

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

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

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

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

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

#### Атрибуты слоёв { #layer-attributes }

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

#|
||**Атрибут**|**Значения**|**Описание**||
||`filesystem`|`archive`, `squashfs`|Формат слоя: `archive` — tar-архив, `squashfs` — образ файловой системы SquashFS||
||`access_method`|`local`, `nbd`|Способ доступа к образу||
|#

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

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

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

#### Значение по умолчанию { #default-layer }

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


### Параметр file_paths { #file-paths }

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

#### Конфликты имён { #file-name-conflicts }

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

#### Атрибуты файлов { #file-attributes }

У каждого файла в `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` задаёт путь в файловом окружении джоба, куда его положить.

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

```python
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-default }

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

### Порядок подготовки окружения { #preparation-order }

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

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

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

### Примеры спецификаций { #spec-examples }

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

```python
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`.

## Подготовка и загрузка слоёв и файлов в Кипарис { #prepare-upload }

### Подготовка слоёв { #prepare-layers }

#### Сборка tar-архива { #create-tar }

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

```bash
tar czf delta_layer.tar.gz configs data bins
```

#### Создание SquashFS-образа { #create-squashfs }

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

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

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

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

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

При сборке образа можно задать размер блока SquashFS — ключевой параметр для производительности при доступе по NBD. Подробнее — в разделе [Оптимизация NBD слоёв](#nbd-optimization).

{% note warning %}

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

{% endnote %}


### Загрузка слоёв в Кипарис { #upload-layers }

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

#### Загрузка tar-слоя { #upload-tar }

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

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

#### Загрузка SquashFS-образа { #upload-squashfs }

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

```bash
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
```

{% note info %}

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

{% endnote %}

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

```bash
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
```

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

```python
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`.

### Подготовка файлов { #prepare-files }

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

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

### Загрузка файлов в Кипарис { #upload-files }

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

#### Выбор медиума { #file-medium }

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

```bash
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
```

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

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

#### Число реплик { #file-replication }

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

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

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

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

#### Рекомендации по именованию и организации { #file-naming }

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

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

#### Проверка доступности { #file-check }

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

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

## Практические сценарии { #scenarios }

### Базовый слой и файлы через file_paths { #scenario-base-files }

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

```python
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 { #scenario-delta }

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

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

```bash
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
```

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

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

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

## Оптимизация и диагностика { #optimization-diagnostics }

### Стадии подготовки окружения { #preparation-stages }

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

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

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

#|
||**Стадия**|**Что происходит**|**Что оптимизировать**||
||Downloading artifacts|Скачивание слоёв и файлов из Кипариса на exec-ноду|[Хранить на SSD](#ssd-storage), [увеличить число реплик](#replication-factor)||
||Preparing artifacts|Подготовка скачанных артефактов: распаковка tar, проверка целостности|Перейти с tar на [SquashFS](#squashfs-layer)||
||Preparing root volume|Монтирование слоёв и сборка корневой файловой системы через overlayfs|Перейти на [SquashFS по NBD](#nbd-layer)||
||Preparing tmpfs volumes|Подготовка tmpfs-томов для джоба|Зависит от размера tmpfs, настраивается на кластере||
|#

### Анализ стадий { #bottleneck-analysis }

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

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

### Методы оптимизации стадий подготовки окружения { #stage-optimization }

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

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

#### RootVolumePreparationFailed { #root-volume-error }

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

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

Причины, специфичные для NBD, — в разделе [Частые ошибки при работе с NBD](#nbd-common-errors).

#### NbdError { #nbd-error }

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

#### Ошибка создания NBD-тома { #nbd-volume-error }

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

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

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

#### Ошибка прав доступа к файлу { #file-permission-error }

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

#### Конфликт имён в /slot/sandbox { #file-name-conflict-error }

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

#### Нехватка дискового пространства { #disk-space-error }

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

#### Таймаут загрузки артефактов { #download-timeout }

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

#### Проблемы с квотами и ресурсами { #quota-error }

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

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

### Хранить слои на SSD { #ssd-storage }

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

```bash
# При создании файла
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 происходит в фоновом режиме и может занять время.

### Увеличить число реплик { #replication-factor }

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

```bash
# При создании файла
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.

### Использовать чанковый кеш { #chunk-cache }

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

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

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

## NBD слои { #nbd }

### Оптимизация NBD слоёв { #nbd-optimization }

#### Размер блока SquashFS { #squashfs-block-size }

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

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

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

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

{% note info %}

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

{% endnote %}

#### Размер блока чанков { #chunk-block-size }

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

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

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

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

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

{% note warning %}

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

{% endnote %}

### Мониторинг и диагностика NBD { #nbd-monitoring }


#### Solomon-сенсоры { #sensors }

На 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-common-errors }

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

#### NBD server is not present { #nbd-server-missing }

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

#### Неверные атрибуты слоя { #nbd-wrong-attributes }

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


<!-- endsource: ru/_includes/user-guide/data-processing/layers/nbd-squashfs-layers.md -->
