Pull to refresh
214.59

Опыт эксплуатации MySQL Master-Master — как пережить аварию датацентра

Reading time6 min
Views81K
Всем привет!

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

Говорить о MySQL Master-Master репликации — в контекстах высокой доступности и производительности — модно, но, к сожалению, многие не понимают ее сути и связанных с технологией серьезных ограничений.
Начнем с того, что в классическом MySQL «настоящей» Master-Master репликации — пока нет :-) Но если постараться, можно все таки просто и быстро настроить эффективную схему выживания при отказе одного датацентра и получить свою долю счастья.



Настройка Master-Master


Известно, что для настройки Master-Master нужно настроить смещение ИДшников и установить для каждого сервера свой уникальный идентификатор:

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

Итог: вы самостоятельно настроили MySQL Master-Master на двух серверах и готовы разбираться дальше.


Синхронность


Нужно четко понять раз и навсегда, что классическая репликация MySQL — асинхронна (в версии 5.6 появилась поддержка ПОЛУ-синхронной репликации; ПОЛУ выделено, т.к. она остается не полностью синхронной до сих пор).
К черту теорию, посмотрим чем нам грозит асинхронность репликации. Данные между БД передаются с произвольной задержкой (от миллисекунд до дней). Для архитектуры Master-Slave со Slave можно приложением просто не читать данные, отставшие на, допустим, 30 секунд. А вот для Master-Master все хуже — у нас нет и не будет (даже в случае ПОЛУ-синхронной репликации) никаких гарантий, что копии БД — синхронны. Т.е. один и тот же запрос может выполняться по-разному на каждой из БД. А одновременное выполнение команд:

UPDATE mytable SET mycol=mycol+1; - на одном сервере

UPDATE mytable SET mycol=mycol*3; - на втором сервере


также приведет к рассинхронизации данных в обеих БД (да простят нас Кодд и Дейт).

Одновременная вставка в обе БД одинакового уникального значения столбца (не автоинкремента!) — приведет к остановке репликации по ошибке. Таких «жутких» примеров можно привести множество.
И хотя иногда советуют решения типа «ON DUPLICATE KEY UPDATE», игнорирование ошибок и пр. и заодно перелопатить приложение — здравый смысл подсказывает, что подобные подходы — скользкие и ненадежные.
Думаю, очевидно, к какому коллапсу и несогласованности это может привести ваше приложение.

Итог: использовать асинхронный Master-Master для одновременной записи в обе БД без знания подводных камней — опасно и ненадежно и применяется в редких кейсах.


Магия кольца


Технически возможно объединить MySQL сервера в кольцо. Однако вышеупомянутые проблемы становятся еще острее — добавляется недетерминизм, связанный с распространением записи по кольцу: можно выполнить обновление одновременно на 1 и 3 узле, а мимоходом раз, и на 2 узле. Что из этого получится на каждой ноде — страшно подумать. А поддерживать такое репликационное хозяйство — «сплошное удовольствие», кошмарный сон системного администратора.


Поддержка синхронной репликации в MySQL


Сейчас, в контексте настоящей синхронной Master-Master репликации (когда целостность данных гарантируется и писать можно одновременно на все ноды кластера) много говорят про Galera. Кто-то скажет, что для этого можно попробовать использовать давно известный MySQL NDB Cluster — но широко известно, что этот «автожир» подходит очень узкому кругу приложений, редко из мира веб.
Мы с интересом следим за Galera — возможно именно на ней в будущем будут строить подлинные Master-Master кластера, а пока посмотрим что полезного можно извлечь из имеющихся хорошо проверенных стабильных инструментов.


Польза от асинхронной MySQL Master-Master репликации


Однако, все не так печально. Как бы не ругали классическую 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, — иногда не достаточно, и репликация при рестарте сервера отваливается)
  • недостаточная поддержка транзакционности (спасибо патчу Percona Server, в котором эта фича реализована)

эта «рабочая лошадка» используется очень широко и приносит массу пользы и счастья системным администраторам:
  • для создания горячего «почти» актуального бэкапа
  • для кластеризации чтений с MySQL слейвов
  • для вертикального шардинга (фильтруем какие таблицы на какие слейвы переносить)
  • для того, чтобы спокойно бэкапить Slave-сервер с помощью mysqldump, не нагружая боевой сервер БД
  • и др.

В «полезную лошадку» можно достаточно быстро превратить и асинхронную Master-Master репликацию. Обычно данную архитектуру называют Master-Master (Active-Passive):

Идеи просты: пишем в одну БД, вторая используется как горячий бэкап, в который можно при необходимости БЫСТРО НАЧАТЬ ПИСАТЬ ДАННЫЕ! Именно «быстро начать писать данные» и дает этой архитектуре такую полезность и HighAvailability-льность.


Немного покурив...


Немного покурив и подумав, можно увидеть еще одно замечательное применение этой «рабочей лошадки» — способность выдержать аварию в локальном датацентре. Нужно просто держать горячую БД в Master-Master (Active-Passive) в другом датацентре, можно и на другом континенте:

Да, вижу, стрелка в горящий датацентр уже не нужна, но оставим для целостности восприятия картинки :-)
Ну а дальше никто нам не запрещает масштабировать чтения на данной архитектуре, получив локальный относительно датацентра кластер:

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

