Какой самый умный и простой подход для синхронизации данных между несколькими объектами? - PullRequest
43 голосов
/ 19 января 2010

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

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

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

  • Какие самые последние данные? Как я хочу это представить?
  • Что мне делать в случае конфликта? Слияние? Я спрашиваю и спрашиваю пользователя, что делать?
  • Что мне делать, когда я нахожусь в несовместимом состоянии (например, отключение из-за ненадежного подключения к мобильной сети)?
  • Что мне делать, если я не хочу входить в противоречивое состояние?
  • Как возобновить текущую синхронизацию, которая была прервана?
  • Как мне обращаться с хранилищем данных (например, база данных MySQL в веб-службе, Core Data на iPhone; и как объединять / синхронизировать данные без большого количества связующего кода)?
  • Как мне обрабатывать правки пользователя, которые происходят во время синхронизации (которая выполняется в фоновом режиме, чтобы пользовательский интерфейс не блокировался)?
  • Как и в каком направлении я распространяю изменения (например, пользователь создает запись «Foo» на своем компьютере и не синхронизируется; затем он на ходу и создает другую запись «Foo»; что происходит, когда он пытается синхронизировать оба устройства)? Будет ли у пользователя две записи «Foo» с разными уникальными идентификаторами? Будет ли у пользователя только одна запись, но какая?
  • Как мне обрабатывать синхронизацию, когда у меня есть иерархические данные? Низходящий? Вверх дном? Я рассматриваю каждую запись атомарно или я смотрю только на суперузел? Насколько велик компромисс между упрощением вещей и затрачиванием слишком большого количества времени на реализацию?
  • ...

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

Ответы [ 3 ]

47 голосов
/ 19 января 2010

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

Итак, чтобы ответить на ваши вопросы:

  • Какие самые последние данные? Как я хочу это представить?

У нас есть столбец LAST_UPDATED_DATE в каждой таблице. Сервер отслеживает, когда происходят синхронизации, поэтому, когда автономное приложение запрашивает синхронизацию, сервер говорит: «Эй, дай мне только данные, измененные с этой даты».

  • Что мне делать в случае конфликта? Слияние? Должен ли я спросить и спросить пользователю что делать?

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

  • Что мне делать, если я не хочу вступать в противоречие состояние
  • Как возобновить текущую синхронизацию, которая была прервана?

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

  • Как мне обращаться с хранилищем данных (например, база данных MySQL в веб-сервисе, Core Данные на айфон; и как мне объединить / синхронизировать данные без большого количества клей код)?

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

  • Как мне обрабатывать правки пользователя, которые происходят во время синхронизации (который работает в фоновом режиме, поэтому Пользовательский интерфейс не заблокирован)?

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

  • Как и в каком направлении я распространяю изменения (например, пользователь создает запись «Foo» на его компьютере и не синхронизируется; тогда он на ходу и создает другую запись «Foo»; какие происходит, когда он пытается синхронизировать оба устройства)? Будет ли у пользователя два «Foo» записи с разными уникальными идентификаторами? Будет ли у пользователя только одна запись, но какой?

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

  • Как мне обрабатывать синхронизацию, когда у меня есть иерархические данные? Низходящий? Вверх дном? Я лечу каждую запись атомно или я только смотрю на supernode

The SynisДействие является атомарным, поэтому, если одна запись заканчивается неудачей, весь процесс помечается как незавершенный, аналогично транзакции фиксации Subversion.

  • Насколько велик компромисс между упрощением вещей и инвестированием слишком много времени на реализацию?

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

Надеюсь, это поможет вам или, по крайней мере, даст вам несколько идей! :)

4 голосов
/ 19 января 2010

Вероятно, "не реальный вопрос", здесь нет реального ответа:

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

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

В то же время, подход iTunes-iPod является самым простым: у вас есть только один мастербиблиотека и каждое устройство тянет оттуда.Очевидно, что синхронизация с одним мастером не очень удовлетворительна во всех сценариях (особенно когда задействовано более одного пользователя), но, тем не менее, я был бы признателен, если бы больше приложений предлагали возможность работать таким образом (pet peeve: у меня три Macс тремя установками iPhoto. Если бы они автоматически синхронизировались с одного выделенного мастера, точно так же, как фотографии синхронизируются с моим iPod, это было бы улучшением).

0 голосов
/ 19 января 2010

Хотя это действительно полезно в экосистеме Microsoft, вы можете изучить Блоки мобильных приложений .

...