Справочник по HTTP-прокси
Структура выполнения команды
При разработке библиотеки для работы с YTsaurus полезно понимать структуру выполнения команды.
Каждая исполняемая команда представляет собой структуру, содержащую:
- информацию о пользователе, позволяющую провести аутентификацию (в случае работы по HTTP это чаще всего токен);
- информацию о входном и выходном формате данных (представлена в виде YSON-строки с атрибутами);
- информацию о параметрах команды (представлены в виде YSON-словаря);
- входной (байтовый) поток данных;
- выходной (байтовый) поток данных.
Ниже приведены формальные спецификации кодирования каждого пункта в HTTP-прокси, которые включают в себя более широкую функциональность по интерпретации HTTP-запросов (отчасти для поддержки совместимости с такими HTTP-клиентами, как веб-браузер). Для корректной работы с YTsaurus требуется поддержать меньший набор функциональности, а именно:
- указывать
X-YT-Header-Format
, определяющий формат для заголовковX-YT-Input-Format
,X-YT-Output-Format
иX-YT-Parameters
(значением заголовка является YSON); - указывать
X-YT-Input-Format
иX-YT-Output-Format
, закодированные в соответствии сX-YT-Header-Format
и определяющие форматы входных и выходных потоков данных; - все параметры команды передавать в заголовке
X-YT-Parameters
, закодированном в соответствии сX-YT-Header-Format
; - все HTTP-ответы 5xx считать ошибкой транспортного уровня. Стоит отличать код 503, который является явным сигналом о временной недоступности, и код 500, сигнализирующий об ошибке на стороне YTsaurus. В первом случае можно повторить запрос;
- во всех остальных ответах (2xx, 4xx) об успешном выполнении команды стоит судить по заголовкам/трейлерам
X-YT-Error
(предпочтительно) илиX-YT-Response-Code
(извлеченном изX-YT-Error
коде ошибки) иX-YT-Response-Message
(извлеченной изX-YT-Error
диагностике ошибки).
Как выбирается HTTP-метод для команды
Для выбора HTTP-метода для команды достаточно следовать следующему алгоритму:
- Если у команды есть поток входных данных, то PUT;
- Если команда мутирующая, то POST;
- Иначе GET.
Форматы данных для операций
Интерпретация входных и выходных байтовых потоков (при типе данных, отличных от бинарного) определяется форматом данных. Описание используемого формата представляет собой YSON-строку с, возможно, дополнительными атрибутами. Стандартным способом задания описания используемых форматов являются заголовки X-YT-Input-Format
и X-YT-Output-Format
. Для большей совместимости с HTTP-библиотеками частично поддерживаются заголовки Accept
и Content-Type
. Ниже приведено подробное описание правил определения формата.
Как указывается формат входных данных
Формат входных данных определяется по следующим правилам. Каждое последующее правило перекрывает предыдущее.
- Если указан заголовок
Content-Type
и указанный MIME-тип есть в таблице соответствия, то формат выбирается из таблицы; - Если указан заголовок
X-YT-Input-Format
, то содержимое заголовка интерпретируется как JSON-закодированная YSON-строка с атрибутами и она используется как описание входного формата; - Если ни п. 1, ни п. 2 не отработали успешно, то используется YSON.
Как указывается формат выходных данных
Формат выходных данных определяется по следующим правилам. Каждое последующее правило перекрывает предыдущее.
- Если указан заголовок
Accept
, то выбирается лучший MIME-тип из таблицы, соответствующий Accept-заголовку, и далее формат берется из таблицы. Content-Type равен совпавшему MIME-типу; - Если указан заголовок
X-YT-Output-Format
, то содержимое заголовка интерпретируется как JSON-закодированная YSON-строка с атрибутами, и она используется как описание выходного формата. Content-Type равенapplication/octet-stream
; - Если ни п. 1, ни п. 2 не отработали успешно, то используется Pretty YSON. Content-Type равен
text/plain
.
Коды возврата HTTP
Если веб-сервер понимает об ошибке до того, как клиенту отправляются какие-либо данные, то код возврата 4xx или 5xx обозначает ошибку. Если клиенту начали поставляться данные, то код возврата будет 202 (Accepted
), а в трейлер-хедере X-YT-Response-Code
будет код возврата YTsaurus. Ненулевой X-YT-Response-Code
свидетельствует об ошибке. В таком случае в трейлер-хедере X-YT-Response-Message
записано сообщение об ошибке (как JSON-строка).
Таблица 1 — Коды возврата
Код возврата | Описание |
---|---|
200 | Команда успешно отработала |
202 | Команда исполняется, тело ответа будет отправлено HTTP-потоком, в трейлер-хедерах записаны внутренние коды возврата |
307 | Редирект тяжёлых запросов с лёгких на тяжёлые прокси |
400 | Команда была исполнена, но вернулась ошибка (в теле подробная JSON-закодированная ошибка) |
401 | Неаутентифицированный запрос |
404 | Неизвестная команда |
405 | Неверный HTTP-метод |
406 | Неверный формат в Accept |
415 | Неверный формат в Accept-Encoding |
429 | Превышен лимит на количество запросов от пользователя |
500 | Ошибка на стороне прокси |
503 | Сервис недоступен. Запрос нужно повторить попозже |
Отладка запроса
Примечание
Все запросы поддерживают опциональные отладочные заголовки. Их обработка не является обязательной, но рекомендуется.
В запросе:
- Сформировать guid и выставить его в заголовок
X-YT-Correlation-Id
. Этот заголовок помогает по логу найти запрос, даже если ответ на него не пришёл клиенту.
В ответе:
X-YT-Request-Id
— идентификатор запроса, сформированный прокси. Нужен, чтобы найти запрос в логе YTsaurus прокси.X-YT-Proxy
— hostname прокси, с которой пришёл ответ. Важно для ситуации, когда запрос идёт через балансер.
Расширенные возможности
Сжатие
При передаче данных через HTTP-прокси можно использовать сжатие. Прокси выбирает кодек для входящих данных исходя из заголовка Content-Encoding
, а для исходящих — исходя из Accept-Encoding
. Возможные кодеки перечислены в таблице.
Content-Encoding/Accept-Encoding | Кодек |
---|---|
identity | Отсутствует |
gzip, deflate | Стандартный zlib |
Параметры
Каждая команда обладает набором дополнительных параметров, которые представляются в виде YSON-словаря. Стандартным способом передачи параметров является заголовок X-YT-Parameters
, который интерпретируется как JSON-закодированный YSON-словарь.
Список тяжёлых прокси (/hosts)
Все команды в YTsaurus делятся на лёгкие и тяжёлые. Тяжелые команды связаны с большим I/O и, как следствие, сетевой нагрузкой. Для изоляции данной нагрузки управляющие (лёгкие) команды отделяются от тяжёлых. При попытке исполнить тяжёлую команду лёгкие прокси вернут код 503. Балансировка тяжёлых команд по тяжёлым прокси производится непосредственно клиентом.
Перед исполнением тяжёлой команды необходимо обратиться к /hosts
и получить список прокси, упорядоченный по нагрузке. Нагрузка оценивается исходя из сиюминутной загрузки по CPU и сети, а также по некоторой запланированной в будущем нагрузки на прокси. Самая первая прокси в списке-результате — наименее загруженная, именно её вам нужно использовать в простых случаях (= в 80% случаев).
Доступные версии API (/api)
HTTP API является версионированным (как можно заметить из наличия префикса /v3
в примерах отсюда). Версия API изменяется при обратно-несовместимых изменениях множества поддерживаемых команд или семантики какой-либо из существующих команд. Добавление новых команд обычно не приводит к смене версии API. В HTTP-прокси осуществляется поддержка двух последних версий API.
Список поддерживаемых версий API можно получить по URL-у /api
.
Получение списка доступных API:
$ curl -v -X GET "http://$YT_PROXY/api"
> GET /api HTTP/1.1
< HTTP/1.1 200 OK
["v3","v4"]
Таблица соответствия MIME-типов и форматов YT
Соответствие MIME-типа YT-формату представлено в таблице.
MIME-тип | YT-формат |
---|---|
application/json | json |
application/x-yt-yson-binary | <format=binary>yson |
application/x-yt-yson-text | <format=text>yson |
application/x-yt-yson-pretty | <format=pretty>yson |
application/x-yamr-delimited | <lenval=false;has_subkey=false>yamr |
application/x-yamr-lenval | <lenval=true;has_subkey=false>yamr |
application/x-yamr-subkey-delimited | <lenval=false;has_subkey=true>yamr |
application/x-yamr-subkey-lenval | <lenval=true;has_subkey=true>yamr |
text/tab-separated-values | dsv |
text/x-tskv | <line_prefix=tskv>dsv |
Фрейминг
Для некоторых команд может использоваться особый протокол поверх обычного HTTP.
Именно, если клиент указывает заголовок X-YT-Accept-Framing: 1
, то прокси может ответить ответом с заголовком X-YT-Framing: 1
.
В таком случае тело ответа будет состоять из записей вида <tag> <header> <frame>
.
Типы фреймов:
Название | Tag | Header | Frame | Комментарий |
---|---|---|---|---|
Data | 0x01 |
4-байтовое little-endian число - размер фрейма | тело фрейма | |
Keep-alive | 0x02 |
отсутствует | отсутствует | "данные готовятся, подожди" |