Главная страница

Дик-ДИ_2018_МУ. Технология построения защищенных распределенных приложений


Скачать 0.74 Mb.
НазваниеТехнология построения защищенных распределенных приложений
Дата27.03.2022
Размер0.74 Mb.
Формат файлаpdf
Имя файлаДик-ДИ_2018_МУ.pdf
ТипМетодические указания
#419638
страница3 из 5
1   2   3   4   5
2.2.5 Выход из строя сервера при master-slave репликации
При выходе из строя ведомого сервера, достаточно просто переключить все приложения на работу с ведущим. После этого восстановить репликацию на ведомом сервере и снова его запустить.
Если выходит из строя ведущий сервер, нужно переключить все операции
(и чтения и записи) на ведомый. Таким образом, он станет новым ведущим.
После восстановления старого ведущего, настроить на нем реплику, и он станет новым ведомым.
2.2.6 Резервирование
Намного чаще репликацию master-slave используют не для масштабирования, а для резервирования. В этом случае, ведущий сервер обрабатывает все запросы от приложения. Ведомый сервер работает в

24 пассивном режиме. Но в случае выхода из строя ведущего, все операции переключаются на ведомый.
2.2.7 Master-master репликация
В этой схеме, любой из серверов может использоваться как для чтения, так и для записи (рисунок 5).
Рисунок 5 — Master-master репликация
При использовании такого типа репликации достаточно выбирать случайное соединение из доступных мастеров:
$masters = [
'10.10.0.1',
'10.10.0.2',
'10.10.0.3',
];
$master = mysql_connect($masters[array_rand($masters)], 'root', 'pwd');
# ... mysql_query('INSERT INTO users ...', $master);
# Выбор случайного Мастера для обработки соединений
2.2.8 Выход из строя сервера
при master-master репликации
Вероятные поломки делают master-master репликацию непривлекательной. Выход из строя одного из серверов практически всегда приводит к потере каких-то данных. Последующее восстановление также сильно затрудняется необходимостью ручного анализа данных, которые либо успели, либо не успели скопироваться.
2.2.9 Проблемы репликации в MySQL
Изначально в MySQL использовалась асинхронная репликация. Принцип работы очень прост, клиент производит изменение (commit), которое выполняется на ведущем сервере, результат заносится в бинарный журнал.
MySQL мастер 1
PHP
MySQL мастер 2
чтение/запись чтение/запись
10.10.0.1 10.10.0.2

25
Клиент, не дожидаясь ответа подчиненных серверов, сразу же получает сообщение об успешном завершении процесса. Такой подход обеспечивает максимальную скорость и позволяет производить репликацию даже по коммутируемым соединениям, но имеет один существенный минус, особенно актуальный для кластеров. Если после подтверждения транзакции ведущий сервер выходит из строя, а подчиненные сервера еще не успевают получить реплику, данные будут потеряны, но клиент будет уверен, что все в порядке. В случае мультимастер репликации проблема только усугубляется.
В MySQL 5.5 появилась поддержка полу-синхронного (semi-synchronous) механизма репликации, основанного на патчах к InnoDB от компании Google. В этом случае ведущий сервер ожидает подтверждения от одного из ведомых, который сообщает, что получил и записал на диск реплику. При этом не ожидается, когда ведомый выполнит сам запрос, и нет никаких гарантий, что он вообще будет выполнен (например, ошибка).
Чтобы не быть зависимым от доступности подчиненного сервера, предусмотрен таймаут, позволяющий автоматически перейти асинхронный режим, если ни один из ведомых серверов не ответил за запрос. При восстановлении связи будет опять активирован semi-synchronous.
Также поддерживается отложенная репликация, когда подчиненный сервер начинает выполнять запрос после истечения указанного промежутка времени (устанавливается при помощи MASTER_DELAY, по умолчанию 0).
Это может быть полезно, если на ведомом сервере понадобится откатить транзакцию.
По умолчанию используется асинхронная репликация, чтобы включить полу-синхронную, необходимо установить специальный плагин и активировать параметр в my.cnf.
П
осмотрим, чем нам грозит асинхронность репликации. Данные между базами данных передаются с произвольной задержкой (от миллисекунд до дней). Для архитектуры master-slave с ведомого сервера можно просто не читать данные, отставшие, допустим, на 30 секунд. А вот для master-master все хуже — у нас нет и не будет (даже в случае полу-синхронной репликации) никаких гарантий, что копии БД — синхронны. Т.е. один и тот же запрос может выполняться по-разному на каждой из БД. А одновременное выполнение команд на разных серверах:
UPDATE mytable SET mycol=mycol+1;
UPDATE mytable SET mycol=mycol*3; также приведет к рассинхронизации данных в обеих БД.
Одновременная вставка в обе БД одинакового уникального значения столбца — приведет к остановке репликации по ошибке (при авто инкременте такой проблемы не возникает). Таких «жутких» примеров можно привести множество. И хотя иногда советуют решения типа «ON DUPLICATE KEY
UPDATE», игнорирование ошибок и пр. и заодно «перелопатить» приложение
— здравый смысл подсказывает, что подобные подходы — скользкие и ненадежные.

