Отправка сообщений в YDB Topics на уровне GRPC
Notice
Эта статья - черновик заметок по разработке SDK, может произвольным образом меняться, дополняться и удаляться. Версия НЕ стабильна.
На уровне протокола запись сообщений происходит через двунаправленный GRPC-стрим. Стрим открывается вызовом метода StreamWrite
Простой протокол отправки сообщений
Текстовое описание
- Отправляется сообщение с настройками подключения InitRequest.
- Сервер отправляет подверждение
- Дальше в цикле идёт отправка сообщений и получение подтверждений от сервера. При получении подтверждений сообщения могут быть перегруппированы (при этом гарантируется сохранение порядка)
- Количество сообщений с подтверждениями может отличаться от количества сообщений с отправкой сообщений.
- При подтверждении может не сохраняться исходная группировка сообщений. Одно подтверждение может охватывать сообщения из нескольких сообщений об отправке или наоборот подтверждать только часть сообщений. На стороне клиента подтверждения нужно отслеживать отдельно по каждому сообщению, без учёта их батчевания при отправке.
Схема
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: описать разбор сообщений и ошибок