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



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



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



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



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



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

1312   5  

5 ответов:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  • Оптимистической Репликации Ясуси Сайто (HP Laboratories) и Марк Шапиро (Microsoft Research Ltd.) - ACM Вычислительные Исследования, Т. Ви, Нет. N, 3 2005.

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

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

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

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

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

  • создание приложений с помощью SQL Сервер CE и SQL RDA от Bill Wagner 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: помните о физических удалениях, так как строки удаляются из исходной БД, и вы должны сделать то же самое в сервер БД. Вы можете решить эту проблему, избегая физических удалений или регистрируя каждое удаление в таблице с метками времени. Что-то вроде этого: DeletedRows = (id, table_name, pk_column, pk_column_value, timestamp) Итак, вы должны прочитать все новые строки таблицы 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 не всегда является лучшей идеей. Особенно если пользовательские данные будут быстро расти.

Comments

    Ничего не найдено.