26
Очевидно, к какому коллапсу и несогласованности это может привести ваше приложение.
Как результат, использовать асинхронный master-master для одновременной записи в обе БД без знания подводных камней — опасно и ненадежно и применяется в редких случаях.
2.2.10 Польза от асинхронной репликации
Однако, все не так печально. Как бы не ругали классическую MySQL master-slave репликацию за:
 асинхронность (рассинхронизация данных на узлах, отставания и т.п.);
 недостаточную надежность (flush_log_at_trx_commit=1, sync_binlog=1, sync_relay_log=1, sync_relay_log_info=1, sync_master_info=1, — иногда не достаточно, и репликация при рестарте сервера отваливается);
 недостаточную поддержка транзакционности, master-slave репликация используется очень широко и приносит массу пользы системным администраторам:
 для создания горячей почти актуальной резервной копии;
 для кластеризации чтений;
 резервирования при вертикальном шардинге (разделение таблиц по разным серверам);
 для создания резервной копии без чрезмерной нагрузки рабочего сервера БД;
 и так далее.
Пользу можно извлечь и из асинхронной master-master репликации. При этом используется так называемая active-passive архитектура.
Идея проста: пишем в одну БД, вторая используется как горячая резервная копия, в которую при необходимости можно быстро начать писать данные, получая, таким образом, высокую степень доступности.
Порядок выполнения работы
2.3
2.3.1 Установка операционной системы
В качестве операционной системы для нашего кластера будем использовать Ubuntu Server 16.04.3 LTS.
Все узлы будут работать на VirtualBox. Выставим следующие системные настройки для виртуальной машины: 10 GB пространства для жёсткого диска, два ядра и 512 Мб памяти. Виртуальную машину можно оснастить двумя сетевыми адаптерами: один NAT, а другой для внутренней сети.
После того, как была скачена и установлена операционная система, необходимо обновиться и установить ssh: sudo apt-get update && sudo apt-get upgrade sudo apt-get install ssh
Для редактирования файлов с консоли будем использовать редактор nano.
Для его установки введем команду:

27 sudo apt-get install nano
Для запуска: nano файл или если нужно редактировать системные файлы (с root правами), то sudo nano файл
Для удобства также можно поставит оболочку Midnight Commander sudo apt-get install mc для ее запуска mc или если хотите редактировать системные файлы (с root правами), то sudo mc
Изменим имя узла на master в файле /etc/hostname.
2.3.2 Настройка статического IP адреса
Для дальнейшей работы нам потребуются IP-адреса серверов. Для того чтобы узнать IP-адрес, можно воспользоваться командой ifconfig
Вместо использования динамически выделенных адресов более удобным может оказаться использование статических адресов. Для настройки статического IP-адреса замените в файле /etc/network/interfaces для соответствующего интерфейса «dhcp» на «static» и укажите значения адреса, маски сети, шлюза и адрес DNS сервера для соответствия требованиям вашей сети: auto enp0s3 iface enp0s3 inet static address 192.168.0.1 netmask 255.255.255.0 gateway 192.168.0.254 dns-nameservers 192.168.0.254
В приведенных далее примерах для серверов используются адреса вида
192.168.0.X.
2.3.3 Настройка доменного имени узла
Нам необходимо, чтобы все узлы могли легко обращаться друг к другу. В большом кластере желательно использовать dns сервер, но для нашей маленькой конфигурации подойдет файл /etc/hosts. В нем мы будем описывать соответствие ip-адреса узла к его имени в сети. Для одного узла ваш файл должен выглядеть примерно так:
127.0.0.1 localhost
# The following lines are desirable for IPv6 capable hosts

