Подтвердить что ты не робот

Какой самый умный и простой подход к синхронизации данных между несколькими объектами?

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

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

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

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

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

4b9b3361

Ответ 1

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Синхронизация является атомарной, поэтому, если одна запись терпит неудачу, весь процесс помечается как неполный, аналогичный транзакции фиксации subversion.

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

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

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

Ответ 2

Наверное, "Не настоящий вопрос", здесь нет реального ответа:

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

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

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

Ответ 3

Спасибо за подробный ответ GaZ. У меня есть несколько следующих вопросов:

Если вы используете временные метки, как вы обрабатываете неточные настройки времени (небольшие различия, например, 1-5 секунд)? Как часто они появляются вообще? Не лучше ли управление версиями (например, SVN) для обработки различных изменений данных?

Я понимаю, что вы только извлекаете данные между двумя метками времени, last_synchronisation_date (для каждого клиента) и теперь?

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