Search
Write a publication
Pull to refresh

Побег из дата-центра: как мы в авральном порядке переносили сайт в другой дата-центр

Reading time5 min
Views802
Я хочу поделиться с сообществом нашим опытом незапланированного переезда большого проекта. В первую очередь, это будет интересно тем, у кого есть более одного выделенного сервера на проект в одном дата-центре. Здесь нет подробных технических решений, но присутствует некоторый здравый смысл.

Исходные данные

  • В проекте используется 10 серверов, которые стоят в одном дата-центре. Сервера с nginx, PHP, MySQL. Без полноценного почтового сервера и каких-либо других сервисов, достойных упоминания;
  • На сайте больше 3,5 миллионов просмотров страниц в день;
  • Больше 12 миллионов запросов в день к nginx, без учета запросов к изображениям. 1/4 часть от них идет на PHP;
  • Больше 250 Гб трафика в день от nginx, без учета изображений;
  • Предварительные сроки восстановления работы серверов в дата-центре — больше нескольких дней.

В момент сбоя у нас были:
  1. Один резервный сервер;
  2. Настроенная версия сайта. Мы иногда проверяли сайт на резервной копии;
  3. Копии базы данных с помощью репликации MySQL;
  4. Копии файлов. Отставание синхронизации, согласно мониторингу, не превышало 20 минут;
  5. Настроенная SOA запись DNS зоны, позволяющая в течение часа почти для всех пользователей сменить настройки DNS зоны.

Проблемы и решение

После сбоя мы решили двигаться в двух направлениях:
  • восстановить работу сайта на имеющемся сервере только для чтения, кэшируя все и «навечно»;
  • заказать новые сервера в другом дата-центре, чтобы восстановить работу сайта в полном объеме.
Таким образом, пока мы получаем сервера, после сайт не теряет позиции в поисковой выдаче, а посетители могут просматривать содержимое без возможности оставлять комментарии, логиниться и т.п..

Мы предполагали выход из строя основных серверов или несколько серверов сразу. Но думали, что остаться без всех 10 серверов на длительный срок маловероятно. Вот что мы не учли:
  1. Рабочие конфиги резервного сервера не обновлялись так же регулярно, как на главном сервере, хоть все они и хранятся в репозитории. В результате мы получили часть URL с ошибками, и часть страниц не кэшировались;
  2. Кэш. Пустить посетителей на 1-н сервер без кэша вместо 10-ти “смертельно” для него. Особенно в сумме с предыдущим пунктом;
  3. В процессе переключения может оказаться, что и сам проект не совсем готов к режиму «только чтение». Страницы, которые уже есть в кэше, нужно исправлять, а после исправлений разработчиков нужно почистить кэш. Ни в коем случае не соглашайтесь удалять весь кэш, созданный с таким трудом. С каждой минутой все больше пользователей получают новый IP, и количество посетителей на сайте только растет. Чистка кэша час спустя, после смены DNS, положит сервер;
  4. Мы не нашли дата-центр, где можно получить больше одного мощного выделенного сервера за день. Даже при наличии всех резервных копий, вы все равно не сможете оперативно начать восстановление сайта в полном объеме, если не позаботитесь об этом заранее.

Все это можно было сделать заблаговременно, а мы были вынуждены действовать по факту.

По первому пункту для решения анализировали логи и делали правки конфигурационных файлов для режима «только чтение». А именно:
  • Отдавали пользователям культурное сообщение о невозможности авторизоваться;
  • Остановили комментарии и прочие действия на запись на уровне nginx, не пуская пользователей к PHP;
  • Применяли return 503 в необходимых местах, а также error_page 503 = /trouble.html;
  • Также исправили ошибки, чтобы кэшировать все остальные страницы.

По второму и третьему пункту, возникло следующее решение. Сделать так, чтобы наш IP, был в приоритете и каждый запрос вместо 504 ошибки гарантировано создавал страницу в кэше и при необходимости ее обновлял. Не заботясь о производительности nginx, так как нужно было хоть немного оживить сайт, мы использовали Evil If, чтобы для нашего IP кэш генерировался в обход остальных посетителей.

