Как вы управляете двусторонней синхронизацией между «основным» сервером базы данных и многими «вторичными» серверами, в частности разрешением конфликтов, при условии, что соединение не всегда доступно?
Например, у меня есть мобильное приложение, которое использует CoreData в качестве «базы данных» на iOS, и я хотел бы позволить пользователям редактировать содержимое без подключения к Интернету. В то же время эта информация доступна на веб-сайте, к которому будут подключаться устройства. Что мне делать, если / когда данные на двух серверах БД конфликтуют?
(Я называю CoreData сервером БД, хотя я знаю, что это немного другое.)
Существуют ли какие-либо общие стратегии для решения этой проблемы? Вот варианты, которые я могу придумать:
1. Всегда использовать данные на стороне клиента в качестве более высокого приоритета.
2. То же самое для стороны на сервере.
3. Попробуйте разрешить конфликты, отметив метку времени для каждого поля и выполнив последнее изменение.
Хотя я уверен, что третий вариант откроет место для разрушительного повреждения данных.
Я знаю, что теорема CAP касается этого, но мне нужна только возможная последовательность, поэтому она не исключает ее полностью, верно?
Смежный вопрос: Лучшие практики для двусторонней синхронизации данных . Второй ответ на этот вопрос говорит, что это, вероятно, не может быть сделано.
Ответы:
Обычное решение для того, чтобы знать, «какое изменение является правильным», - это векторные часы . По сути, вы отслеживаете счетчики для каждого репозитория, в котором хранятся данные, и отклоняете изменения, если точка зрения конкретного клиента на состояние других пользователей отличается от точки зрения партнера, к которому он подключается.
Большой вопрос, на который вам нужно ответить, - как вы решите отклоненные сохранения. Обычно это означает какую-то операцию слияния.
Обратите внимание, что векторные часы не используют метки времени в реальном времени. Проблемы, связанные с синхронизацией часов реального времени, не менее сложны, чем синхронизация данных.
источник
Это проблема византийских генералов , которая неразрешима. Вы никогда не сможете гарантировать синхронизацию двух серверов, если не можете гарантировать, что когда- нибудь в будущем у вас будет достаточно надежной полосы пропускания для выполнения синхронизации всего за один раз.
источник
Я думаю, что не существует стандартного способа сделать это, каждая система использует свои собственные политики для разрешения конфликтов.
Я провел несколько симуляций, используя два устройства, компьютер и телефон, и электронную таблицу Google, чтобы проверить, как Google Docs автоматически обрабатывает конфликты. Вот несколько случаев:
Случай 1
Дело 2
Таким образом, по крайней мере сервер Google Docs использует последние данные, которые он получил, как более высокий приоритет независимо от того, когда он был создан (временная метка клиента). Я также проверил, выполняют ли они синхронизацию в фоновом режиме, и, по-видимому, они этого не делают, поэтому результат разрешения конфликта прозрачен для пользователя.
GIT, с другой стороны, не обрабатывает конфликты автоматически, а вместо этого делегирует последнему пользователю, который пытался изменить хранилище, способ слияния.
Я бы пошел на подход Google Docs, если это нормально, синхронизировать только на переднем плане, с пользователем, визуализирующим данные. В противном случае пользователь может быть удивлен тем, что, хотя его телефон автоматически подключался к WiFi, несинхронное изменение к собранию, которое он после повторного редактирования на своем компьютере, стало возможным.
Я бы предпочел подход с метками времени клиента, переопределяя конфликты с последними отредактированными, если вам нужна фоновая синхронизация, может доверять метке времени клиента, а стоимость нежелательного слияния меньше, чем стоимость запроса пользователя, чтобы выбрать, какую версию он хочет хранить.
В противном случае я бы пошел к подходу GIT, показав всплывающее окно в следующем клиенте на переднем плане, в котором пользователь должен выбрать, какую версию сохранить, или дать возможность отменить слияние.
источник