Schemat / algorytm synchronizacji klient-serwer?

Mam wrażenie, że muszą istnieć Schematy synchronizacji klient-serwer. Ale zupełnie nie udało mi się wygooglować jednego.

Sytuacja jest dość prosta-serwer jest centralnym węzłem, do którego łączy się wielu klientów i manipuluje tymi samymi danymi. Dane można podzielić na atomy, w przypadku konfliktu, cokolwiek jest na serwerze, ma priorytet (aby uniknąć wciągnięcia użytkownika w rozwiązywanie konfliktów). Częściowa synchronizacja jest preferowana ze względu na potencjalnie duże ilości data.

Czy są jakieś wzorce / dobre praktyki w takiej sytuacji, lub jeśli o nich nie wiesz - jakie byłoby twoje podejście?

Poniżej jest jak teraz myślę, aby go rozwiązać: Równolegle do danych będzie prowadzony dziennik modyfikacji, z oznaczeniem czasu wszystkich transakcji. Gdy klient łączy się, otrzymuje wszystkie zmiany od ostatniego sprawdzenia, w formie skonsolidowanej (serwer przechodzi przez listy i usuwa dodatki, po których następuje usunięcie, łączy aktualizacje dla każdego atomu, itp.). Et voila, we are na bieżąco.

Alternatywą byłoby zachowanie daty modyfikacji dla każdego rekordu i zamiast usuwania danych, po prostu oznacz je jako usunięte.

Jakieś pomysły?

Author: Jonas, 2009-01-05

7 answers

Powinieneś przyjrzeć się, jak działa rozproszone zarządzanie zmianami. Spójrz na SVN, CVS i inne repozytoria, które zarządzają deltami pracy.

Masz kilka przypadków użycia.

  • Synchronizuj zmiany. Twoje podejście do dziennika zmian (lub historii delta) wygląda dobrze. Klienci wysyłają swoje delty do serwera; serwer konsoliduje i dystrybuuje delty do klientów. To typowy przypadek. Bazy danych nazywają to "replikacją transakcji".

  • Klient przegrał synchronizacja. Albo przez kopię zapasową / przywracanie lub z powodu błędu. W takim przypadku Klient musi uzyskać aktualny stan z serwera bez przechodzenia przez delty. To jest kopia od mistrza do detalu, delty i wydajność niech będą przeklęte. To jednorazowa rzecz; klient jest uszkodzony; nie próbuj tego optymalizować, po prostu zaimplementuj wiarygodną kopię.

  • Klient jest podejrzliwy. W takim przypadku musisz porównać klienta z serwerem, aby ustalić, czy klient jest aktualny i potrzebuje delty.

Należy postępować zgodnie z wzorcem projektowym bazy danych (i SVN) sekwencyjnego numerowania każdej zmiany. W ten sposób klient może złożyć banalne żądanie ("jaką rewizję powinienem mieć?") przed próbą synchronizacji. I nawet wtedy zapytanie ("wszystkie delty od 2149") jest zachwycająco proste do przetworzenia przez Klienta i serwer.

 89
Author: S.Lott,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-01-05 13:47:02

Jako członek zespołu wykonałem sporo projektów, które wymagały synchronizacji danych, więc powinienem być kompetentny, aby odpowiedzieć na to pytanie.

Synchronizacja danych jest dość szerokim pojęciem i jest zbyt wiele do omówienia. Obejmuje szereg różnych podejść z ich zaletami i wadami. Oto jedna z możliwych klasyfikacji oparta na dwóch perspektywach: Synchroniczna / asynchroniczna, klient / serwer / Peer-to-Peer. Implementacja synchronizacji jest w znacznym stopniu zależna od tych czynników, dane złożoność modelu, ilość przesyłanych i przechowywanych danych oraz inne wymagania. Tak więc w każdym konkretnym przypadku wybór powinien być na korzyść najprostszej implementacji spełniającej wymagania aplikacji.

