Допустим, я арендую 6 выделенных серверов у поставщика серверов для своего сайта. http://example.com:
# 1: 203.2.113.1
# 2: 203.2.113.2
# 3: 203.2.113.3
...
# 6: 203.2.113.6
каждая из них имеет максимальную скорость загрузки 10 МБ / с.
Я решил использовать машину №1 в качестве балансировщика нагрузки, поэтому моим регистратором я установил запись DNS «A»: example.com A 203.2.113.1
.
Два случая:
50 клиентов хотят получать от моего сервиса видеопоток со скоростью 200 Кб / с при этом: вроде все нормально:
Они соединяются http://example.com в их браузере DNS дает им IP-адрес 203.2.113.1, их браузер делает HTTP-запрос на этот IP-адрес, балансировщик нагрузки (машина №1) получает HTTP-запрос, передает задачу машине №2, №3, .. ., # 6, и эти машины отправляют поток клиенту, передавая сначала данные через балансировщик нагрузки. Правильно ли я, что клиент не принял ответ от 203.2.113.2, потому что его запрос был отправлен на 203.2.113.1?
200 клиентов хотят получать видеопоток со скоростью 200 КБ / с от моего сервиса: это не работает:
Клиенты подключаются http://example.com в их браузере DNS дает им IP-адрес 203.2.113.1, их браузер делает HTTP-запрос на этот IP-адрес, балансировщик нагрузки (машина №1) получает HTTP-запрос, передает задачу машине №2, №3, .. ., №6. Каждая из этих 5 машин обрабатывает 1/5 из 200 клиентов, то есть 40 клиентов * 200 КБ / с = 8 МБ / с.
Если # 2, # 3, ..., # 6 могут отправить данные напрямую клиентам, было бы хорошо (8 МБ / с).
Но поскольку данные должны проходить через машину балансировки нагрузки №1, это не работает, потому что машина №1 не может выгружать со скоростью 40 МБ / с.
Как настроить балансировщик нагрузки (машина №1) для решения этой проблемы?
Или возможно, что балансировщик нагрузки передает запросы машинам №2, №3, ..., №6, а затем они отвечают клиентам. прямо, не проходя через машину №1 для ответов?
Или возможно, что балансировщик нагрузки передает запросы машинам №2, №3, ..., №6, а затем они отвечают клиентам напрямую, не проходя через машину №1 для ответов?
Да, это называется балансировкой нагрузки «Прямой возврат», и любой приличный балансировщик нагрузки L4 сможет это сделать.
Вы уверены, что что-то вроде http://www.haproxy.org/ не сможет обрабатывать трафик от 200+ клиентов? Прочтите это, например: http://www.haproxy.org/#perf .
Фактически все, что ему нужно сделать, это направить трафик TCP / IP на конкретную машину и обратно. С точки зрения ЦП это не очень дорого, за исключением действительно огромного количества подключений. Меня больше беспокоит емкость сетевого контроллера, и вам также нужно помнить о таких вещах, как максимальное количество открытых файлов и т. Д., Которые могут негативно повлиять на обработку сетевого трафика. Похоже, что тщательная настройка сетевого стека важнее мощности HAProxy:
Все эти микрооптимизации приводят к очень низкой загрузке ЦП даже при умеренных нагрузках. И даже при очень высоких нагрузках, когда ЦП перегружен, довольно часто встречаются такие цифры, как 5% пользователей и 95% системы, что означает, что процесс HAProxy потребляет примерно в 20 раз меньше, чем его системный аналог. Это объясняет, почему настройка операционной системы очень важна.
Единственная машина, работающая в качестве балансировщика нагрузки, является узким местом. Ты должен посмотреть на Циклический DNS (вторая ссылка) aka DNS Load Balancing. Это не очень надежно, ваши машины не будут загружены равномерно, но каждая машина должна получить определенную нагрузку.
Вы захотите проверить это, чтобы убедиться, что это работает, с помощью службы тестирования распределенной нагрузки. Ключевым моментом является то, что клиент регулярно ищет DNS для вашего домена.
Вы также должны посмотреть на кеширование потока. CloudFlare предлагает услугу, как я и ожидал от других, но я ею не пользовался, поэтому мало о ней знаю.
Я только что нашел потенциальные решения этой проблемы, вот как это происходит:
Браузер клиента подключается к example.com
, т.е. после разрешения DNS, на сервер №1 (203.2.113.1)
Сервер №1 смотрит, какая из машин №2, №3, ..., №6 доступна, скажем, №5 имеет наименьшую нагрузку на данный момент и может выполнять эту работу.
Сервер №1 отправляет клиенту HTTP-ответ: yourworker=203.2.113.5
или yourworker=worker5.example.com
Клиент получает это и знает теперь он должен подключиться 203.2.113.5
или worker5.example.com
(через AJAX / XMLHttpRequest) для получения видеопотока.
Таким образом, видеотрафик никогда не проходит через балансировщик нагрузки машина №1, которая отправляет всего несколько байтов (yourworker=...
) для каждого клиента в начале, то есть больше нет узких мест.
Единственная потенциальная проблема: если браузер загрузил страницу http://example.com от 203.2.113.1, может ли он выполнять AJAX / XHR до 203.2.113.5 или worker5.example.com
для получения видеопотока, или он будет отклонен как CORS?
Изменить: протестировано, работает. Работает, если включить Access-Control-Allow-Origin
, пример с Apache .htaccess
(можно поставить более точный контроль, но здесь для теста это нормально):
Header set Access-Control-Allow-Origin "*"
Другое более простое решение: не может балансировщик нагрузки №1 просто проанализировать, какая машина №2, №3, ..., №6 доступна, и отправить это взамен клиенту:
<?php
$i = which_worker_available();
header('Location: https://worker' . $i . '.example.com/');
?>
?
затем весь остальной трафик никогда больше не будет проходить через балансировщик нагрузки. Больше никаких узких мест.
Проблема здесь: URL-адрес, отображаемый в браузере клиента, изменится с https://example.com к https://worker5.example.com что не очень приятно для конечного пользователя.
Изменить: протестировано, работает (но действительно URL-адрес в строке браузера изменяется с http://example.com к http://worker5.example.com/ ...)