28
::1 ip6-localhost ip6-loopback fe00::0 ip6-localnet ff00::0 ip6-mcastprefix ff02::1 ip6-allnodes ff02::2 ip6-allrouters
192.168.0.1 master
2.3.4 Настройка SSH
Для копирования базы данных с ведущего сервера на ведомый нам потребуется доступ по ssh. Для начала необходимо сгенерировать новый ssh ключ: ssh-keygen -t rsa -P ""
Следующим шагом необходимо добавить созданный ключ в список авторизованных: cat $HOME/.ssh/id_rsa.pub >> $HOME/.ssh/authorized_keys
Проверяем работоспособность, подключившись к себе: ssh master
Чтобы вернуться в локальную сессию, просто наберите: exit
2.3.5 Копирование образа виртуальной машины
Теперь у нас есть готовый образ, который послужит основой для создания репликации. Далее создадим копию образа.
При клонировании образа необходимо сгенерировать новые MAC-адреса для сетевых интерфейсов и выдать им необходимые IP-адреса
, выдать им необходимые IP-адреса и п
оправить файл /etc/hosts на всех узлах так, чтобы в нем были прописаны все соответствия:
127.0.0.1 localhost
192.168.0.1 master
192.168.0.2 slave
Заменим имя нового узла на slave, для этого внесем изменения в файл
/etc/hostname.
2.3.6 Установка MySQL сервера
На каждый из созданных узлов установим MySQL сервер: sudo apt-get install mysql-server
Конфигурация MySQL сервера содержится в файле /etc/mysql/my.cnf, который подключает конфигурационные файлы из директорий /etc/mysql/conf.d и /etc/mysql/mysql.conf.d.

29
По умолчанию MySQL сервер принимает соединения только с локальной машины. Для того, чтобы разрешить подключаться к нему с других машин замените строку в файле /etc/mysql/mysql.conf.d/mysqld.cnf bind-address = 127.0.0.1 на
#разрешить подключатся с любого хоста bind-address = 0.0.0.0 на каждом из узлов.
2.3.7 Настройка master-slave репликация
2.3.7.1 Настройка ведущего сервера
На сервере, который будет выступать мастером, необходимо внести правки в /etc/mysql/mysql.conf.d/mysqld.cnf:
# выбираем ID сервера, произвольное число, лучше начинать с 1 server-id = 1
# путь к бинарному логу log_bin = /var/log/mysql/mysql-bin.log
# название Вашей базы данных, которая будет реплицироваться binlog_do_db = clusterdb
Перезапускаем Mysql: sudo /etc/init.d/mysql restart либо sudo service mysql restart
Для управления демоном MySql можно использовать следующие команды:
 остановка сервиса MySql sudo service mysql stop
 запуск сервиса sudo service mysql start
 узнать состояние сервиса sudo service mysql status
2.3.7.2 Создание базы данных на ведущем сервере
Для создания базы данных запустим консоль MySql: mysql -u root -p --prompt='master> '
Создаем базу данных, создаем таблицу и вставляем в нее данные create database clusterdb; create table clusterdb.simples (id int not null primary key);

30 insert into clusterdb.simples values (999),(1),(2),(3);
Посмотрим содержимое таблицы select * from clusterdb.simples;
2.3.7.3 Настройка прав на репликацию
Далее необходимо создать профиль пользователя, из-под которого будет происходить репликация. Для этого запускаем консоль: mysql -u root -p --prompt='master> '
Далее создаем и назначаем права пользователю для реплики (даем права пользователю slave_user с паролем slavepass): grant replication slave on *.* to 'slave_user'@'%' identified by 'slavepass';
Альтернативно можно вначале создать пользователя и лишь, затем дать ему права create user 'repl'@'%.mydomain.com' identified by 'slavepass'; grant replication slave on *.* to 'slave_user'@'%';
Обновим права доступа: flush privileges;
2.3.7.4 Получение статуса ведущего сервера
Далее блокируем все таблицы в нашей базе данных: use clusterdb; flush tables with read lock;
Проверяем статус ведущего сервера: show master status;
Мы увидим что-то похожее на: mysql> SHOW MASTER STATUS;
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000004 | 1243 | clusterdb | |
+------------------+----------+--------------+------------------+
1 row in set (0.00 sec)
Выделенные значения мы будем использовать для запуска ведомого сервера.
Выходим из консоли mysql: quit
2.3.7.5 Создание дампа базы данных
Теперь необходимо сделать дамп базы данных: mysqldump -u root -p clusterdb > /home/user/clusterdb.sql
Снова заходим в консоль

