Синхронизация баз данных клиент-сервер

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

в моем конкретном случае у меня есть приложение для android-телефона с базой данных sqlite и веб-приложением PHP с базой данных MySQL.

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

меня не волнует, как передавать данные с телефона на сервер или наоборот. Я упоминаю свои конкретные технологии только потому, что я не могу использовать, например, функции репликации, доступные MySQL.

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

5 ответов


первое, что вам нужно решить, это общая политика о том, какая сторона считается "авторитетной" в случае противоречивых изменений.

т. е.: предположим, запись № 125 изменена на сервере 5 января в 10 вечера и та же запись изменена на одном из телефонов (назовем ее клиент а) 5 января в 11 вечера. Последняя синхронизация была 3 января. Затем пользователь подключается, скажем, 8 января.

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

Итак, предположим, что изменяется только запись #125. Вы либо решаете, что один из двух автоматически "выигрывает" и перезаписывает другой, либо вам нужно поддерживать фазу согласования, на которой пользователь может решить, какая версия (сервер или клиент) является правильной, перезаписывая другую.

этот решение чрезвычайно важно, и вы должны взвесить "роль" клиентов. Особенно, если существует потенциальный конфликт не только между клиентом и сервером, но и в случае, если разные клиенты могут изменить одни и те же записи.

