Плавный переезд

:

После того, как мне попались на глаза рассказы о переезде информационной инфраструктуры компании с места на место, я подумал, что переезд среднего контентного интернет-проекта с одной площадки на другую — тоже довольно интересная тема. Особенно интересно то, как сделать это с минимальными перебоями в работе.

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

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

Рассказ рассчитан на подготовленную аудиторию и не является точным пошаговым руководством к действию.


Итак, имеется типичный «джентельменский набор»:
  • Nginx — фронтенд сервер, за ним Apache или FastCGI
  • Сервер базы данных — MySQL
  • Сервера в новом датацентре — достойная замена серверам текущего хостера, который уже испытал ваше терпение до последнего предела

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

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

Таким образом, простой сервиса при переносе можно сократить по крайней мере до времени создания дампа базы. Хорошо если сервер базы уже настроен для репликации, если нет, придётся сделать и это.

Весь процесс делится на две части: первая — создание актуальной копии ресурса на новой площадке, вторая — плавное перенаправление трафика, обусловленное постеменным обновлением кеширующих DNS-серверов.


Код, шаблоны и прочее в хорошем случае переносятся простым действием: svn co svn://my.repository.ru/myproject/trunk .
Итак, нужно открыть два соединения с рабочим сервером базы данных, в одной консоли написать flush tables with read lock, в другой запустить mysqldump c нужными параметрами. Этот момент и подразумевается моментом простоя, так как скорее всего в это время ваш проект может работать некорректно в силу read-блокировки(только чтение) всех таблиц, вероятно, на это время вам придётся повесить «заглушку» (bonnie создаёт полный дамп суперхабра примерно за 58 секунд). После того, как копия базы будет готова, в первой консоли пишем show master status и запоминаем полученные значения (текущее имя файла бинарного лога и позиция в нём) в какое-нибудь безопасное место. Затем просто закрываем консоль, что снимает блокировку таблиц или выполняем unlock tables.

Полученный файл архивируем и переносим на новую площадку. Там, на новом, ещё пахнущим заводом серверов, сервере, создаём базу и восстанавливаем в неё данные. Затем делаем из этого сервера клиента репликации базы со старой площадки и инициализируем репликацию с полученного ранее места: change master to master_log_file='server1-relay-bin.00025', master_log_pos=350384183; start slave;

Если вы знакомы с репликацией и всё сделали правильно, то через несколько минут у вас будет «живая» актуальная копия базы на новом месте. В большинстве случаев трафик между разными площадками передаётся с достаточной скоростью, чтобы все «пишушие» запросы успели попасть от сервера к серверу без очередей и задержек.

Примечание: этот пункт можно опустить чем полностью исключить перебой в работе, если у вас уже есть слейв-сервер, который вы можете перенести на новое место.


Пользовательские файлы очень удобно перемещаются с помощью rsync (man rsync). При начальной подготовке можно скопировать полный набор хранилища, а во время запуска запустить синхронизацию снова, для того, чтобы синхронизировать изменения: обновить изменившиеся файлы и перенести новые.
Теперь решающий и самый интересный момент. Когда у вас уже есть две работающие копии проекта, прежде чем вносить изменения в DNS, нужно «замкнуть» одну площадку на другую. Сделать это можно при помощи родных возможносней nginx, а именно: его проксирующего модуля. То есть попросту осуществить проксирование всех запросов на новый сервер через старый(снова дурацкая тавтология, когда же конец?): proxy_pass httр://new.server.ip:80/.

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

Как только вы почувствуете, что старые сервера более не нужены, можно отключить или перенастроить репликацию так, как вам нужно и заявить старому хостеру о том, что более он от вас не получит ни рубля.