Мы запускаем веб-приложение, обслуживающее веб-API для все большего числа клиентов. Для начала клиенты, как правило, были домашними, офисными или другими беспроводными сетями, которые отправляли фрагментированные HTTP-загрузки в наш API. Теперь мы расширились, чтобы обслуживать больше мобильных клиентов. Файлы размером от нескольких тысяч до нескольких гигабайт, разбиты на более мелкие части и повторно собраны с помощью нашего API.
Наша текущая балансировка нагрузки выполняется на двух уровнях: сначала мы используем циклический DNS для объявления нескольких записей A для нашего адреса api.company.com. На каждом IP мы размещаем Linux LVS: http://www.linuxvirtualserver.org/, балансировщик нагрузки, который смотрит на исходный IP-адрес запроса, чтобы определить, к какому серверу API передать соединение. Эти LVS-боксы настроены с тактовым сигналом для перехвата внешних VIP-адресов и IP-адресов внутренних шлюзов друг от друга.
В последнее время мы видели два новых состояния ошибки.
Первая ошибка - это когда клиенты колеблются или переходят с одного LVS на другой в середине загрузки. Это, в свою очередь, приводит к тому, что наши балансировщики нагрузки теряют отслеживание постоянного соединения и отправляют трафик на новый сервер API, тем самым прерывая загрузку фрагментов между двумя или более серверами. Мы стремились к тому, чтобы значение TTL Round Robin DNS для нашего api.company.com (которое мы установили на 1 час) учитывались нижестоящими кэширующими серверами имен, уровнями кэширования ОС и уровнями клиентских приложений. Эта ошибка возникает примерно для 15% наших загрузок.
Вторую ошибку мы встречаем гораздо реже. Клиент будет инициировать трафик к LVS-серверу и будет перенаправлен на реальный сервер A за ним. После этого клиент войдет через новый IP-адрес источника, который блок LVS не распознает, тем самым направляя текущий трафик на реальный сервер B, также находящийся за этим LVS.
Учитывая нашу архитектуру, как описано в части выше, я хотел бы знать, как люди сталкиваются с лучшим подходом, который позволит нам более изящно обрабатывать каждый из указанных выше случаев ошибок?
Изменить 5/3/2010:
Похоже, это то, что нам нужно. Взвешенное хеширование GSLB на исходном IP-адресе.
Каноническое решение этой проблемы - не полагаться на IP-адрес конечного пользователя, а вместо этого использовать балансировщик нагрузки уровня 7 (HTTP / HTTPS) с «закрепленными сеансами» через cookie.
Прикрепленные сеансы означают, что балансировщик нагрузки всегда будет направлять данного клиента на один и тот же внутренний сервер. Через cookie означает, что балансировщик нагрузки (который сам по себе является полнофункциональным HTTP-устройством) вставляет cookie (который балансировщик нагрузки создает и управляет автоматически), чтобы запомнить, какой внутренний сервер следует использовать для данного HTTP-соединения.
Основным недостатком липких сессий является то, что загрузка сервера в конце может стать несколько неравномерной. Балансировщик нагрузки может справедливо распределять нагрузку только при создании новых подключений, но, учитывая, что существующие подключения могут быть долгоживущими в вашем сценарии, тогда в некоторые периоды времени нагрузка не будет распределяться полностью справедливо.
Практически каждый балансировщик нагрузки уровня 7 должен уметь это делать. В Unix / Linux распространенными примерами являются nginx, HAProxy, Apsis Pound, Apache 2.2 с mod_proxy и многие другие. В Windows 2008+ есть маршрутизация запросов приложений Microsoft. В качестве бытовой техники Coyote Point, loadbalancer.org, Kemp и Barracuda распространены в области low-end; и F5, Citrix NetScaler и другие в high-end.
Вилли Тарро, автор HAProxy, имеет хороший обзор методов балансировки нагрузки здесь.
О циклическом переборе DNS:
Мы стремились к тому, чтобы значение TTL Round Robin DNS для нашего api.company.com (которое мы установили на 1 час) учитывались нижестоящими кэширующими серверами имен, уровнями кэширования ОС и уровнями клиентских приложений.
Это не будет. И DNS Round Robin не подходит для балансировки нагрузки. И если вас ничто другое не убеждает, имейте в виду, что современные клиенты могут предпочесть один хост всем другим из-за самого длинного совпадения префикса закрепление, поэтому, если мобильный клиент меняет IP-адрес, он может переключиться на другой хост RR.
В принципе, это нормально использовать циклический перебор DNS в качестве крупномасштабного распределения нагрузки, указывая 2 или более записей RR на высокодоступные IP-адреса, обрабатываемые реальными балансировщиками нагрузки в активном / пассивном или активном / активном HA. И если это то, что вы делаете, то вы также можете обслуживать эти записи DNS RR с длинными значениями времени жизни, поскольку связанные IP-адреса уже являются высокодоступными.
Чтобы ответить на ваш вопрос об альтернативах: вы можете получить надежную балансировку нагрузки на уровне 7 с помощью HAProxy.
Что касается исправления проблем сродства LVS, я немного сух по твердым идеям. Это может быть просто тайм-аут или переполнение. Некоторые мобильные клиенты будут переключать IP-адреса, когда они подключены к сети; может это может быть источником ваших бед? Я бы посоветовал, по крайней мере, распространить степень детализации сходства как минимум на класс C.