[предполагая, что #125 может быть изменен вторым клиентом (клиент B) есть шанс, что клиент B, который еще не синхронизирован, предоставит еще одну версию той же записи, что делает предыдущее разрешение конфликта спорным]

в отношении " создано или обновлено" вышеуказанного пункта... как вы можете правильно идентифицировать запись, если она была создана на одном из клиентов (предполагая, что это имеет смысл в вашем проблемном домене)? Предположим, ваше приложение управляет списком деловых контактов. Если клиент A говорит, что вам нужно добавить недавно созданный John Smith, и на сервере есть John Smith, созданный вчера клиентом D... вы создаете две записи, потому что не можете быть уверены, что это не разные люди? Вы попросите пользователя примирить и этот конфликт?

имеют ли клиенты "право собственности" на подмножество данных? Т. е. если клиент B настроен на "полномочия" по данным для области #5, Может ли клиент a изменять/создавать записи для области #5 или нет? (Это облегчило бы разрешение некоторых конфликтов, но может оказаться невозможным для вашей ситуации).

подводя итог, основные проблемы:

  • как определить "идентичность", учитывая, что отдельные клиенты, возможно, не обращались к серверу раньше создание новой записи.
  • предыдущая ситуация, независимо от того, насколько сложное решение, может привести к дублированию данных, поэтому вы должны предвидеть, как периодически их решать и как информировать клиентов о том, что то, что они считали "записью #675", фактически было объединено с/заменено записью #543
  • решите, будут ли конфликты разрешены fiat (например, " версия сервера всегда превосходит версию клиента, если первая была обновлена с последнего synch") или ручным вмешательством
  • в случае fiat, особенно если вы решите, что клиент имеет приоритет, вы также должны позаботиться о том, как иметь дело с другими, еще не синхронизированными клиентами, которые могут иметь еще некоторые изменения.
  • предыдущие элементы не учитывают детализацию ваших данных (чтобы упростить описание). Достаточно сказать, что вместо рассуждений на уровне "записи", как в моем примере, вы можете найти больше вместо этого целесообразно регистрировать изменения на уровне поля. Или работать над набором записей (например, запись человека + запись адреса + запись контактов) одновременно, рассматривая их совокупность как своего рода "мета-запись".

список литературы:

  • подробнее об этом, конечно, о Википедия.

  • простой алгоритм синхронизации автором Vdirsyncer

  • OBJC статья о синхронизации данных

  • SyncML®: синхронизация и Управление мобильными данными (книга о сафари О'Рейли)

  • бесконфликтные реплицированные типы данных

  • Оптимистической Репликации Ясуси Сайто (HP Laboratories) и Марк Шапиро (Microsoft Research Ltd.) - ACM Computing Surveys, Vol. Ви, Нет. N, 3 2005.

  • Александр Traud, Юрген Наглер-Ihlein, Фрэнк Kargl, и Майкл Вебер. 2008. Циклическая синхронизация данных путем повторного использования SyncML. В материалах девятой Международной конференции по управлению мобильными данными (MDM ' 08). IEEE Computer Society, Washington, DC, USA, 165-172. DOI=10.1109 / MDM.2008.10 http://dx.doi.org/10.1109/MDM.2008.10

  • Лам, Ф. Лам, Н. и Вонг, Р. 2002. Эффективная синхронизация для мобильных XML-данных. В материалах одиннадцатой международной конференции по управлению информацией и знаниями (Маклин, Вирджиния, США, 04 - 09 ноября 2002 года). CIKM ' 02. АСМ, Нью-Йорк, Нью-Йорк, 153-160. DOI= http://doi.acm.org/10.1145/584792.584820

  • Кунья, П. Р. и Maibaum, Т. С. 1981. Ресурс & equil; абстрактный тип данных + синхронизация-методология программирования сообщений -. В Материалы 5 - й Международной конференции по разработке программного обеспечения (Сан-Диего, Калифорния, Соединенные Штаты, 09-12 марта 1981 года). Международная конференция по программной инженерии. IEEE Press, Piscataway, NJ, 263-272.

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

с Доктор Доббс сайт:

  • создание приложений с помощью SQL Server CE и SQL RDA by Bill Wagner May 19, 2004 (рекомендации по разработке приложений для настольных и мобильных ПК - Windows/.NET)

от arxiv.org:

  • бесконфликтный Реплицированный тип данных JSON - в статье описывается реализация JSON CRDT (бесконфликтные реплицированные типы данных-CRDTs - семейство структур данных, поддерживающих параллельную модификацию и гарантирующих сходимость таких параллельных новинки.)

Если кто-то имеет дело с аналогичной проблемой дизайна и должен синхронизировать изменения на нескольких устройствах Android, я рекомендую проверить Google Cloud Messaging для Android (GCM).

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

в основном, каждый клиент отправляет Дельта-изменения на сервер. Например. идентификатор ресурса ABCD1234 изменился со значения 100 на 99.

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

Если изменение одобрено сервером, сервер уведомляет других клиентов (за исключением того, кто отправил Дельта-изменение) через GCM и отправляет многоадресное сообщение с тем же Дельта-изменением. Клиенты обрабатывают это сообщение и обновляет свою базу данных.

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

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

проверить тоже в этом уроке чтобы начать работу с реализацией клиента CGM.


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

наблюдение 1: имейте в виду физические удаления, так как строки удаляются из исходной БД, и вы должны сделать то же самое на сервер БД. Вы можете решить эту проблему, избегая физических удалений или регистрации каждого удаления в таблице с метками времени. Что-то вроде этого:--0--> Итак, вы должны прочитать все новые строки таблицы DeletedRows и выполнить удаление на сервере, используя table_name, pk_column и pk_column_value.

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


это отвечает разработчикам, которые используют платформу Xamarin (см. https://stackoverflow.com/questions/40156342/sync-online-offline-data)

очень простой способ достичь этого с помощью платформы xamarin-использовать автономную синхронизацию данных Azure, поскольку она позволяет передавать и извлекать данные с сервера по требованию. Операции чтения выполняются локально, а операции записи выполняются по требованию; если сетевое подключение прерывается, операции записи ставятся в очередь до соединение восстанавливается, затем выполняется.

реализация довольно проста:

1) Создайте мобильное приложение на портале azure (вы можете попробовать его бесплатно здесьhttps://tryappservice.azure.com/)

2) подключите клиент к мобильному приложению. https://azure.microsoft.com/en-us/documentation/articles/app-service-mobile-xamarin-forms-get-started/

3) Код для установки локальной репозиторий:

const string path = "localrepository.db";

//Create our azure mobile app client
this.MobileService = new MobileServiceClient("the api address as setup on Mobile app services in azure");

//setup our local sqlite store and initialize a table
var repository = new MobileServiceSQLiteStore(path);

// initialize a Foo table
store.DefineTable<Foo>();

// init repository synchronisation
await this.MobileService.SyncContext.InitializeAsync(repository);
var fooTable = this.MobileService.GetSyncTable<Foo>();

4) после этого нажать и вытянуть ваши данные для обеспечения что мы имеем самые последние изменения:

await this.MobileService.SyncContext.PushAsync();
await this.saleItemsTable.PullAsync("allFoos", fooTable.CreateQuery());

https://azure.microsoft.com/en-us/documentation/articles/app-service-mobile-xamarin-forms-get-started-offline-data/


Я предлагаю вам также взглянуть на Symmetricds. это библиотека репликации SQLite, доступная для систем android. вы можете использовать его для синхронизации клиентской и серверной базы данных, я также предлагаю иметь отдельные базы данных на сервере для каждого клиента. Попытка удержать данные всех пользователей в одной базе данных mysql не всегда является лучшей идеей. Особенно если пользовательские данные будут быстро расти.