Na podstawie przeglądu istniejących gotowych rozwiązań możemy wyróżnić kilka głównych klas synchronizacji, różniących się ziarnistością obiektów podlegających synchronizacji:

  • Synchronizacja całego dokumentu lub bazy danych jest używana w aplikacjach chmurowych, takich jak Dropbox, Google Napęd lub Yandex.Dysk. Gdy użytkownik edytuje i zapisuje plik, nowa wersja pliku jest przesyłana do chmury całkowicie, zastępując wcześniejszą kopię. W przypadku konfliktu obie wersje plików są zapisywane, dzięki czemu użytkownik może wybrać, która wersja jest bardziej odpowiednia.
  • Synchronizacja par klucz-wartość może być używana w aplikacjach o prostej strukturze danych, gdzie zmienne są uważane za atomowe, tzn. nie są podzielone na logiczne składniki. Ta opcja jest podobna do synchronizacji całych dokumentów, ponieważ zarówno wartość, jak i dokument można całkowicie nadpisać. Jednak z punktu widzenia użytkownika dokument jest złożonym obiektem złożonym z wielu części, ale para klucz-wartość to tylko krótki łańcuch lub liczba. Dlatego w tym przypadku możemy użyć prostszej strategii rozwiązywania konfliktów, biorąc pod uwagę wartość bardziej odpowiednią, jeśli była to ostatnia zmiana.
  • Synchronizacja danych o strukturze drzewa lub wykresu jest używana w bardziej zaawansowanych aplikacjach, w których ilość danych jest duża wystarczy wysłać bazę danych w całości przy każdej aktualizacji. W tym przypadku konflikty muszą być rozwiązywane na poziomie poszczególnych obiektów, pól lub relacji. Skupiamy się przede wszystkim na tej opcji.

