Что такое репликация данных

Что такое репликация данных

Roman Bogachev VMware Specialist | Drone Pilot | Traveler

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

mysql_replication

Существует два основных подхода при работе с репликацией данных:

Master-Slave репликация

В этом подходе выделяется один основной сервер базы данных, который называется Master. На нем происходят все изменения в данных (любые запросы INSERT/UPDATE/DELETE).

Slave сервер постоянно копирует все изменения с Master. С приложения на Slave-сервер отправляются запросы чтения данных (запросы SELECT). Таким образом Master-сервер отвечает за изменения данных, а Slave за чтение.

mysql_replication

Читайте как настроить Master-Slave репликацию на MySQL

В приложении нужно использовать два соединения — одно для Master, второе — для Slave:
(Используем два соединения — для Master и Slave — для записи и чтения соответственно)

1
2
3
4
5
6
7
8
9
<?
$master = mysql_connect('10.10.0.1', 'root', 'pwd');
$slave = mysql_connect('10.10.0.2', 'root', 'pwd');

# ...
mysql_query('INSERT INTO users ...', $master);

# ...
$q = mysql_query('SELECT * FROM photos ...', $slave);

Несколько Slave серверов

Преимущество этого типа репликации в том, что мы можем использовать более одного Slave сервера. Обычно следует использовать не более 20 Slave серверов при работе с одним Master.

mysql_master_server

Тогда приложение выбирает случайным образом один из Slave серверов для обработки запросов:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?
$master = mysql_connect('10.10.0.1', 'root', 'pwd');
$slaves = [
'10.10.0.2',
'10.10.0.3',
'10.10.0.4',
];
$slave = mysql_connect($slaves[array_rand($slaves)], 'root', 'pwd');

# ...
mysql_query('INSERT INTO users ...', $master);

# ...
$q = mysql_query('SELECT * FROM photos ...', $slave);

Задержка репликации

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

1
2
3
4
5
6
7
8
9
10
<?
$master = mysql_connect('10.10.0.1', 'root', 'pwd');
$slave = mysql_connect('10.10.0.2', 'root', 'pwd');

# ...
mysql_query('UPDATE users SET age = 25 WHERE id = 7', $master);
$q = mysql_query('SELECT * FROM users WHERE id = 7', $master);

# ...
$q = mysql_query('SELECT * FROM photos ...', $slave);

Выход из строя

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

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

Резервирование

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

Master-Master репликация

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

mysql_master_master

Читайте как настроить Master-Master репликацию на MySQL

При использовании такого типа репликации достаточно выбирать случайное соединение из доступных Master серверов:
(Выбор случайного Master для обработки соединений)

1
2
3
4
5
6
7
8
9
10
<?
$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);

Выход из строя

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

Используйте Master-Master репликацию только в крайнем случае. Вместо нее лучше пользоваться техникой “ручной” репликации, описанной ниже.

Асинхронность репликации

В MySQL репликация работает в асинхронном режиме. Это значит, что приложение не знает, как быстро данные появятся на Slave.

async_mysql_replication

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

Синхронный режим

Синхронный режим репликации позволит гарантировать копирование данных на Slave.

mysql_sync_replication

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

“Ручная” репликация

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

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

mysql_manual_replication

При записи данных, все запросы будут отправляться на несколько серверов. Зато операции чтения можно будет отправлять на любой сервер. Нагрузка при этом будет распределяться по всем доступным серверам:
(Все операции изменения данных происходят на нескольких серверах, а чтения — на одном случайном)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?
$dbs = [
'10.10.0.1',
'10.10.0.2'
];

foreach ( $dbs as $db )
{
$connection = mysql_connect($db, 'root', 'pwd');
mysql_query('INSERT INTO users ...', $connection);
}


# ...

$connection_read = mysql_connect($dbs[array_rand($dbs)], 'root', 'pwd');
mysql_query('SELECT * FROM users WHERE ...', $connection_read);

Это позволит использовать преимущества репликации даже если сама технология ее не поддерживает.

Выход из строя

При поломке одного из серверов в такой схеме необходимо сделать следующее:

  • Исключить сервер из списка используемых.
  • Настроить репликацию Master-Slave на новом сервере, используя один из рабочих серверов в качестве Master.
  • Когда все данные репликации будут синхронизированы, включить сервер обратно в список используемых и остановить репликацию.

Самое важное

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