балансировка нагрузки на стороне клиента gRPC
Я использую gRPC с Python в качестве клиента / сервера внутри модулей kubernetes... Я хотел бы иметь возможность запускать несколько модулей одного типа (серверы gRPC) и позволять клиенту подключаться к ним (случайным образом).
Я отправил 10 стручков сервера и настроил "службу" для их назначения. Затем в клиенте я подключился к DNS-имени службы-это означает, что kubernetes должен выполнить балансировку нагрузки и направить меня на случайный сервер. На самом деле клиент вызывает функции gRPC (который работает хорошо), но когда я смотрю на журналы, я вижу, что все вызовы идут на один и тот же серверный модуль.
Я предполагаю, что клиент делает какое-то кэширование DNS, которое приводит ко всем вызовам, отправляемым на тот же сервер. Это так? В любом случае, чтобы отключить его и установить тот же клиент заглушки, чтобы сделать "новый" вызов и получить новый ip-адрес DNS с каждым вызовом?
Я знаю о накладных расходах, которые я могу вызвать, если он будет запрашивать DNS-сервер каждый раз, но распределение нагрузки сейчас для меня это гораздо важнее.
редактировать
наверное, не проблема кэширования... Может быть, так работает gRPC. HTTP / 2 и постоянное многоразовое соединение. Любой способ "отключить" после каждого звонка?
2 ответов
позвольте мне воспользоваться возможностью ответить, описав, как все должно работать.
способ работы LB на стороне клиента в ядре gRPC C (основа для всех, кроме Java и go flavors или gRPC) выглядит следующим образом (авторитетный документ можно найти здесь):
клиентская сторона LB поддерживается простой и" тупой " специально. Способ, который мы выбрали для реализации сложных политик LB, - через внешний сервер LB (как описано в вышеупомянутом документе). Вы меня не волнует этот сценарий. Вместо этого вы просто создаете канал, который будет использовать (по умолчанию) выбрать- "первый"!--9--> политика LB.
вход в политику LB-это список разрешенных адресов. При использовании DNS, если foo.com решает [10.0.0.1, 10.0.0.2, 10.0.0.3, 10.0.0.4]
политика будет пытаться установить подключение ко всем из них. Первым, кто успешно подключится, станет избранный пока он не отключится. Таким образом, название "pick-first". Более длинное имя могло бы быть "сначала выберите и придерживайтесь его как можно дольше", но это сделало для очень длинного имени файла :). Если / когда выбранная будет отключена, политика выбора сначала перейдет к возвращению следующего успешно подключенного адреса (внутренне называемого "подключенным подканалом"), если таковые имеются. Еще раз, он будет продолжать выбирать этот подключенный подканал до тех пор, пока он остается подключенным. Если все они потерпят неудачу, вызов потерпит неудачу.
проблема здесь в том, что разрешение DNS, будучи внутреннеприсуще тяга основанная, только вызвана 1) на творении канала и 2) на отключении выбранного Соединенного подканала.
на данный момент хакерским решением было бы создать новый канал для каждого запроса (очень неэффективно, но это сделало бы трюк с учетом вашей настройки).
учитывая изменения, поступающие в Q1 2017 (см. https://github.com/grpc/grpc/issues/7818) позволит клиентам выбрать другую политику LB, а именно Round Robin. Кроме того, мы можем посмотрите на введение бита "рандомизации" в эту конфигурацию клиента, который перетасует адреса до выполнения кругового перебора над ними, эффективно достигая того, что вы намереваетесь.
Если вы создали службу vanilla Kubernetes, служба должна иметь свой собственный виртуальный IP-адрес с балансировкой нагрузки (проверьте, если kubectl get svc your-service
показывает CLUSTER-IP
для вашего обслуживания). Если это так, кэширование DNS не должно быть проблемой, потому что один виртуальный IP-адрес должен разделять трафик между фактическими бэкэндами.
попробовать kubectl get endpoints your-service
чтобы подтвердить, что ваша служба действительно знает обо всех ваших бэкэндах.
Если у вас безголовый услуги поиск DNS будет верните запись A с 10 IPs (по одному для каждого из ваших стручков). Если ваш клиент всегда выбирает первый IP-адрес в записи A, это также объясняет поведение, которое вы видите.