Создание резервных копий сайтов и синхронизация баз данных между разными хостингами

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

Рис.1. Репликация баз данных и ее настройка.
Рис.1. Репликация баз данных и ее настройка.

Вы узнаете, как настроить автоматическую синхронизацию данных между основным и резервным серверами, используя Cloudflare и PHP. И сможете воспользоваться готовым скриптом, который мы разработали для решения этой задачи.

Проблема

Клиент обратился к нам в Ant-Team.ru с задачей, касающейся шести ресурсов на WordPress. Это были новостные издания, посвященные спортивным событиям. Сообщения об их недоступности приходили регулярно, сайты не работали и теряли пользователей. Необходимость изменений стала очевидной: клиент хотел обеспечить доступность ресурсов даже при падении основного хостинга.

Логичное решение — использовать балансировщики нагрузки (собственные или готовые). В данном случае мы решили обратиться к Cloudflare.

Балансировку настроили, однако даже с настроенным автоматическим переключением оставалась задача синхронизации данных: код сайтов остается прежним, но контент постоянно обновляется. Чтобы пользователи всегда видели актуальную информацию, нужно поддерживать идентичность данных на хостингах.

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

Репликация данных через бэкапы

Для решения задачи разработали скрипт, который действует следующим образом:

  • На Хостинге 1 (Master) раз в час создается бэкап базы данных.
  • Этот бэкап отправляется на Хостинг 2 (Slave), где база данных восстанавливается.
  • Каждый час происходит сравнение данных, и если на Master было изменение, то на Slave база обновляется.

Автоматизация процесса

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

Преимущества

  • Высокая доступность: сайты работают даже при сбоях хостинга.
  • Автоматическая синхронизация: избегаете потерь данных и рассинхронизации.
  • Минимальное время простоя: пользователи не заметят проблем с доступом к сайтам.

Теперь давайте подробнее рассмотрим, как все это настроить.

Дублирование сайтов

Дублирование сайтов осуществляется следующим образом:

  1. На новом хостинге добавляете новый домен (он нужен, чтобы запустить сайты) и создаете поддомены для каждого сайта. В нашем случае 6 поддоменов, так как у нас 6 сайтов.
  2. Каждому сайту с поддоменом присваиваете оригинальный домен. Обратите внимание, что SSL-сертификаты не создаются через хостинг, а будут получены через Cloudflare.

Настройка Cloudflare

Создайте аккаунт Cloudflare для каждого из своих сайтов. Настройка будет одинаковой для всех. Чтобы не утонуть в подробностях, покажу только основные шаги, из которых будет понятно, как это сделать.

  • В разделе Websites добавьте ваш домен, нажав на кнопку Add a domain.
Рис.2. Добавление домена.
Рис.2. Добавление домена.
  • Перейдите в меню DNS и пропишите NS-серверы, которые выдал Cloudflare, у регистратора домена.
  • Добавьте по две A-записи для каждого IP от ваших двух хостингов (для домена и www). Убедитесь, что Proxy status установлен на Proxied.

Настройка балансировщика нагрузки

  • Перейдите в раздел Traffic — Load Balancing.
Рис.3. Load Balancing.
Рис.3. Load Balancing.
  • Нажмите Manage Monitors — Create и добавьте IP для первого хостинга.
Рис.4. Добавление IP.
Рис.4. Добавление IP.
  • Создайте новый балансировщик, нажав Create Load Balancer.
Рис.5. Создание нового балансировщика.
Рис.5. Создание нового балансировщика.
  • Укажите свой домен, выберите оба пула и добавьте их в таблицу.
Рис.6. Указание домена.
Рис.6. Указание домена.
Рис.7. Завершение настройки балансировщика.
Рис.7. Завершение настройки балансировщика.

Обязательно протестируйте переключение на резервный хостинг и не забудьте после этого вернуть все обратно.

Создание системы бэкапов Master-Slave на PHP

Теперь перейдем к важной части — как задублировать данные с помощью системы Master-Slave.

Почему стоит использовать систему Master-Slave?

  • Автоматизация: не придется вручную переживать за бэкапы — все происходит по расписанию.
  • Отказоустойчивость: если ваш Master-сервер решит взять выходной, Slave всегда наготове.
  • Масштабируемость: легко добавлять новые сайты или базы данных в систему.
  • Минимизация риска потерь: благодаря регулярной синхронизации вы защищены от потери данных.

Общий функционал системы Master-Slave

На стороне Master (описанной ранее) создается резервная копия базы данных, она архивируется и передается на Slave-серверы для последующего восстановления. На стороне Slave реализован прием архивов с бэкапами и их разархивирование, после чего данные из бэкапа восстанавливаются в базу данных.

Шаг 1: Настройка Master-сервера

На Master-сервере:

  1. Создание бэкапа базы данных: используйте mysqldump, чтобы вытащить данные в файл.
  2. Архивирование: ZIP-архив, чтобы сохранить все в целости.
  3. Передача бэкапа на Slave: отправьте архив с помощью cURL.

Пример кода на PHP для Master:

// Создаем бэкап базы данных $backupFile = '/path/to/backup.sql'; exec("mysqldump --user={$dbUser} --password={$dbPass} --host={$dbHost} {$dbName} > {$backupFile}"); // Архивируем $zip = new ZipArchive(); $zipFile = '/path/to/backup.zip'; if ($zip->open($zipFile, ZipArchive::CREATE) === TRUE) { $zip->addFile($backupFile, 'backup.sql'); $zip->close(); } // Отправляем архив на Slave $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "http://slave-server/backup-receive", CURLOPT_POST => true, CURLOPT_POSTFIELDS => [ 'file' => new CURLFile($zipFile) ], CURLOPT_RETURNTRANSFER => true ]); $response = curl_exec($curl); curl_close($curl); echo "Ответ от Slave: $response";

Этот код создает резервную копию базы данных и отправляет её на сервер:

  1. Создание бэкапа — с помощью команды mysqldump выполняется экспорт базы данных в SQL-файл.
  2. Архивирование — создается ZIP-архив, в который добавляется SQL-файл.
  3. Отправка на Slave-сервер — архив отправляется через cURL на удалённый сервер для дальнейшего хранения.

После выполнения операций выводится ответ от сервера.

Шаг 2: Настройка Slave-сервера

На Slave-сервере:

  1. Прием архива от Master: сохраняем полученный бэкап.
  2. Распаковка архива: открываем его, чтобы достать SQL-файл.
  3. Восстановление базы данных: исполняем SQL-файл.

Пример кода для Slave:

class RestoreController { private string $backupDir = '/path/to/backup'; private string $backupFile = 'backup.zip'; private string $sqlFile = 'backup.sql'; public function receiveBackup($file) { if ($file['error'] === UPLOAD_ERR_OK) { move_uploaded_file($file['tmp_name'], "{$this->backupDir}/{$this->backupFile}"); return ['status' => 'success', 'message' => 'Файл успешно загружен']; } return ['status' => 'error', 'message' => 'Ошибка загрузки файла']; } public function restoreDatabase() { $zip = new ZipArchive(); if ($zip->open("{$this->backupDir}/{$this->backupFile}") === TRUE) { $zip->extractTo($this->backupDir); $zip->close(); } else { return ['status' => 'error', 'message' => 'Не удалось распаковать бэкап']; } $pdo = new PDO("mysql:host={$dbHost};dbname={$dbName}", $dbUser, $dbPass); $sql = file_get_contents("{$this->backupDir}/{$this->sqlFile}"); $pdo->exec($sql); return ['status' => 'success', 'message' => 'База данных успешно восстановлена']; } } // Получаем запрос $restoreController = new RestoreController(); if ($_FILES) { $response = $restoreController->receiveBackup($_FILES['file']); echo json_encode($response); } elseif ($_POST['action'] === 'runrestore') { $response = $restoreController->restoreDatabase(); echo json_encode($response); }

Этот код реализует контроллер для восстановления базы данных:

  1. receiveBackup — загружает файл резервной копии на сервер.
  2. restoreDatabase — распаковывает бэкап, извлекает SQL-файл и восстанавливает базу данных через PDO.
  3. Обработка запросов — загрузка файла или запуск восстановления базы данных через POST-запрос.

Конфигурация системы

Основные компоненты на стороне Slave:

  • SlaveController: главный контроллер, который управляет получением и восстановлением данных.
  • ReceiveFileController: контроллер для обработки загрузки файлов от Master.
  • RestoreController: контроллер для восстановления базы данных из архива.
  • ConfigController: контроллер для получения конфигурации сервера и базы данных.
  • ReceiveFileRepository: репозиторий для сохранения полученных файлов и проверки их целостности.

Что выполняет код на стороне Slave:

1. Получение данных и выполнение действий

  • Главный контроллер SlaveController обрабатывает входящие запросы.
  • Если в запросе передан параметр action=runrestore, запускается процесс восстановления базы данных.
  • Если в запросе переданы файлы (например, архив backup.zip), запускается процесс получения файла через ReceiveFileController.

2. Загрузка архива на Slave-сервер

  • Когда Master отправляет архив бэкапа на Slave, файл принимается с помощью ReceiveFileController и сохраняется в директорию, указанную в конфигурации ($DUMP_DIR).
  • Если файл загружен успешно, создается контрольная сумма файла для дальнейшего сравнения с контрольной суммой на стороне Master, чтобы убедиться, что файл передан корректно.

3. Восстановление базы данных

После успешной загрузки архива запускается процесс восстановления базы данных через RestoreController, который включает следующие шаги:

  • Распаковка архива с бэкапом.
  • Восстановление базы данных из файла backup.sql, который был извлечен из архива.
  • Каждая строка SQL-файла выполняется по очереди, и данные восстанавливаются в базу данных.

4. Обработка конфигурации

  • Конфигурация для Slave-сервера задается в классе ConfigController, который определяет параметры для подключения к базе данных и пути для хранения дампов.
  • В зависимости от типа сервера (обычный или WordPress), конфигурация может быть взята либо из предустановленных параметров, либо из файла wp-config.php (для WordPress).

5. Логика обработки запросов:

Запросы на Slave могут быть двух типов:

  • Прием файла архива с бэкапом от Master (ReceiveFileController).
  • Восстановление базы данных на основе полученного архива (RestoreController).

6. Получение данных и выполнение действий

  • Главный контроллер SlaveController обрабатывает входящие запросы.
  • Если в запросе передан параметр action=runrestore, запускается процесс восстановления базы данных.
  • Если в запросе переданы файлы (например, архив backup.zip), запускается процесс получения файла через ReceiveFileController.

7. Загрузка архива на Slave-сервер

  • Когда Master отправляет архив бэкапа на Slave, файл принимается с помощью ReceiveFileController и сохраняется в директорию, указанную в конфигурации ($DUMP_DIR).
  • Если файл загружен успешно, создается контрольная сумма файла для дальнейшего сравнения с контрольной суммой на стороне Master, чтобы убедиться, что файл передан корректно.

8. Восстановление базы данных

После успешной загрузки архива запускается процесс восстановления базы данных через RestoreController, который включает следующие шаги:

  • Распаковка архива с бэкапом.
  • Восстановление базы данных из файла backup.sql, который был извлечен из архива.
  • Каждая строка SQL-файла выполняется по очереди, и данные восстанавливаются в базу данных.

9. Обработка конфигурации

  • Конфигурация для Slave-сервера задается в классе ConfigController, который определяет параметры для подключения к базе данных и пути для хранения дампов.
  • В зависимости от типа сервера (обычный или WordPress), конфигурация может быть взята либо из предустановленных параметров, либо из файла wp-config.php (для WordPress).

10. Логика обработки запросов:

Запросы на Slave могут быть двух типов:

  • Прием файла архива с бэкапом от Master (ReceiveFileController).
  • Восстановление базы данных на основе полученного архива (RestoreController).

Как это работает в связке с Master

Рис.8. Как это работает в связке с Master.
Рис.8. Как это работает в связке с Master.

Таким образом, система обеспечивает автоматический процесс резервного копирования, передачи и восстановления данных между серверами Master и Slave, поддерживая их синхронизацию.

Практическая установка

Теперь перейдем к самой настройке. В архиве dbcopier-master.zip вы можете найти готовый скрипт, который мы разработали для решения этой задачи. Там находятся две папки: Master и Slave.

1. Подготовка папок на серверах:

На хостинге 1 (Master) создаем в корне сайта папку backup и помещаем в нее все файлы из папки Master.

На хостинге 2 (Slave) создаем аналогичную папку backup и помещаем в нее все файлы из папки Slave.

2. Настройка доступа на Master:

На хостинге 1 (Master) идем в папку backup и открываем файл Config.php. Здесь необходимо указать данные для подключения к серверу Slave.Также здесь можно задать папку, куда будут сохраняться копии БД. В нашем случае /upload.

3. Если вы используете WordPress, скрипт автоматически извлечет данные из файла wp-config.php, так что вам не нужно будет беспокоиться о подключении.

Если у вас не WordPress, просто укажите свои данные для подключения к базе данных в файле backup/Config.php на Master и в backup/src/Config.php на Slave.

Рис.9. Код.
Рис.9. Код.

4. Настройка Cron:

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

Используйте команду:

Рис.10. Команда.
Рис.10. Команда.

Полный путь можно посмотреть на вашем хостинге.

Это обеспечит автоматическое создание бэкапов и их передачу на Slave.

Проверка работоспособности

После всех настроек стоит убедиться, что система работает корректно:

  • Проверьте, создаются ли бэкапы на Master.
  • Убедитесь, что данные успешно передаются и восстанавливаются на Slave.
  • Периодически тестируйте процесс восстановления, чтобы быть уверенным, что все работает как часы.

Поддержка системы

Поддерживать систему Master-Slave достаточно просто, если соблюдать несколько правил:

  1. Регулярные проверки: следите за состоянием обоих серверов. Проверяйте, чтобы бэкапы действительно создавались и восстанавливались.
  2. Мониторинг нагрузки: убедитесь, что Slave-сервер не перегружен, особенно если он начинает принимать много запросов.
  3. Тестирование восстановления: периодически проводите тесты на восстановление, чтобы убедиться, что бэкапы работают.

Теперь ваша система репликации Master-Slave настроена, и вы можете спокойно заниматься развитием своих проектов, зная, что ваши данные в надежных руках!

Автор: Сергей Фуфаев, web-разработчик в Ant-Team.ru.

Подписывайтесь на наш телеграм-канал, чтобы первыми узнавать о выходе новых материалов. И смотрите наши бесплатные обучающие видео на YouTube, VK и Rutube.

1212
77
11
22 комментария

Интересно, спасибо за материал!

1

Будем рады, если статья принесет вам пользу

спасибо, что поделились кодом! ну и сама технология выглядит вполне рабочей

1

Да, технология абсолютно рабочая, проверена нашим агентством)

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

1

Спасибо! Используйте нашу технологию, и такого больше не повторится)

У меня самый простой сайт на виртуальном хостинге. И хостер сам делает бэкапы. Если мы что-то налажаем (бывает такое раз в полгода), просим хостера откатить, и он отказывает. Это не то? Такой бэкап не подходит?