У меня есть ощущение, что там должны быть шаблоны синхронизации клиент-сервер. Но я совершенно не смог погуглить.
Ситуация довольно проста - сервер является центральным узлом, к которому несколько клиентов подключаются и манипулируют одними и теми же данными. Данные могут быть разделены на атомы, в случае конфликта, что бы ни находилось на сервере, имеет приоритет (чтобы не вовлечь пользователя в решение конфликта). Частичная синхронизация предпочтительна из-за потенциально больших объемов данных.
Существуют ли какие-либо модели / передовые практики для такой ситуации, или если вы не знаете о них - каков будет ваш подход?
Ниже я расскажу, как решить эту проблему: параллельно с данными будет вестись журнал изменений, в котором будут отмечены все транзакции. Когда клиент подключается, он получает все изменения со времени последней проверки в консолидированной форме (сервер просматривает списки и удаляет дополнения, за которыми следуют удаления, объединяет обновления для каждого атома и т. Д.). И вуаля, мы в курсе.
Альтернативой будет сохранение даты изменения для каждой записи, и вместо того, чтобы выполнять удаление данных, просто пометьте их как удаленные.
Есть предположения?
Ответы:
Вы должны посмотреть, как работает распределенное управление изменениями. Посмотрите на SVN, CVS и другие репозитории, которые управляют работой дельт.
У вас есть несколько вариантов использования.
Синхронизировать изменения. Ваш подход к журналу изменений (или истории дельты) выглядит хорошо для этого. Клиенты отправляют свои дельты на сервер; Сервер консолидирует и раздает дельты клиентам. Это типичный случай. Базы данных называют это «репликация транзакций».
Клиент потерял синхронизацию. Либо через резервное копирование / восстановление, либо из-за ошибки. В этом случае клиент должен получить текущее состояние с сервера, не проходя через дельты. Это копия от мастера к деталям, черт побери и производительность. Это разовая вещь; клиент сломан; не пытайтесь оптимизировать это, просто используйте надежную копию.
Клиент подозрителен. В этом случае вам необходимо сравнить клиент с сервером, чтобы определить, актуален ли клиент и какие-либо различия.
Вы должны следовать схеме проектирования базы данных (и SVN) для последовательной нумерации каждого изменения. Таким образом, клиент может сделать тривиальный запрос («Какую ревизию я должен иметь?») Перед попыткой синхронизации. И даже в этом случае запрос («Все ошибки с 2149 года») восхитительно прост для обработки клиентом и сервером.
источник
Как часть команды, я выполнил довольно много проектов, связанных с синхронизацией данных, поэтому я должен быть компетентным, чтобы ответить на этот вопрос.
Синхронизация данных - это достаточно широкое понятие, и здесь слишком много вопросов для обсуждения. Он охватывает ряд различных подходов с их достоинствами и недостатками. Вот одна из возможных классификаций, основанных на двух аспектах: Синхронный / Асинхронный, Клиент / Сервер / Одноранговый. Реализация синхронизации сильно зависит от этих факторов, сложности модели данных, объема передаваемых и хранимых данных и других требований. Таким образом, в каждом конкретном случае выбор должен быть в пользу самой простой реализации, отвечающей требованиям приложения.
Основываясь на обзоре существующих готовых решений, мы можем выделить несколько основных классов синхронизации, различающихся по степени детализации объектов, подлежащих синхронизации:
Итак, мы включили наши знания в эту статью, которая, я думаю, может быть очень полезна для всех, кто интересуется этой темой => Синхронизация данных в основных приложениях iOS на основе данных ( http://blog.denivip.ru/index.php/2014/04 / data-syncing-in-core-data-based-ios-apps /? lang = ru )
источник
Что вам действительно нужно, так это оперативное преобразование (OT). Это может даже обслуживать конфликты во многих случаях.
Это все еще активная область исследований, но есть реализации различных алгоритмов ОТ. Я принимал участие в таких исследованиях уже несколько лет, поэтому дайте мне знать, если этот маршрут вас интересует, и я буду рад предоставить вам соответствующие ресурсы.
источник
Вопрос не совсем ясен, но я бы посмотрел на оптимистическую блокировку на вашем месте. Это может быть реализовано с порядковым номером, который сервер возвращает для каждой записи. Когда клиент пытается сохранить запись обратно, он будет содержать порядковый номер, полученный от сервера. Если порядковый номер совпадает с тем, что находится в базе данных в момент получения обновления, обновление разрешается и порядковый номер увеличивается. Если порядковые номера не совпадают, обновление запрещено.
источник
Я создал такую систему для приложения около 8 лет назад, и я могу поделиться несколькими путями, по мере того, как она росла, с ростом использования приложения.
Я начал с записи каждого изменения (вставки, обновления или удаления) с любого устройства в таблицу «истории». Так, если, например, кто-то изменит свой номер телефона в таблице «контакт», система отредактирует поле contact.phone, а также добавит запись истории с действием = обновление, поле = телефон, запись = [идентификатор контакта], значение = [новый номер телефона]. Затем, когда устройство синхронизируется, оно загружает элементы истории с момента последней синхронизации и применяет их к своей локальной базе данных. Это похоже на шаблон «репликации транзакций», описанный выше.
Одной из проблем является сохранение уникальных идентификаторов, когда элементы могут быть созданы на разных устройствах. Когда я начал это, я не знал об идентификаторах UUID, поэтому я использовал автоматически увеличивающиеся идентификаторы и написал несколько извилистых кодов, которые выполняются на центральном сервере для проверки новых идентификаторов, загруженных с устройств, изменения их на уникальные идентификаторы в случае конфликта и скажите исходному устройству изменить идентификатор в своей локальной базе данных. Простое изменение идентификаторов новых записей было не так уж плохо, но если я, например, создаю новый элемент в таблице контактов, затем создаю новый связанный элемент в таблице событий, теперь у меня есть внешние ключи, которые мне также нужны проверить и обновить.
В конце концов я узнал, что UUIDs могли бы избежать этого, но к тому времени моя база данных стала довольно большой, и я боялся, что полная реализация UUID создаст проблему производительности. Поэтому вместо использования полных UUID я начал использовать случайно сгенерированные 8-символьные буквенно-цифровые ключи в качестве идентификаторов и оставил свой существующий код на месте для обработки конфликтов. Где-то между моими нынешними 8-символьными клавишами и 36 символами UUID должно быть хорошее место, которое устраняло бы конфликты без ненужного раздувания, но, поскольку у меня уже есть код разрешения конфликтов, экспериментировать с этим не было приоритетом. ,
Следующая проблема заключалась в том, что таблица истории была примерно в 10 раз больше, чем вся остальная база данных. Это делает хранение дорогим, и любое обслуживание таблицы истории может быть болезненным. Сохранение всей этой таблицы позволяет пользователям откатывать любые предыдущие изменения, но это начинало казаться излишним. Поэтому я добавил подпрограмму в процесс синхронизации, где, если элемент истории, который было загружено последним устройством, больше не существует в таблице истории, сервер не передает ему последние элементы истории, а вместо этого предоставляет файл, содержащий все данные для этот аккаунт. Затем я добавил cronjob, чтобы удалить элементы истории старше 90 дней. Это означает, что пользователи по-прежнему могут откатывать изменения менее чем за 90 дней, и если они синхронизируются хотя бы раз в 90 дней, обновления будут, как и прежде, инкрементными. Но если они ждут дольше 90 дней,
Это изменение уменьшило размер таблицы истории почти на 90%, поэтому теперь ведение таблицы истории только увеличивает базу данных в два раза, а не в десять раз больше. Еще одним преимуществом этой системы является то, что синхронизация может по-прежнему работать без таблицы истории при необходимости - например, если мне нужно выполнить какое-то обслуживание, которое временно отключило ее. Или я мог бы предложить разные периоды отката для учетных записей в разных ценовых категориях. И если для загрузки требуется более 90 дней изменений, полный файл обычно более эффективен, чем инкрементный формат.
Если бы я начинал сегодня, я бы пропустил проверку конфликта ID и просто нацелился на длину ключа, достаточную для устранения конфликтов, с какой-то проверкой ошибок на всякий случай. Но таблица истории и комбинация дополнительных загрузок для последних обновлений или полной загрузки, когда это необходимо, работала хорошо.
источник
Для дельта-синхронизации (изменения) вы можете использовать шаблон pubsub для публикации изменений на всех подписанных клиентах, такие сервисы, как pusher, могут сделать это.
Для зеркального отображения базы данных некоторые веб-фреймворки используют локальную мини-базу данных для синхронизации базы данных на стороне сервера с локальной в базе данных браузера, поддерживается частичная синхронизация. Проверьте метр .
источник