Tak więc, wzięliśmy naszą wiedzę do tego artykułu, który myślę, że może być bardzo przydatny dla wszystkich zainteresowanych tematem = > Synchronizacja danych w podstawowych aplikacji iOS opartych na Danych(http://blog.denivip.ru/index.php/2014/04/data-syncing-in-core-data-based-ios-apps/?lang=en)

 33
Author: Denis Bulichenko,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-16 06:22:00

To, czego naprawdę potrzebujesz, to transformacja operacyjna (OT). Może to nawet zaspokoić konflikty w wielu przypadkach.

Jest to nadal aktywny obszar badań, ale istnieją implementacje różnych algorytmów OT. Jestem zaangażowany w takie badania od wielu lat, więc daj mi znać, jeśli ta trasa Cię zainteresuje, a chętnie przekażę Ci odpowiednie zasoby.

 29
Author: Daniel Paull,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-01-05 13:50:49

Pytanie nie jest jasne, ale na Twoim miejscu przyjrzałbym się optymistycznemu blokowaniu. Może być zaimplementowany z numerem sekwencji, który serwer zwraca dla każdego rekordu. Gdy klient spróbuje zapisać rekord z powrotem, będzie zawierał numer sekwencji, który otrzymał z serwera. Jeśli numer sekwencji odpowiada temu, co znajduje się w bazie danych w momencie otrzymania aktualizacji, aktualizacja jest dozwolona, a numer sekwencji jest zwiększany. Jeśli numery sekwencji nie pasują, aktualizacja jest zabroniona.

 13
Author: erikkallen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-01-05 13:32:22

Zbudowałem taki system dla aplikacji około 8 lat temu i mogę podzielić się kilkoma sposobami, które ewoluowały wraz ze wzrostem użycia aplikacji.

Zacząłem od zapisywania każdej zmiany (wstawiania, aktualizowania lub usuwania) z dowolnego urządzenia do tabeli" historia". Jeśli więc, na przykład, ktoś zmieni swój numer telefonu w tabeli "kontakt", system będzie edytować kontakt.pole telefon, a także dodać rekord historii z action = update, table = contact, field = phone, record = [ID kontaktu], value=[nowy numer telefonu]. Następnie za każdym razem, gdy urządzenie się synchronizuje, pobiera elementy historii od ostatniej synchronizacji i stosuje je do lokalnej bazy danych. Brzmi to jak opisany powyżej wzór "replikacji transakcji".

Jednym z problemów jest zachowanie unikalnych identyfikatorów, gdy elementy mogą być tworzone na różnych urządzeniach. Nie wiedziałem o uuid, kiedy to zacząłem, więc użyłem Auto-incrementing ID i napisał kilka zawiłych kodu, który działa na centralnym serwerze, aby sprawdzić nowe ID przesłane z urządzeń, zmienić je na unikalny ID, jeśli jest konflikt i powiedz urządzeniu źródłowemu, aby zmieniło identyfikator w lokalnej bazie danych. Sama zmiana ID nowych rekordów nie była taka zła, ale jeśli utworzę na przykład nową pozycję w tabeli kontaktów, a następnie utwórz nową powiązaną pozycję w tabeli zdarzeń, teraz mam klucze obce, które również muszę sprawdzić i zaktualizować.

W końcu dowiedziałem się, że uuid może tego uniknąć, ale do tego czasu moja baza danych stała się dość duża i bałem się, że pełna implementacja uuid stworzy wydajność problem. Zamiast używać pełnych uuid, zacząłem używać losowo generowanych, 8-znakowych kluczy alfanumerycznych jako identyfikatorów i zostawiłem mój istniejący kod na miejscu, aby poradzić sobie z konfliktami. Gdzieś pomiędzy moimi obecnymi 8-znakowymi kluczami i 36 znakami UUID musi być sweet spot, który eliminowałby konflikty bez zbędnego nadęcia, ale ponieważ mam już kod rozwiązywania konfliktów, nie było priorytetem eksperymentowanie z tym.

Kolejnym problemem było to, że tabela historii była około 10 razy większa niż cała reszta bazy danych. To sprawia, że przechowywanie jest drogie, a każda konserwacja na stole historii może być bolesna. Utrzymanie tej całej tabeli pozwala użytkownikom cofnąć wszelkie poprzednie zmiany, ale to zaczęło wydawać się przesadą. Dodałem więc procedurę do procesu synchronizacji, w której jeśli element historii ostatnio pobrany przez urządzenie nie istnieje już w tabeli historii, serwer nie daje mu ostatnich elementów historii, ale zamiast tego daje mu plik zawierający wszystkie elementy historii. dane do tego konta. Następnie dodałem cronjob, aby usunąć elementy historii starsze niż 90 dni. Oznacza to, że użytkownicy nadal mogą cofnąć zmiany sprzed 90 dni, a jeśli synchronizują się co najmniej raz na 90 dni, aktualizacje będą przyrostowe, jak wcześniej. Ale jeśli będą czekać dłużej niż 90 dni, aplikacja zastąpi całą bazę danych.

Ta zmiana zmniejszyła rozmiar tabeli historii o prawie 90%, więc teraz utrzymanie tabeli historii sprawia, że baza danych jest tylko dwa razy większa niż dziesięć razy tak duże. Kolejną zaletą tego systemu jest to, że synchronizacja może nadal działać bez tabeli historii, jeśli to konieczne-na przykład, gdybym musiał wykonać konserwację, która tymczasowo wyłączyła go. Albo mogę zaoferować różne okresy wycofania dla kont w różnych punktach cenowych. A jeśli do pobrania jest więcej niż 90 dni, Cały plik jest zwykle bardziej wydajny niż format Przyrostowy.

Gdybym dzisiaj zaczynał od nowa, pominąłbym sprawdzanie konfliktu ID i po prostu celował dla długości klucza, która jest wystarczająca do wyeliminowania konfliktów, z pewnego rodzaju sprawdzaniem błędów na wszelki wypadek. (Wygląda na to, że YouTube używa 11-znakowych losowych identyfikatorów.) Tabela historii i kombinacja przyrostowych pobrań dla ostatnich aktualizacji lub pełnego pobrania w razie potrzeby działa dobrze.

 11
Author: arlomedia,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-10-12 22:43:21

Dla synchronizacji delta (change), możesz użyć wzorca pubsub do publikowania zmian z powrotem do wszystkich subskrybowanych klientów, usługi takie jak pusher mogą to zrobić.

Dla serwerów lustrzanych, niektóre frameworki internetowe używają lokalnej mini bazy danych do synchronizacji bazy danych po stronie serwera z bazą danych lokalnych w przeglądarce, obsługiwana jest częściowa synchronizacja. Sprawdź miernik .

 1
Author: fuyi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-08 06:38:29

Ta strona wyraźnie opisuje najbardziej scenariusze synchronizacji danych z wzorcami i przykładowym kodem: Data Synchronization: Patterns, Tools, & Techniques

Jest to najbardziej wszechstronne źródło, jakie znalazłem, biorąc pod uwagę całe synchronizacje delta, strategie postępowania z usunięciami oraz synchronizację serwer-klient i klient-serwer. Jest to bardzo dobry punkt wyjścia, wart obejrzenia.

 0
Author: danb4r,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-10-06 22:53:31