Failover и доступность

Доступность любого приложения зависит от работоспособности его компонент. Обеспечение доступности приложения — это обеспечение доступности компонент. На физическом уровне — это снижение зависимости работы приложения от поломок серверов.

Рано или поздно сервер сломается, каким бы надежным он ни был. Риск выхода из строя железа решается только посредством избыточности. Т.е. тогда, когда каждый узел имеет резервную копию. И в случае выхода их строя основного сервера, резервный может взять на себя работу основного. По-другому это и называется failover.

Избыточность

Главный принцип обеспечения отказоустойчивости — это избегать числа 1 (SPOF). Любой компонент должен быть зарезервирован. Это принцип избыточности.

Резервные компоненты должны повторять конфигурацию основных (количество оперативной памяти, мощность процессора и т.п.). Два сервера послабее лучше одного помощнее, т.к. вероятность выхода из строя двух серверов одновременно намного ниже, чем одного.

Существует несколько простых подходов по резервированию основных компонент Web приложения:

  • DNS
  • Фронтенды
  • Бекенды
  • Базы данных

1. DNS

Обычно для одного домена указывается несколько NS записей:

ruhighload.com. 172800 IN NS ns1.dnsimple.com.
ruhighload.com. 172800 IN NS ns2.dnsimple.com.

В случае, если один из NS серверов выходит из строя, запросы обрабатывают другие.

Это и позволяет обеспечить высокий уровень доступности для обслуживания запросов к DNS. Убедитесь, что Ваш домен имеет несколько NS записей:

dig ns ruhighload.com

2. Фронтенды

Фронтенд — это сервер, который получает запросы от клиентов и отправляет им ответ. Выход из строя такого сервера приводит к недоступности всего Web приложения.

Резервирование фронтендов удобно реализовывать с помощью виртуальных IP адресов UCARP. Тогда один из двух идентичных серверов получает виртуальный IP, к которому привязан домен. При выходе из строя текущего сервера, этот IP адрес назначается резервному серверу.

Отслеживание состояния и переключение IP адреса следует автоматизировать. Можно каждую секунду опрашивать основной сервер на корректность работы (т.н. heartbeat). В случае, если корректный ответ не был получен, переназначать IP адрес на резервный фронтенд:

<?
while (true)
{
	# IP адрес фронтенда
	$c = curl_init('http://10.10.10.1/heartbeat.html');
	curl_setopt(CURLOPT_RETURNTRANSFER, true);
	$html = curl_exec($c);

	# что-то пошло не так, нужно менять IP
	if ( $html != 'ok' )
	{
		# Назначение виртуального IP второму фронтенду
		exec('kill ucarp');
		sleep(1);
	}
}

# Проверка heartbeat.html (содержит слово "ок") каждую секунду

Более низкий уровень мониторинга (доступность сервера) UCARP реализует самостоятельно.

3. Бекенды

Бекенды — это сервера, на которых работает основное приложение (например, PHP). Они обычно абсолютно идентичны. Это позволяет использовать активное резервирование. Т.е. все бекенды обрабатывает запросы, нет резервных серверов. Если один из бекендов выходит из строя, он просто исключается из общего списка, и на него перестают приходить запросы от фронтенда.

Однако, при отключении одного из серверов, повысится нагрузка на остальные. Количество бекендов лучше рассчитывать исходя из того, что в любой момент может выйти из строя 25% их общего количества.

Nginx позволяет указать несколько серверов для обработки fastcgi запросов с помощью upstream:

upstream backend {
        server 10.10.0.5;
        server 10.10.0.6;
        server 10.10.0.7;
}

server {
	location ~* \.(php)$ {
        fastcgi_pass backend;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }
}

Запросы будут автоматически распределяться между указанными серверами.

Кроме этого, Ngxinx будет в реальном времени анализировать ошибки в ответах от бекендов. В случае обнаружения ошибки, он перестанет отправлять запросы на сломанный бекенд. Время и количество попыток можно настроить:

upstream backend {
        server 10.10.0.5 fail_timeout=360s max_fails=2;
        server 10.10.0.6 fail_timeout=360s max_fails=2;
        server 10.10.0.7 fail_timeout=360s max_fails=2;
    }

# в случае 2х неуспешных запросов, Nginx исключит сервер из пула на 360 секунд

max_fails определяет количество ошибок, полученных от бекенда, а fail_timeout — время, на которое бекенд будет исключен из пула.

4. Базы данных

Резервирование баз данных — самая сложная задача. Для обеспечения отказоустойчивости часто используют Master-Slave репликацию. Следует отметить, что реплика в этом случае работает в пассивном режиме. Т.е. никаких запросов от приложения она не обрабатывает, а служит только для хранения актуальной копии данных с мастера.

Удобно автоматизировать отслеживание состояния баз данных. В случае обнаружения ошибки, настройки в приложении автоматически изменяются на сервер реплики:

<?
$master = include 'config/db/master.php';
$master_replica = include 'config/db/replica.php';

# Проверяем выполнение запроса на мастере
mysql_connect($master);
mysql_query('SELECT NOW()');

# Произошла ошибка
if ( mysql_errno() )
{
	$config = "<? return '{$master_replica}';";
	file_put_contents('config/db/master.php', $config);
}

# Перезаписываем файл настроек с адресом Мастера в случае ошибки

Процесс восстановления сломанного сервера будет таким:

  1. Сломанный сервер отключается от любых операций и чинится.
  2. После восстановление, на нем настраивается репликация с работающего сервера.
  3. После настройки репликации и ее синхронизации, в приложение добавляется конфигурация этого сервера (в нашем примере мы бы добавили его адрес в файл "config/db/replica.php").

Настройку слейва с работающего мастера можно выполнить с помощь утилиты Xtrabackup.

После этого, бывший слейв становится основным (т.е. Мастером), а восстановленный сервер становится резервным (т.е. Слейвом).

Самое важное

Любой сервер когда-то сломается. Избегайте узлов, которые работают в единственном экземпляре. Отдавайте предпочтение менее мощным серверам, но большему их количеству.

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


Подпишитесь на Хайлоад с помощью Google аккаунта
или закройте эту хрень