# #go #grpc #google-cloud-bigtable
#Вперед #grpc #google-облако-bigtable
Вопрос:
У меня есть сервисы golang с постоянным клиентом Bigtable. Службы выполняют сотни операций чтения / записи на Bigtable в секунду.
Каждые часы после загрузки службы я сталкиваюсь с сотнями ошибок, подобных этой:
Retryable error: rpc error: code = Unavailable desc =
the connection is draining, retrying in 74.49241ms
За ошибкой следует увеличенное время обработки, которое я не могу допустить при возникновении этих ошибок.
Мне удалось выяснить, что клиент Bigtable использует пул соединений gRPC.
Похоже, что у сервера Bigtable gRPC максимальное время подключения составляет 1 час, что может объяснить указанную выше ошибку и увеличение времени обработки при повторном подключении.
Предполагается, что конфигурация maxAgeGrace дает дополнительное время для завершения текущих операций и позволяет избежать одновременного завершения всех подключений к пулу.
Я увеличил размер пула соединений с 4 до 12 по умолчанию без какой-либо реальной выгоды
Как мне предотвратить увеличение времени обработки при повторных подключениях и возникновение этих ошибок, учитывая, что мой трафик будет продолжать расти?
Ответ №1:
Облачные клиенты bigtable используют пул соединений gRPC для подключения к bigtable. Java-клиент использует пул каналов для каждого соединения HBase, каждый пул каналов имеет несколько соединений gRPC. Соединения gRPC отключаются каждый час (или после 15 минут бездействия), и базовая инфраструктура gRPC выполняет повторное подключение. Первый запрос при каждом новом соединении выполняет ряд задач настройки, таких как подтверждение связи TLS и прогревание кэшей на стороне сервера. Эти операции довольно дороги и могут вызвать всплески задержки.
Bigtable спроектирована как система с высокой пропускной способностью, и амортизированная стоимость этих повторных подключений при постоянном объеме запросов должна быть незначительной. Однако, если клиентское приложение имеет очень низкий QPS или длительные периоды простоя между запросами и не может переносить эти всплески задержки, оно может создавать новое соединение Hbase (java) или новый клиент CBT (golang) каждые 30-40 минут и не запускать вызовы op (существующие на клиенте hbase или считывающие небольшую строку) на новом соединении / клиенте для запуска базовых соединений gRPC (один вызов на соединение, поскольку hbase по умолчанию вдвое превышает количество процессоров, go по умолчанию имеет 4 соединения). После загрузки вы можете заменить новое соединение / клиент для основных операций в клиентском приложении. Вот пример кода go для этого обходного пути.
Комментарии:
1. Связанный вами обходной код использует концепцию «вращающейся таблицы» и отмечает, что «Для новой ссылки на таблицу потребуется, чтобы через нее проходило несколько запросов для установления каждого соединения в пуле соединений». Означает ли это, что при настройке нового клиента Bigtable каждая таблица, открытая в клиентском приложении, должна быть перенасыщена? Или новый клиент Bigtable может просто использовать одну таблицу для загрузки базовых соединений gRPC?
Ответ №2:
Я подозреваю, что это может быть связано с ошибкой, появившейся в недавнем выпуске grpc-go и только что исправленной. По сути, вместо повторного подключения сразу после разрыва соединения мы неправильно ждем 1 секунду перед повторным подключением. Пожалуйста, повторите попытку с помощью grpc-go master head. Спасибо!