31 mysql -u root -p --prompt='master> ' и разблокируем таблицы в консоли mysql: use clusterdb; unlock tables;
2.3.7.6 Создание базы на ведомом сервере
Копируем файл clusterdb.sql с ведущего сервера на ведомый: scp user@master:/home/user/clusterdb.sql /home/user/clusterdb.sql
Заходим в консоль mysql -u root -p --prompt='slave> '
В консоли mysql на ведомом сервере создаем базу с таким же именем, как и на ведущем: create database clusterdb;
Выходим из консоли и загружаем дамп (через bash): mysql -u root -p clusterdb < /home/user/clusterdb.sql
2.3.7.7 Настройка ведомого сервера
В настройках my.cnf на ведомом сервере необходимо указать такие параметры:
# ID ведомого сервера, удобно выбирать следующим числом после Мастера server-id = 2
# Путь к relay логу relay-log = /var/log/mysql/mysql-relay-bin.log
# Путь к bin логу на Мастере log_bin = /var/log/mysql/mysql-bin.log
# База данных для репликации binlog_do_db = clusterdb
Перезапускаем MySql на ведомом сервере: sudo /etc/init.d/mysql restart
2.3.7.8 Активации репликации на ведомом сервере
Нам осталось включить репликацию, для этого необходимо указать параметры подключения к мастеру. В консоли mysql на ведомом сервере необходимо выполнить запрос: change master to master_host='master', master_user='slave_user', master_password='slavepass', master_log_file = 'mysql-bin.000004', master_log_pos = 1243;
Указанные значения мы берем из настроек ведущего сервера.
После этого запускаем репликацию на ведомом сервере: start slave;

32
Проверить работу репликации можно запросом на ведомом сервере: slave> show slave status\G
Slave_IO_State: Waiting for master to send event
Master_Host: master
Master_User: slave_user
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000004
Read_Master_Log_Pos: 1243
Relay_Log_File: mysql-relay-bin.000002
Relay_Log_Pos: 548
Relay_Master_Log_File: mysql-bin.000004
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 1243
Relay_Log_Space: 527
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 1
Master_UUID: 3e11fa47-71ca-11e1-9e33-c80aa9429562
Master_Info_File: /var/lib/mysql/master.info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
Master_Retry_Count: 86400
Master_Bind:
Last_IO_Error_Timestamp:
Last_SQL_Error_Timestamp:
Master_SSL_Crl:
Master_SSL_Crlpath:
Retrieved_Gtid_Set:
Executed_Gtid_Set:
Auto_Position: 0
Replicate_Rewrite_DB:
Channel_name:
1 row in set (0.00 sec)

33
2.3.7.9 Проверка работы репликации
Через mysql консоль на ведущем сервере добавим новую запись в таблицу simples нашей базы данных: master> insert into clusterdb.simples values (5);
Через mysql консоль на ведомом сервере посмотрим содержимое таблицы и удостоверимся, что ведомый сревер получил изменения slave> select * from clusterdb.simples;
2.3.8 Настройка master-master репликация
Перенастроим Master-Slave репликацию в Master-Master репликацию
(перенастроим ведомый сервер во второй мастер).
2.3.8.1 Настройка прав на репликацию
На будущем втором мастер-сервере (бывшем ведомом) создадим пользователя и назначаем ему права для реплики (даем права пользователю replicator с паролем password): grant replication slave on *.* to 'replicator'@'%' identified by 'password';
Проверяем статус второго мастер-сервера (бывшего ведомого):
SHOW MASTER STATUS;
Мы увидим что-то похожее на: mysql> show master status;
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000001 | 443 | clusterdb | |
+------------------+----------+--------------+------------------+
1 row in set (0.00 sec)
Выделенные значения мы будем использовать для запуска репликации на первом мастере.
2.3.8.2 Активации репликации на первом мастер-сервере
Нам осталось включить репликацию на первом мастере, для этого необходимо указать параметры подключения ко второму мастеру. В консоли mysql на первом мастере необходимо выполнить запросы: stop slave; change master to master_host='slave', master_user='replicator', master_password='password', master_log_file = 'mysql-bin.000001', master_log_pos = 443; start slave;

34
1   2   3   4   5


написать администратору сайта