Go SDK для YDB: как сократить число запросов к СУБД в интерактивных транзакциях

Команда Алисы совместно с разработчиками YDB оптимизировала Go SDK, объединив команды начала транзакции и первого запроса. Это позволяет сократить сетевой трафик и ускорить выполнение интерактивных транзакций в распределённой СУБД.

Go SDK для YDB: как сократить число запросов к СУБД в интерактивных транзакциях

Разработчики, работающие с распределённой СУБД YDB от Яндекса, получили возможность заметно сократить количество сетевых запросов при выполнении интерактивных транзакций. Это стало возможным благодаря рефакторингу Go SDK, в котором по умолчанию теперь используется новый Query Service. Степан Пестерников, разработчик из команды Алисы, рассказал, как совместно с коллегами из YDB удалось объединить команду начала транзакции и выполнения первого запроса, что уменьшило задержки и нагрузку на сеть.

Интерактивные транзакции — это когда клиентское приложение само управляет жизненным циклом транзакции: начинает её, выполняет серию запросов и завершает. В такой модели каждый шаг требует отдельного сетевого вызова к СУБД. Раньше для начала транзакции SDK отправлял отдельную команду, а затем уже первый запрос. Теперь эти две операции можно объединить в одну, что особенно важно для высоконагруженных сервисов вроде Алисы, где каждая миллисекунда на счету.

Объединение начала транзакции и первого запроса в Go SDK

Суть оптимизации заключается в том, что в новом Query Service появилась возможность передать параметры начала транзакции вместе с первым запросом. Вместо двух отдельных команд — BeginTransaction и ExecuteQuery — SDK отправляет одну команду, которая одновременно создаёт транзакцию и выполняет первый запрос. Это уменьшает количество сетевых round-trip'ов в два раза на старте транзакции.

В коде это выглядит довольно просто. Вместо того чтобы сначала вызывать метод для начала транзакции, а затем отдельно выполнять запрос, разработчик может использовать специальный флаг или параметр, который указывает SDK начать транзакцию непосредственно перед выполнением первого запроса. Например, в Go SDK для YDB появился метод, который принимает настройки транзакции и сразу выполняет запрос, создавая транзакцию неявно.

Степан отмечает, что фрагменты кода получились небольшими и их легко адаптировать под свои задачи. Главное — понимать, что теперь не нужно вручную вызывать BeginTransaction, если первый запрос может быть выполнен в рамках новой транзакции. Это упрощает код и снижает вероятность ошибок.

Предыстория и контекст: почему это важно для разработчиков

YDB — это распределённая отказоустойчивая СУБД, которая используется в Яндексе для хранения данных множества сервисов, включая Алису. Клиентские SDK устанавливают gRPC-подключения к кластеру YDB, и каждый запрос проходит по сети. В высоконагруженных системах даже небольшое сокращение количества запросов может существенно снизить нагрузку на сеть и уменьшить задержки.

Раньше в YDB использовался более старый API, который требовал явного разделения команд. С появлением Query Service появилась возможность более гибко управлять транзакциями, и разработчики YDB провели большой рефакторинг Go SDK, чтобы использовать новые возможности. Степан воспользовался этим, чтобы оптимизировать взаимодействие Алисы с базой данных.

Интересно, что подобные оптимизации уже давно применяются в других СУБД, например, в PostgreSQL и MySQL, где можно объединять команды в один сетевой пакет. Теперь и YDB предоставляет такую возможность для Go-разработчиков.

Как это работает: технические детали

Чтобы понять, как работает объединение команд, нужно немного углубиться в устройство gRPC и протокола YDB. gRPC — это фреймворк для удалённого вызова процедур, который использует Protocol Buffers для сериализации данных. Каждая команда к YDB — это отдельный gRPC-вызов. Когда SDK отправляет команду начала транзакции, он создаёт gRPC-запрос, который обрабатывается сервером, и возвращается ответ с идентификатором транзакции. Затем SDK отправляет следующий запрос, уже с этим идентификатором.

Новый Query Service позволяет передать параметры транзакции (например, режим изоляции) непосредственно в запросе первого выполнения. Сервер сам создаёт транзакцию и возвращает её идентификатор вместе с результатами первого запроса. Это сокращает количество gRPC-вызовов и, соответственно, уменьшает сетевые задержки.

В Go SDK для этого используется специальный метод, который принимает контекст, настройки транзакции и функцию, выполняющую запросы. Если транзакция ещё не начата, SDK автоматически начинает её перед выполнением первого запроса. Это удобно, так как разработчику не нужно думать о том, как правильно начать транзакцию — SDK делает это автоматически.

Кого затронет и как это отразится на работе

В первую очередь эта оптимизация полезна разработчикам, которые используют Go SDK для работы с YDB в высоконагруженных сервисах. Сокращение количества сетевых запросов снижает нагрузку на сеть и уменьшает задержки, что критично для систем реального времени, таких как голосовые помощники, платёжные системы и другие.

Для бизнеса это означает более быстрый отклик сервисов и, как следствие, лучшее пользовательское впечатление. Для разработчиков — упрощение кода и меньше ошибок, связанных с управлением транзакциями.

В России и СНГ YDB активно используется как в крупных компаниях, так и в стартапах. Поэтому оптимизация Go SDK будет полезна многим командам, которые строят свои продукты на этой СУБД.

Что будет дальше

Разработчики YDB продолжают развивать Go SDK, и в будущих релизах можно ожидать дальнейших улучшений. Возможно, появятся новые методы для объединения не только начала транзакции и первого запроса, но и других команд, например, завершения транзакции с последним запросом.

Степан также отмечает, что аналогичные оптимизации могут быть реализованы в SDK для других языков, таких как Python, Java и C++. Так что разработчикам на других языках стоит следить за обновлениями.

Итог

Оптимизация Go SDK для YDB, позволяющая объединять начало транзакции и первый запрос, — это значимый шаг в улучшении производительности распределённых приложений. Разработчики, использующие YDB, теперь могут сократить количество сетевых запросов и ускорить выполнение интерактивных транзакций без изменения логики приложения. Это особенно актуально для высоконагруженных сервисов, где важна каждая миллисекунда. Следите за обновлениями Go SDK и внедряйте новые возможности в свои проекты.