Бинарные данные в таблицах
В данном разделе собрана информация о том, как использовать таблицы для хранения бинарных данных.
Общие сведения
Иногда необходимо сохранять бинарные данные из джобов.
Очевидное решение заключается в том, чтобы писать из каждого джоба файл в Кипарис.
Но у этого способа есть недостатки:
- Создается высокая нагрузка на прокси.
- Появляется большое количество объектов в Кипарисе, что негативно сказывается на эффективности работы с ними.
Поэтому предпочтительнее записывать бинарные данные в одну таблицу:
- Данные разбиваются на части и сохраняются в отдельные строки таблицы. У этой таблицы должен быть набор ключевых колонок, которые однозначно определяют файл: имя и путь. Кроме того, должна быть колонка, отвечающая за номер BLOB с данными и колонка, отвечающая за сами данные. Таблица должна быть отсортирована по набору ключевых колонок и по колонке с номером BLOB, чтобы были возможны точечные чтения по ключу, задающему имя файла.
- Для файла все BLOB, кроме последнего, должны иметь одинаковый размер. Рекомендуемый размер — 4 МБ, его по умолчанию ожидают некоторые команды, например
read_blob_table
. Колонки с данными и номером BLOB должны иметь именаdata
иpart_index
соответственно.
Таблицы, удовлетворяющие описанным условиям, — BLOB-таблицы.
Внутри YTsaurus BLOB-таблицы используются для хранения stderr и core-файлов, порождаемых джобами операций.
Например, в таблице с stderr операции имеется 3 колонки: job_id
, part_index
и data
, таблица отсортирована по job_id
и part_index
.
Команда read_blob_table
Для удобного чтения данных из BLOB-таблиц реализована специальная команда read_blob_table
.
Команда принимает на вход путь к таблице. На выход данная команда передает поток бинарных данных.
Также команда проверяет, что индексы читаемых BLOB начинаются с нуля и идут без пропусков.
Команда имеет параметры part_index_column_name
и data_column_name
, позволяющие задать имена колонок с номером BLOB и данными соответственно. По умолчанию эти имена равны part_index
и data
.
Пример запуска операции и чтения stderr джоба из таблицы с BLOB:
# Запускаем Map операцию
$ yt --proxy <cluster-name> map --src '//tmp/table_in' --dst '//tmp/table_mapped' --format yson 'cat; echo something >&2' --spec='{stderr_table_path="//tmp/stderr_table";}'
2023-12-07 16:25:19,463 INFO Operation started: http://<cluster-name>/?page=operation&mode=detail&id=11788844-52f37dd2-3ff03e8-ff3bf1e4&tab=details
2023-12-07 16:25:19,561 INFO ( 0 min) operation 11788844-52f37dd2-3ff03e8-ff3bf1e4 initializing
2023-12-07 16:25:22,961 INFO ( 0 min) Unrecognized spec: {'mapper': {'title': 'cat;'}}
2023-12-07 16:25:24,230 INFO ( 0 min) operation 11788844-52f37dd2-3ff03e8-ff3bf1e4: running=0 completed=0 pending=1 failed=0 aborted=0 lost=0 total=1 blocked=0
2023-12-07 16:25:25,353 INFO ( 0 min) operation 11788844-52f37dd2-3ff03e8-ff3bf1e4 completing
2023-12-07 16:25:27,527 INFO ( 0 min) operation 11788844-52f37dd2-3ff03e8-ff3bf1e4 completed
# Узнаём job id
$ yt --proxy <cluster-name> list-jobs 11788844-52f37dd2-3ff03e8-ff3bf1e4 --format json | jq '.jobs[] | select(.type=="map").id'
"4c3fc84d-884fbde5-3ff0384-94b1"
# Читам «ошибки» только этого джоба
$ yt --proxy <cluster-name> read-blob-table '//tmp/stderr_table["4c3fc84d-884fbde5-3ff0384-94b1"]'
something