Rozwiązywanie konfliktów dla synchronizacji dwukierunkowej

24

Jak zarządzasz dwukierunkową synchronizacją między „głównym” serwerem bazy danych a wieloma „wtórnymi” serwerami, w szczególności rozwiązywaniem konfliktów, zakładając, że połączenie nie zawsze jest dostępne?

Mam na przykład aplikację mobilną, która używa CoreData jako „bazy danych” na iOS i chciałbym umożliwić użytkownikom edycję treści bez połączenia z Internetem. Jednocześnie informacje te są dostępne na stronie internetowej, z którą połączą się urządzenia. Co mam zrobić, jeśli / kiedy dane na dwóch serwerach DB są w konflikcie?
(Mówię o CoreData jako o serwerze DB, choć wiem, że jest to coś nieco innego).

Czy istnieją jakieś ogólne strategie radzenia sobie z tego rodzaju problemem? Są to opcje, o których mogę myśleć:
1. Zawsze używaj danych po stronie klienta o wyższym priorytecie
2. Tak samo po stronie serwera
3. Spróbuj rozwiązać konflikty, zaznaczając znacznik czasu edycji każdego pola i dokonując ostatniej edycji

Chociaż jestem pewien, że trzecia opcja otworzy miejsce na druzgocące uszkodzenie danych.

Wiem, że twierdzenie CAP dotyczy tego, ale chcę tylko ostatecznej spójności, więc nie wyklucza to całkowicie, prawda?

Powiązane pytanie: wzorce najlepszych praktyk w zakresie dwukierunkowej synchronizacji danych . Druga odpowiedź na to pytanie mówi, że prawdopodobnie nie można tego zrobić.

K.Steff
źródło

Odpowiedzi:

14

Zwykłym rozwiązaniem pozwalającym stwierdzić, „która zmiana jest poprawna”, jest zegar wektorowy . Zasadniczo śledzisz liczniki dla każdego repozytorium, które przechowuje dane, i odrzucasz zmiany, jeśli pogląd konkretnego klienta na stan wszystkich innych osób różni się od poglądu peera, z którym się łączy.

Najważniejsze pytanie, na które musisz odpowiedzieć, brzmi: w jaki sposób rozwiążesz odrzucone zapisy. Ogólnie oznacza to operację scalania.

Pamiętaj, że zegary wektorowe nie używają znaczników czasu w czasie rzeczywistym. Problemy związane z synchronizacją zegarów czasu rzeczywistego są co najmniej tak trudne, jak synchronizacja danych.

parsifal
źródło
1
Fajnie, tego właśnie szukałem
K.Steff,
10

Jest to problem generałów bizantyjskich , którego nie można rozwiązać. Nigdy nie możesz zagwarantować synchronizacji dwóch serwerów, jeśli nie możesz zagwarantować, że w przyszłości będziesz mieć wystarczającą niezawodną przepustowość, aby przeprowadzić synchronizację za jednym razem.

DeadMG
źródło
Ok, ale w jaki sposób ci faceci uzyskują podobny efekt: Rozwój
Syncpoint
3
Zakładają po prostu, że w przyszłości będziesz mieć niezawodne połączenie o wystarczającej przepustowości.
DeadMG
1

Myślę, że nie ma standardowego sposobu, aby to zrobić, każdy system stosuje własne zasady rozwiązywania konfliktów.

Przeprowadziłem kilka symulacji przy użyciu dwóch urządzeń: komputera i telefonu oraz arkusza kalkulacyjnego Google, aby sprawdzić, jak Dokumenty Google automatycznie obsługują konflikty. Oto kilka przypadków:

Przypadek 1

  1. Komputer i telefon są w trybie offline
  2. Komputerowo edytuj komórkę o wartości „komputer”, a po telefonie edytuj komórkę o wartości „telefon”
  3. Komputer stał się online
  4. Telefon staje się online, a zarówno komputer, jak i telefon wyświetlają „telefon”.

Przypadek 2

  1. Komputer i telefon są w trybie offline
  2. Komputerowo edytuj komórkę o wartości „komputer”, a po telefonie edytuj komórkę o wartości „telefon”
  3. Telefon staje się online
  4. Komputer staje się online, a zarówno komputer, jak i telefon wyświetlają „komputer”.

Tak więc przynajmniej serwer Google Docs wykorzystuje ostatnie otrzymane dane jako wyższy priorytet niezależnie od tego, kiedy zostały utworzone (znacznik czasu klienta). Testowałem też, czy synchronizują się w tle i najwyraźniej nie, więc wynik rozwiązania konfliktu jest przezroczysty dla użytkownika.

Z drugiej strony GIT nie obsługuje automatycznie konfliktów, ale przekazuje dane ostatniemu użytkownikowi, który próbował zmienić repozytorium, jak należy wykonać scalanie.

Wybrałbym podejście do Dokumentów Google, jeśli synchronizacja jest możliwa tylko na pierwszym planie, a użytkownik wizualizuje dane. W przeciwnym razie użytkownik może być zaskoczony, że podczas gdy jego telefon automatycznie łączył się z siecią Wi-Fi, nie zsynchronizowana zmiana spotkania, które po ponownej edycji na komputerze uruchomiła.

Wybrałbym podejście klienta dotyczące znacznika czasu, zastępując konflikty z ostatnio edytowanym, jeśli potrzebujesz synchronizacji w tle, możesz zaufać znacznikowi czasu klienta, a koszt niepożądanego scalenia jest mniejszy niż koszt żądania od użytkownika wyboru, którą wersję chce do zachowania.

W innym przypadku wybrałbym podejście GIT, wyświetlając wyskakujące okienko w następnym kliencie na pierwszym planie, prosząc użytkownika o wybranie wersji do zachowania lub dając szansę cofnięcia scalenia.

Allan Veloso
źródło
1
Zgadzam się, że podejście indywidualne jest właściwym sposobem na przejście tutaj. „Najlepszy” sposób (podejście git) nie zawsze ma zastosowanie, ponieważ użytkownicy mogą nie chcieć sprawdzać / scalać zmian
K.Steff,