Риски


Честно говоря, такая схема репликации работает достаточно надежно и мы ее с успехом применяем на Битрикс24 в облаке Amazon и в решении «Географический веб-кластер». Особенности же ее эксплуатации следующие:
  • Начните эксплуатацию в режиме statement-based репликации. Если в логе MySQL появляются сообщения, что типа данный запрос опасно выполнять в этом режиме, т.к. порядок его выполнения на Slave может быть другим — включите режим репликации «mixed» (это может потребовать увеличения режима изоляции транзакций в InnoDB до Repeatable Read). Не рекомендую включать «row-based».
  • Если вы беспокоитесь о производительности, то скорее всего не будете включать параметры: flush_log_at_trx_commit=1, sync_binlog=1, sync_relay_log=1, sync_relay_log_info=1, sync_master_info=1 (сарказм :-) ). Значит вам придется иногда после аварийных рестартов MySQL поднимать репликацию с последней позиции вручную — покурите с маном команды mysqlbinlog, очень много интересного и полезного можно найти.
  • Постарайтесь пока не поднимите репликацию с одной стороны не переключать обратно балансировщик — иначе может начаться каша с данными (и во второй раз Кодд и Дейт могут уже не простить :-) ).



«А компот?»


Забыли про синхронизацию контента между ДЦ. Тут все в принципе стандартно:
Облачное хранилище для шары файлов — Clodo.ru, Selectel.ru, Amazon S3, Google Storage и другие. Интенсивное использование CDN. Передача статики между ДЦ посредством csync2, rsync и других подобных инструментов. Обычно тут проблем не возникает.

Что почитать по этой теме


Стоит посмотреть на проект linux-ha и, видимо, сделать проще на bash ;-) Очень перспективной выглядит Galera. Будем также надеяться, что в MySQL наконец-то сделают «настоящую» Master-Master репликацию, так востребованную сегодня.
И конечно, совсем забыл — данные все равно могут рассинхронизироваться между Master-Master (Active-Passive). Это бывает из-за краха mysql, внезапной перезагрузки сервера, потери позиции репликации, ошибок в ее коде. Ничего страшного, есть лекарство — посложнее:

и попроще типа этого простого скриптика на bash (не используйте на больших таблицах):
#!/bin/bash

DATABASES=`mysql -u root -p${MYSQL_ROOT_PASSWORD} -h $SHARD_L -B -N -e"SHOW DATABASES" | grep -vE '(^binlogs$)|(^performance_schema$)|(^test.*$)|(^information_schema$)'`

for DB in $DATABASES; do

TABLES=`mysql -u root -p${MYSQL_ROOT_PASSWORD} -h $SHARD_L -B -N -D $DB -e"SHOW TABLES"

    for TABLE in $TABLES; do

        CS_L=`mysql -u root -p${MYSQL_ROOT_PASSWORD} -h $SHARD_L -D $DB -B -N -e"CHECKSUM TABLE $TABLE" | awk '{print $2}'`
        CS_R=`mysql -u root -p${MYSQL_ROOT_PASSWORD} -h $SHARD_R -D $DB -B -N -e"CHECKSUM TABLE $TABLE" | awk '{print $2}'`

        if [ "$CS_L" != "$CS_R" ]; then
            echo "${DB}-${TABLE} : DIFF"

            mysql -u root -p${MYSQL_ROOT_PASSWORD} -h $SHARD_L -D $DB -B -N -e"SELECT * FROM $TABLE" > /var/tmp_data/table_diff_${SHARD_L}.tmp
            mysql -u root -p${MYSQL_ROOT_PASSWORD} -h $SHARD_R -D $DB -B -N -e"SELECT * FROM $TABLE" > /var/tmp_data/table_diff_${SHARD_R}.tmp
            diff -u /var/tmp_data/table_diff_${SHARD_L}.tmp /var/tmp_data/table_diff_${SHARD_R}.tmp
            rm -f /var/tmp_data/table_diff_${SHARD_L}.tmp /var/tmp_data/table_diff_${SHARD_R}.tmp

        else
            echo "${DB}-${TABLE} : OK"
        fi

    done

done


Итоги


На проекте Битрикс24 мы интенсивно используем описанную технологию — и это выручало нас не раз. Последнее падение датацента в амазоне 15 июня сего года прошло незаметно для клиентов — мы автоматически переключились на резервный мастер в другом ДЦ.
В статье мы по полочкам разобрали тему MySQL Master-Master, чтобы в дальнейшем не искать в этой технологии скрытого смысла. Рассмотрели опасные и плохо описанные в сети подводные камни. Выбрали для Master-Master (Active-Passive) простое и практичное применение для обеспечения горячего Master-сервера MySQL в другом датацентре (на другом континенте) и теперь сисдамину можно съездить в отпуск не опасаясь, что на всех нодах репликации данные станут разными (больше не упоминаю имен отцов основателей реляционной теории) или молния ударит в датацентр :-) Всем удачи, хорошего настроения и надежной репликации!
Tags:
Hubs:
Total votes 86: ↑73 and ↓13+60
Comments70

Articles

Information

Website
www.bitrix24.ru
Registered
Founded
1998
Employees
501–1,000 employees
Location
Россия