У нас есть настройка MySQL master и slave, которые находятся в разных центрах обработки данных, и еще один slave в том же центре обработки данных, что и master.
Пропускная способность между центром обработки данных довольно высока (в сетевых тестах, которые мы сделали, мы можем достичь 15 МБ / с), но задержка существует, она составляет около 28 мс. Это ни в коем случае не высоко, но намного выше, чем задержка менее секунды в том же центре обработки данных.
Время от времени мы сталкиваемся с серьезными задержками (2000 секунд и более) с удаленным ведомым, в то время как местный подчиненный остается в курсе. При рассмотрении запаздывающего удаленного ведомого устройства поток SQL обычно тратит время на ожидание потока ввода-вывода для обновления журнала ретрансляции. Мастер показывает "ожидание сети" или что-то в этом роде одновременно.
Таким образом, это означает, что это сеть, но у нас все еще есть свободная пропускная способность, когда это происходит.
Мой вопрос : может ли задержка между центрами обработки данных повлиять на производительность репликации? Ведомый поток io просто передает события до тех пор, пока мастер не перестанет их отправлять, или он как-то объединяет мастер между событиями?
источник
Ответы:
Прямой ответ на ваш вопрос - Да, но это зависит от версии MySQL, которую вы используете. До MySQL 5.5 репликация работала бы следующим образом:
Начиная с MySQL 5.5, используя полусинхронную репликацию , теперь репликация будет работать следующим образом:
Эта новая парадигма позволит Рабу быть ближе к своему Мастеру.
Несмотря на это, задержка в сети может помешать MySQL Semisync Replication до такой степени, что она возвращается к асинхронной репликации старого стиля. Почему ? Если тайм-аут происходит без какого-либо ведомого, подтвердившего транзакцию, мастер возвращается к асинхронной репликации. Когда хотя бы один полусинхронный подчиненный сервер догоняет, мастер возвращается к полусинхронной репликации.
ОБНОВЛЕНИЕ 2011-08-08 14:22 EDT
Конфигурация полусинхронной репликации MySQL 5.5 проста
Шаг 1) Добавьте эти четыре (4) строки в /etc/my.cnf
Шаг 2) Перезапустите MySQL
Шаг 3) Запустите эти команды в клиенте MySQL
Шаг 4) Раскомментируйте три параметра rpm_semi_sync после параметра plugin-dir
Шаг 5) Перезапустите MySQL
Все сделано !!! Теперь просто настройте MySQL Replication как обычно.
источник
Мне очень нравится, как Роландо описал последовательность операций, которые выполняет репликация. Однако, я думаю, было бы более понятно, если бы мы добавили еще один компонент - клиент.
С клиентом последовательность операций для асинхронной репликации может быть следующей:
Клиент отправляет мастеру запрос SQL (например, вставка) с использованием транзакций
Мастер выполняет транзакцию. В случае успеха запись сохраняется на диске, но транзакция еще не зафиксирована.
Мастер записывает событие вставки в двоичный журнал мастера. Если мастер не может сохранить его в двоичном журнале, транзакция откатывается.
Клиент получает ответ от мастера (успех или откат).
В случае успешной транзакции поток дампа на главном сервере считывает событие из двоичного журнала и отправляет его в подчиненный поток ввода-вывода.
Подчиненный поток ввода-вывода получает событие и записывает его в конец файла журнала ретрансляции.
Как только событие попадает в релейный журнал, подчиненный поток SQL выполняет
событие, чтобы применить изменения к базе данных на ведомом устройстве.
В этом сценарии ведущее устройство не заботится о подчиненном устройстве, а клиент знает, что на ведомом устройстве что-то не так, вручную выполняя команду «SHOW SLAVE STATUS».
В случае полусинхронной репликации последовательность операций может быть следующей:
Клиент отправляет мастеру запрос SQL (например, вставка) с использованием транзакций.
Мастер выполняет транзакцию. В случае успеха запись сохраняется на диске, но транзакция не фиксируется.
Мастер записывает событие вставки в двоичный журнал мастера. Если мастер не может сохранить его в двоичном журнале, транзакция откатывается, и клиент получает ответ только в случае отката.
В связи с успешным выполнением транзакции на главном сервере поток дампа на главном компьютере считывает событие из двоичного журнала и отправляет его в подчиненный поток ввода-вывода.
Подчиненный поток ввода-вывода получает событие и записывает его в конец файла журнала ретрансляции.
Ведомый подтверждает мастер записи события в файле журнала реле.
Мастер фиксирует транзакцию вставки.
Клиент получает ответ от мастера (успех).
Как только событие попадает в релейный журнал, подчиненный поток SQL выполняет
событие. Мастер и клиент не знают, было ли выполнение успешным или нет.
Полусинхронная репликация разрешила один важный случай, когда ведомое устройство или сеть умерли, а ведущее устройство продолжило работу. Затем мастер умирает, и вы хотите перезапустить старого подчиненного как нового мастера только потому, что вы исправили этот узел.
Итак, вы запустили этот узел как новый мастер, вы исправили старый мастер и теперь хотите использовать его как подчиненный. На этом узле все еще есть данные, но если новый ведомый запускается с позиции, с которой начался новый ведущий, будут повторяться записи.
Если период ожидания бесконечен, то позиция главного двоичного журнала всегда будет синхронизирована с позицией журнала подчиненного реле, если предположить, что все запросы на ведомом были успешными. Насколько реалистично это предположение?
Я думаю, что это очень реалистично. Одним из наиболее распространенных случаев сбоя подчиненного запроса является «дублирующаяся запись». Где дубликат записи попал на раба, если у мастера его не было? Это пришло из неправильного положения, данного рабу, чтобы начать копировать. Начальная позиция репликации включала запись, которая уже была реплицирована. В случае полусинхронной репликации такой ситуации не будет.
Джейкоб Ником
источник
Квалификатор : я не пользователь MySQL, так что, в основном, это всего лишь мое исследование интернета.
Как я уверен, вы знаете, самое большое ограничение репликации MySQL - это то, что он однопоточный. Таким образом, пока поток занят отправкой данных внутреннему ведомому устройству, он не сможет отправить данные удаленному ведомому устройству. Это здесь .
За здесь :
Одна вещь, которую вы должны сделать, это сократить время транзакции. Это позволяет вашему потоку репликации иметь возможность узнать, что происходит в базе данных. Вы хотите, чтобы ваши транзакции были максимально короткими.
Один из способов сделать это - разделить запрос; ограничить строки, измененные с помощью UPDATE или DELETE с помощью предложений WHERE. Если вы вставите это в цикл, вы можете перебирать список, каждый раз начиная и совершая транзакцию. (ОБНОВЛЕНИЕ / УДАЛЕНИЕ первой трети, второй трети, затем последней трети каждой в своей собственной транзакции.) Я лично настоятельно рекомендую не делать этого, поскольку вы открываете себе возможность изменения данных в таблице между транзакциями. Но есть возможность улучшить эту производительность, если вы уверены, что никто не возится с таблицей (и никогда не будет) .
Другая возможность состоит в том, чтобы не реплицировать эти долго выполняющиеся транзакции, а запустить их на обоих ведущих (которые реплицируются на локальное ведомое устройство), а затем запустить их на удаленном ведомом устройстве отдельно. Это освободит поток репликации, так что он не достигнет отметки 30 с лишним минут.
За здесь :
Последняя возможность - настроить размер ваших буферов TCP. Цель состоит в том, чтобы уменьшить количество коммуникаций между ведущим и подчиненным. Это может помочь уменьшить задержку.
Лично я бы попробовал это, если все остальное терпит неудачу. Я подозреваю, что проблема больше связана с однопоточной системой репликации, а не с задержкой в сети. Сети обычно отключаются задолго до 30-минутной отметки. (30 минут?!)
Закладки JHammerb Delicious содержат несколько ссылок для репликации mysql, которые вы также можете проверить.
Надеюсь, это поможет.
источник