Назад | Перейти на главную страницу

Как я могу централизовать данные MySQL между 3 или более географически отдельными серверами?

Чтобы объяснить предысторию вопроса:

У нас есть собственное PHP-приложение (для запуска онлайн-курсов по изучению языков), работающее на сервере Linux и использующее MySQL на локальном хосте для сохранения пользовательских данных (например, результатов проведенных тестов, отметок отправленных работ, времени, проведенного на разных страницах в курсы и т. д.).

Поскольку у нас есть студенты из разных географических регионов, в настоящее время у нас есть 3 виртуальных сервера, размещенных рядом с этими местами (Испания, Великобритания и Гонконг), и пользователи добавляются на ближайший к ним сервер (они получают доступ через разные URL-адреса, например, europe.domain.com. , uk.domain.com и asia.domain.com). Это работает, но является административным кошмаром, поскольку мы должны помнить, на каком сервере находится конкретный пользователь, а пользователи могут подключаться только к одному серверу. Мы хотели бы каким-то образом централизовать информацию, чтобы все пользователи были видны на любом из серверов, а пользователи могли подключаться к любому из 3 серверов.

Вопрос в том, какой метод мы должны использовать для этого. Должно быть, это проблема, с которой сталкивались многие люди, но я не нашел ничего убедительного после некоторого количества поисков в Google. Ближайшие к решениям, которые я видел, следующие:

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

Спасибо,

Энди

P.S. Я должен добавить, что мы экспериментировали с записью в центральную базу данных, а затем использовали чтение из локальной базы данных, но время отклика между разными серверами для записи было довольно плохим, и также важно, чтобы записанные данные были доступны для чтения немедленно, поэтому, если репликация слишком медленно это может привести к возврату устаревших данных.

Редактировать: Я думал о написании моего собственного рудиментарного сценария репликации, который предполагал бы что-то вроде того, чтобы каждому пользователю давался идентификатор сервера, чтобы указать, какой из них является его «домашним сервером», например пользователи в азии будут отмечены как имеющие сервер в Гонконге в качестве собственного сервера. Затем сценарии репликации (которые будут сценарием PHP, настроенным для запуска в качестве задания cron достаточно часто, например, каждые 15 минут или около того) будут запускаться независимо на каждом из серверов в системе. Они будут проходить через базу данных и распространять любую информацию о пользователях с «домашним сервером», установленным на сервере, на котором выполняется сценарий, всем другим базам данных в системе. Им также потребуется получить новую информацию, которая была добавлена ​​в любую из других баз данных в системе, где флаг «домашний сервер» - это сервер, на котором выполняется сценарий. Мне нужно было бы проработать детали и встроить логику для разрешения конфликтов, но я думаю, что это возможно, однако я хотел убедиться, что нет верный решение для этого уже существует, поскольку кажется, что это проблема, с которой уже сталкивались многие люди.

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

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

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

Проблема auto_increment легко решается с помощью auto_increment_increment и auto_increment_offset.

Контролировать репликацию на всех экземплярах с относительно высокой частотой и исправлять источники всего, что приводит к сбою репликации или смещению ваших данных. Мааткитконтрольная сумма mk-table и mk-table-sync хороши для идентификация дрейфующие данные. Надо попасть в двоичные журналы и код, чтобы идентифицировать источники ... :)

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

Проблема, которую вы описываете, действительно звучит как случай передачи данных пользователем по требованию.

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

Редактировать: ... и пока вы это делаете, возможно, вы могли бы добавить суффикс к именам пользователей в каждом из ваших экземпляров, чтобы пользователи могли указать (путем предоставления своих имен пользователей), на каком сервере зарегистрирована их учетная запись, когда они запрашивают помощь.

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

Если у вас есть мониторинг в реальном времени, вы можете поддерживать кольцо в рабочем состоянии с помощью CHANGE MASTER TO (сначала вам нужно остановить ведомое устройство). Это позволяет вам переключаться с мастер-мастер-мастер на мастер-мастер и обратно на лету. Это поможет только в сочетании с активным механизмом аварийного переключения, который срабатывает и направляет пользователей на активный сайт, а не на «локальный» (который в настоящее время не работает).

У меня было только два сайта и два сервера на каждом сайте (вместо вашей модели «один сервер на сайт»). Потенциальным решением в нашем случае было создание кластера MySQL NDB на каждом сайте, который поддерживал экземпляры MySQL для каждого сайта, и создание кольца репликации между экземплярами MySQL. Это будет означать, что потеря сайта (или связи между сайтами) не потребует каких-либо аварийных изменений, и все выздоровеет после восстановления неисправного сайта.

Если вы хотите изменить свой уровень доступа к данным и модель данных, и вы хотите, чтобы данные хранились где-то помимо ваших серверов, вы можете попробовать службу распределенной БД, такую ​​как http://aws.amazon.com/simpledb/

Давайте подумаем о простом сценарии, когда все серверы баз данных (Server 1, Server2 и server3) географически расположены на разных сайтах, связанных через VPN или какую-либо другую сеть, в которой могут быть сбои связи. Мы планируем смену мастера каждые 10 минут.

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

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

Сервер 1

Сценарий 1 выполняется в течение 10 минут, затем выполняется цепочка к сценарию 2:

  • Остановить раба
  • Измените мастер на сервер 2
  • Запустить раб

Сценарий 2 выполняется в течение 10 минут, затем выполняется переход к сценарию 1:

  • Остановить раба
  • Измените мастер на сервер 3
  • Запустить раб

Сервер 2

Сценарий 1 выполняется в течение 10 минут, затем выполняется цепочка к сценарию 2:

  • Остановить раба
  • Измените мастер на сервер 3
  • Запустить раб

Сценарий 2 выполняется в течение 10 минут, затем выполняется переход к сценарию 1:

  • Остановить раба
  • Измените мастер на сервер 1
  • Запустить раб

Сервер 3

Сценарий 1 выполняется в течение 10 минут, затем выполняется цепочка к сценарию 2:

  • Остановить раба
  • Измените мастер на сервер 1
  • Запустить раб

Сценарий 2 выполняется в течение 10 минут, затем выполняется переход к сценарию 1:

  • Остановить раба
  • Измените мастер на сервер 2
  • Запустить раб

Это похоже на запланированную синхронизацию между мастерами.

Любые комментарии приветствуются.