В нашем случае это выглядело так:
fastcgi_pass unix:/var/run/php-fpm/fpm-all.sock;
if ( $remote_addr = 8.8.8.8 ) {
#if ( $remote_addr ~ (8.8.8.8|127.0.0.1) ) { # если необходимо добавить более одного адреса
  fastcgi_pass unix:/var/run/php-fpm/fpm-private.sock;
  # обновления кеша
  #set $nocache 1;
  #fastcgi_cache_bypass $nocache;
}
Вместо 8.8.8.8 подставляем свой IP.

Кроме этого, у нас было два пула PHP-FPM: fpm-private — для нас, fpm-all — для остальных. Для обновления кэша использовали директиву fastcgi_cache_bypass.
Для создания кэша мы запустили wget -r -l0 -np — example.com. Для обновления кэша мы раскомментировали строчки с $nocache. Таким образом, мы получили рабочий сайт для себя с возможностью генерировать кэш и обновлять его при необходимости со своего IP. После нескольких часов работы было уже несколько десятков гигабайт кэша.

Вопроса оптимизации настроек сервера почти не касаемся, подобные темы хорошо описаны в отдельных статьях. В данном случае запросы к базе были только на чтение, так что оптимизация MySQL был проста — база данных не была узким местом. Настройка nginx свелась к корректировке таймаутов и буферов для обработки всех подключений. Была хорошая нагрузка на сеть, так как не было больше дополнительного сервера для отдачи изображений. Слабым местом был PHP. Даже после генерации большого кэша, некоторые страницы генерировались по 20 секунд, так как была очередь в PHP-FPM.

Касательно последнего пункта — поиска новых серверов. Решить этот вопрос оперативно нам не удалось. Дата-центры могли предоставить только сервера с максимальными характеристиками core i3-i7, и ОЗУ 8Гб в течении 1-2 дней, а более мощные сервера нужно было ждать еще дольше, плюс время на заключение договоров и оплату серверов. Мы нашли дата-центра, с которым удалось договориться о получении 4-х мощных серверов для горячего резерва через 3 дня. Сейчас этих серверов достаточно для работы сайта, без пары тяжелых модулей, которые нам не критичны. Теперь мы можем переключиться на работу в другой дата-центр при необходимости.

Вариантом решения проблемы резервных серверов может быть предварительная договоренность с резервным дата-центром о возможном предоставлении дополнительных серверов в случае проблем с основным. Можно поступить еще мудрее и масштабировать сайт более чем на один дата-центр, что мы теперь и сделали.

Итоги

  1. Без резервных копий жить нельзя, проверять их стоит регулярно мониторингом, руками и чем угодно. Тут лишней осторожности не бывает;
  2. Проверка резервного сервера должна быть в полном объеме. В нашем случае не хватало нагрузочного тестирования, опять же потому, что мы не предвидели подобную ситуацию;
  3. Если у вас есть только один резервный сервер, то настройте его сразу так, чтобы он работал хоть в ограниченном режиме при реальной нагрузке;
  4. Найдите время, чтобы с командой проекта или архитектором и администраторами смоделировать самую маловероятную ситуацию — взрыв, пожар, другие обстоятельства в дата-центре, когда вы в один момент лишаетесь доступа к серверам. Разбор, а в результате и документирование такого случая, а также подготовка конфигурационных файлов с тестированием их работы позволит исправить большинство вероятных сбоев. Тогда если за вашими серверами прилетит НЛО, вы не будете говорить, что не ожидали такого, и сможете восстановить работу проекта:);
  5. В нашем случае сайт был полностью недоступен чуть более часа. Еще несколько часов были перебои в работе. Подготовка к подобной ситуации позволила бы потратить час, пока обновлялись DNS записи, на генерацию кэша, чтобы встретить первых посетителей, и в дальнейшем, не ложиться намертво под нагрузкой.

В нашем случае дата-центр восстановил работу чуть больше чем через сутки. Учитывая, что мы работали в режиме «только чтение», никаких данных обратно переносить не пришлось. После проверки серверов, мы перевели домен обратно.

Надеюсь, мой опыт пригодится вам в трудную минуту, когда вы на неопределенный срок лишитесь доступа к серверам, при чем у вас будут бекапы, но не будет резервного кластера в другом дата-центре. Буду рад если в комментариях поделитесь, как бы вы действовали в такой ситуации?
Tags:
Hubs:
Total votes 3: ↑2 and ↓1+1
Comments5

Articles