Отправка сообщений в YDB Topics на уровне GRPC

Notice

Эта статья - черновик заметок по разработке SDK, может произвольным образом меняться, дополняться и удаляться. Версия НЕ стабильна.

На уровне протокола запись сообщений происходит через двунаправленный GRPC-стрим. Стрим открывается вызовом метода StreamWrite

Простой протокол отправки сообщений

Текстовое описание

  1. Отправляется сообщение с настройками подключения InitRequest.
  2. Сервер отправляет подверждение
  3. Дальше в цикле идёт отправка сообщений и получение подтверждений от сервера. При получении подтверждений сообщения могут быть перегруппированы (при этом гарантируется сохранение порядка)
    1. Количество сообщений с подтверждениями может отличаться от количества сообщений с отправкой сообщений.
    2. При подтверждении может не сохраняться исходная группировка сообщений. Одно подтверждение может охватывать сообщения из нескольких сообщений об отправке или наоборот подтверждать только часть сообщений. На стороне клиента подтверждения нужно отслеживать отдельно по каждому сообщению, без учёта их батчевания при отправке.

Схема

sequenceDiagram
  participant Client
  participant Server
  Client --> Server: Init stream
  Client ->> Server: StreamWriteMessage.FromClient.InitRequest
  Server ->> Client: StreamWriteMessage.FromServer.InitResponse

  Client --> Server: Common send messages loop

  loop For every message batches
    Client ->> Server: StreamWriteMessage.FromClient.WriteRequest(1,2,3)
    Server ->> Client: WriteResponse.FromServer.WriteResponse(1)
    Client ->> Server: StreamWriteMessage.FromClient.WriteRequest(4,5)
    Client ->> Server: StreamWriteMessage.FromClient.WriteRequest(6)
    Server ->> Client: WriteResponse.FromServer.WriteResponse(2)
    Server ->> Client: WriteResponse.FromServer.WriteResponse(3,4,5)
    Server ->> Client: WriteResponse.FromServer.WriteResponse(6)
    Note right of Client: Write response for messages will be received in order of write requests
Each response message may be ack any number of sent messages
Response messages count may be different from write request count. end Client --> Server: Auth loop, messages may interviave with other loop For update auth token, depends on token expiration time Client ->> Server: StreamWriteMessage.FromClient.UpdateTokenRequest Server ->> Client: StreamWriteMessage.FromServer.UpdateTokenResponse end Client --> Server: Stop working alt normal close from server Server --x Client: Server close grpc stream, client should reconnect else normal close from client Client --x Server: Client close grpc stream else error from server Server ->> Client: Any message with status != SUCCESS Server --x Client: Server close grpc stream Note right of Client: Client may reconnect, it depends on status code. end

Протокол прямой записи сообщений в партицию

Позволяет экономить сеть на внутренних пересылках сообщения внутри кластера. Общая идея: клиент перед подключением дескрайбит топик и узнаёт на какой ноде работает таблетка, обслуживающая нужную партицию и её поколение. Клиент подключается напрямую к ноде с таблеткой и указывает партицию и поколение. Если таблетка переехала - её поколение меняется, клиент получит ошибку, заново подескрайбит топик и снова подключится к правильной ноде.

TODO: описать разбор сообщений и ошибок

Отправка сообщений в транзакции

Ссылки