Синхронизировать данные таблицы MySQL от клиента к мастеру - PullRequest
0 голосов
/ 19 августа 2010

Я столкнулся с небольшой проблемой.История выглядит следующим образом:

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

У меня есть скрипт, который подключается к базе данных клиента, выбирает все записи из таблицы, где столбец синхронизации = '0000-00-00 00:00:00 '(по умолчанию, чтобы указать, что он не был синхронизирован).Затем я перебрал бы каждую запись, вставил ее на центральный сервер и установил время синхронизации записи базы данных клиента во время выполнения сценария.Это работает, но очевидно имеет большие накладные расходы с несколькими запросами, и я только что заметил проблемы сейчас.

Каждый клиент может генерировать до 2000 - 3000 нечетных документов в день.С этими большими числами это занимает слишком много времени (1 сек / 2 документа).

Есть ли лучшее решение моей проблемы?Предпочтительно PHP-решение на основе сценариев, так как мне нужно делать логи, чтобы проверить, все ли прошло успешно.

Спасибо

РЕДАКТИРОВАТЬ: Мой текущий процесс:

  1. Выбрать все несинхронизированные данные
  2. Начать транзакцию
  3. Вставить запись в центральный сервер базы данных
  4. Выбрать запись документа с клиента
  5. Вставитьдокумент на центральный сервер базы данных
  6. Обновление столбца синхронизации на клиенте
  7. Обновление столбца синхронизации на сервере
  8. Подтверждение транзакции

Это скриптзапустить на центральном сервере.Теперь, когда я подумаю об этом, я могу удалить шаг 7 и сделать его частью шага 5, но это не приведет к значительному сокращению времени обработки.

Ответы [ 4 ]

1 голос
/ 19 августа 2010

Я бы предложил использовать auto_increment_increment , чтобы сохранить все идентификаторы уникальными для всех серверов.Затем все, что вам нужно сделать, это SELECT * FROM blah WHERE sync = '0000-00-00 00:00:00', а затем сгенерировать операторы вставки и выполнить их.Вам не придется иметь дело с каким-либо видом разрешения конфликтов для конфликтующих первичных ключей ...

Что касается длительного времени запроса, вам нужно посмотреть на размер ваших данных.Если каждая запись имеет размер (несколько сотен килобайт +), потребуется время ...

Один из вариантов может состоять в создании таблицы federated для таблицы каждого дочернего сервера.Затем сделайте все это в SQL на мастере.INSERT INTO master_table SELECT * FROM child_1_table WHERE sync = '0000-00-00 00:00:00' ... Вы можете избежать перетаскивания всех данных в PHP.Вы все еще можете выполнить некоторые проверки, чтобы убедиться, что все прошло хорошо, и вы все еще можете войти, так как все по-прежнему выполняется из земли PHP ...

0 голосов
/ 20 августа 2010

Есть еще одна возможность, если вы не можете использовать платформу синхронизации -

Можно ли распределить нагрузку в течение дня, а не в конце дня?Скажем, запускать синхронизацию каждый раз, когда поступают 10 новых документов или 10 изменений?(это можно сделать, если синхронизация инициируется со стороны клиента).

Если вы хотите перенести логику синхронизации на серверную часть, вы можете рассмотреть возможность использования очередей обмена сообщениями для отправки на сервер уведомлений от клиентов, когда клиенту требуется синхронизация.Затем сервер может получить данные.Для этого вы можете использовать служебную шину или платформы по требованию, такие как Azure Appfabric / Amazon SQS.

0 голосов
/ 19 августа 2010

Я знаю, что вы предпочитаете решение на основе PHP, но вы можете проверить Microsoft Sync Framework -

http://msdn.microsoft.com/en-in/sync/default(en-us).aspx

Это потребует написания модуля синхронизации в .net, но есть огромное преимущество с точки зрения логики синхронизации и обработки исключений (сбой сети, конфликты синхронизации и т. д.), что сократит время для вас.

Фреймворк также обрабатывает базы данных, не относящиеся к SQL Server, если есть коннектор базы данных для .net.Mysql должен поддерживаться довольно легко - просто возьмите пример по следующей ссылке -

http://code.msdn.microsoft.com/sync/Release/ProjectReleases.aspx?ReleaseId=4835

и адаптируйте его к mysql.

0 голосов
/ 19 августа 2010

Основной метод звучит нормально - но 0,5 секунды на одну операцию смехотворно чрезмерны - сколько данных вы тянете по сети?Весь образ?Вы делаете что-нибудь еще в операции?Есть ли индекс в столбце синхронизации?

Вы можете получить небольшое преимущество, выполнив экспорт несинхронизированных данных в базу данных:

1) mark all records available for sync with a transaction id in a new column
2) extract all records flagged in first step into a flat file
3) copy the file across the network
4) load the data into the master DB
5) if successful notify the origin server
6) origin server then sets the sync time for all records flagged with that transaction id

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

Но это, вероятно, не приведет к большим проникновениямв производительность, которая кажется невероятно высокой, если вы только копируете метаданные об изображении (а не само изображение).

C.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...