Справочник по 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-метода для команды достаточно следовать следующему алгоритму:

  1. Если у команды есть поток входных данных, то PUT;
  2. Если команда мутирующая, то POST;
  3. Иначе GET.

Форматы данных для операций

Интерпретация входных и выходных байтовых потоков (при типе данных, отличных от бинарного) определяется форматом данных. Описание используемого формата представляет собой YSON-строку с, возможно, дополнительными атрибутами. Стандартным способом задания описания используемых форматов являются заголовки X-YT-Input-Format и X-YT-Output-Format. Для большей совместимости с HTTP-библиотеками частично поддерживаются заголовки Accept и Content-Type. Ниже приведено подробное описание правил определения формата.

Как указывается формат входных данных

Формат входных данных определяется по следующим правилам. Каждое последующее правило перекрывает предыдущее.

  1. Если указан заголовок Content-Type и указанный MIME-тип есть в таблице соответствия, то формат выбирается из таблицы;
  2. Если указан заголовок X-YT-Input-Format, то содержимое заголовка интерпретируется как JSON-закодированная YSON-строка с атрибутами и она используется как описание входного формата;
  3. Если ни п. 1, ни п. 2 не отработали успешно, то используется YSON.

Как указывается формат выходных данных

Формат выходных данных определяется по следующим правилам. Каждое последующее правило перекрывает предыдущее.

  1. Если указан заголовок Accept, то выбирается лучший MIME-тип из таблицы, соответствующий Accept-заголовку, и далее формат берется из таблицы. Content-Type равен совпавшему MIME-типу;
  2. Если указан заголовок X-YT-Output-Format, то содержимое заголовка интерпретируется как JSON-закодированная YSON-строка с атрибутами, и она используется как описание выходного формата. Content-Type равен application/octet-stream;
  3. Если ни п. 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 Сервис недоступен. Запрос нужно повторить попозже

Отладка запроса

Примечание

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

В запросе:

  1. Сформировать guid и выставить его в заголовок X-YT-Correlation-Id. Этот заголовок помогает по логу найти запрос, даже если ответ на него не пришёл клиенту.

В ответе:

  1. X-YT-Request-Id — идентификатор запроса, сформированный прокси. Нужен, чтобы найти запрос в логе YTsaurus прокси.
  2. 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 отсутствует отсутствует "данные готовятся, подожди"
Предыдущая
Следующая