Opcje efektywnej synchronizacji 1 miliona plików ze zdalnymi serwerami?

27

W firmie, dla której pracuję, mamy coś takiego, zwane „listami odtwarzania”, które są małymi plikami ~ 100-300 bajtów każdy. Jest ich około miliona. Około 100 000 z nich zmienia się co godzinę. Te listy odtwarzania należy co godzinę przesyłać na 10 innych zdalnych serwerów na różnych kontynentach, a najlepiej w krótkim czasie poniżej 2 minut. Bardzo ważne jest, aby pliki usuwane z wzorca były również usuwane we wszystkich replikach. Obecnie używamy Linuksa do naszej infrastruktury.

Myślałem o wypróbowaniu rsync z opcją -W, aby skopiować całe pliki bez porównywania zawartości. Nie próbowałem tego jeszcze, ale może ludzie, którzy mają większe doświadczenie z rsync, mogliby mi powiedzieć, czy jest to realna opcja?

Jakie inne opcje są warte rozważenia?

Aktualizacja: Jako odpowiedź wybrałem opcję lsyncd, ale tylko dlatego, że była najbardziej popularna. Inne sugerowane alternatywy są również ważne na swój sposób.

Zilvinas
źródło
1
Czy masz dziennik wskazujący, które pliki zostały zmienione lub usunięte?
Oliver,
3
Gdyby tylko listy odtwarzania były rekordami mysql. Następnie można użyć replikacji bazy danych i uzyskać mysql, aby ustalić, co należy wysłać / odebrać.
Matt
@oliver robimy. Jednak musisz zaufać temu dziennikowi, co oznacza, że ​​kod go generujący musi być poprawny, a następnie potrzebujesz kodu niestandardowego do przetworzenia tego dziennika, który również musi być poprawny. Wolałbym unikać budowania własnego kodu, aby zrobić to w oparciu o coś, co zostało dokładnie przetestowane przez społeczność.
Zilvinas,
Czy chcesz, aby zmiana była stosowana tylko co godzinę? Czy też akceptowalna jest natychmiastowa replikacja?
faker
1
Nie lekceważ czasu, w którym rsync zajmuje milion plików. Po prostu spróbuj, a zobaczysz, co porabiasz. Jeśli masz ten dziennik, użyj go lub wypróbuj inne proponowane rozwiązania.
Oliver,

Odpowiedzi:

39

Ponieważ natychmiastowe aktualizacje są również dopuszczalne, możesz użyć lsyncd .
Obserwuje katalogi (inotify) i rsynczmienia się w niewolników.
Przy starcie zrobi to w pełni rsync, więc zajmie to trochę czasu, ale potem zostaną przesłane tylko zmiany.
Możliwe jest rekurencyjne oglądanie katalogów, jeśli serwer podrzędny nie działa, synchronizacja będzie ponawiana do momentu powrotu.

Jeśli wszystko znajduje się w jednym katalogu (lub statycznej liście katalogów), możesz również użyć incron .
Wadą jest to, że nie pozwala na rekurencyjne oglądanie folderów i musisz samodzielnie wdrożyć funkcję synchronizacji.

oszust
źródło
Znowu genialna wskazówka :)
Zilvinas
1
+1 Zasadniczo jest to problem ze spójnością pamięci podręcznej, najłatwiejszym rozwiązaniem jest monitor, który wprowadza zmiany. lsyncdimplementuje to ...
Chris S
1
Zbadam lsyncdi inotifydogłębnie, jak to dotyczy konkretnego systemu operacyjnego serwera. Istnieje ograniczenie liczby dostępnych zegarów Inotify. Uważam, że domyślnie jest to około 1500 lub 8000, w zależności od konkretnej wersji systemu Linux. Większość jąder pozwala podnieść limit, ale monitorowanie 1 miliona plików może być więcej niż praktyczne. Nie działało to dla mnie w 2008 roku. Kolejka zdarzeń inotify może się przepełnić, powodując utratę zdarzeń i musisz mieć sposób na odzyskanie tego. Starannie dostrojona lsyncdimplementacja plus codzienny rsyncmoże działać teraz w 2012 roku, aby pokryć twoje bazy.
Old Pro
2
W rzeczywistości robi to iontifyw katalogu, a nie w poszczególnych plikach. Ile katalogów można oglądać? Sprawdź /proc/sys/fs/inotify/max_user_watches(zwykle 8192).
faker
2
Przy ~ 50 tys. Katalogów inotify prawdopodobnie nie będzie dobrze skalować. Kiedy wypróbowaliśmy podobne podejście w 2009 roku ze 100 000 katalogów, jądro zajęło dużo czasu, aby subskrybować wszystkie katalogi. Jeśli chodzi o @OldPro, nie działało to dla nas.
neovatar,
11

Rozważ użycie rozproszonego systemu plików, takiego jak GlusterFS . Zaprojektowany z myślą o replikacji i równoległości, GlusterFS może skalować do 10 serwerów znacznie płynniej niż rozwiązania ad-hoc obejmujące inotify i rsync.

W tym szczególnym przypadku można zbudować 10-serwerowy wolumin GlusterFS z 10 replikami (tj. 1 replika / cegła na serwer), tak aby każda replika była dokładnym lustrem każdej innej repliki w woluminie. GlusterFS automatycznie propaguje aktualizacje systemu plików do wszystkich replik.

Klienci w każdej lokalizacji kontaktowaliby się z lokalnym serwerem, więc dostęp do plików byłby szybki. Kluczowe pytanie brzmi, czy opóźnienie zapisu można utrzymać na niskim poziomie. Jedynym sposobem na to jest wypróbowanie.

Steven Monday
źródło
+1 dla Glusterfs
Tom O'Connor
8

Wątpię, rsyncczy zadziałałoby to w normalny sposób, ponieważ skanowanie miliona plików i porównywanie ich z systemem zdalnym 10 razy zajęłoby dużo czasu. Spróbowałbym zaimplementować system z czymś takim, inotifyktóry utrzymuje listę zmodyfikowanych plików i wypycha je na zdalne serwery (jeśli te zmiany i tak nie zostaną zarejestrowane w inny sposób). Następnie możesz użyć tej listy, aby szybko zidentyfikować pliki wymagane do przesłania - może nawet za pomocą rsync (lub lepiej 10 równoległych instancji).

Edycja: Przy odrobinie pracy możesz nawet użyć tej metody inotify / log watch, aby skopiować pliki, gdy tylko nastąpi modyfikacja.

Sven
źródło
5

Kilka innych alternatyw:

  • Wkładka pracy w RabbitMQ lub Gearman do asynchronicznie zgaśnie i usunąć (lub dodać) tego samego pliku na wszystkich zdalnych serwerów w dowolnym momencie usunąć lub dodać plik na serwerze podstawowym.
  • Przechowuj pliki w bazie danych i używaj replikacji, aby synchronizować zdalne serwery.
  • Jeśli masz ZFS , możesz użyć replikacji ZFS .
  • Niektóre sieci SAN mają replikację plików. Nie mam pojęcia, czy można tego użyć przez Internet.
Ladadadada
źródło
4

Wydaje się, że jest to idealny przypadek użycia podręcznika dla MongoDB i być może GridFS . Ponieważ pliki są stosunkowo małe, sam MongoDB powinien wystarczyć, chociaż korzystanie z interfejsu API GridFS może być wygodne.

MongoDB to baza danych nosql, a GridFS to platforma do przechowywania plików. MongoDB ma wiele wbudowanych opcji replikacji i dzielenia na fragmenty , więc powinien bardzo dobrze skalować się w twoim przypadku użycia.

W twoim przypadku prawdopodobnie zaczniesz od zestawu replik, który składa się z wzorca zlokalizowanego w twoim głównym centrum danych (być może w drugim, na wypadek, gdybyś chciał przełączyć się w tę samą lokalizację) i twoich dziesięciu „niewolników” rozmieszczonych na całym świecie. Następnie wykonaj testy ładowania, aby sprawdzić, czy wydajność zapisu jest wystarczająca, i sprawdź czasy replikacji do swoich węzłów. Jeśli potrzebujesz większej wydajności, możesz zmienić konfigurację na podzieloną (głównie w celu rozdzielenia obciążenia zapisu na więcej serwerów). MongoDB został zaprojektowany w taki sposób, aby skalować ogromne konfiguracje za pomocą „taniego” sprzętu, dzięki czemu możesz dodać partię niedrogich serwerów, aby poprawić wydajność.

neovatar
źródło
0

Użyłbym backendu S3, a następnie po prostu zamontowałem go na wszystkich potrzebnych serwerach - w ten sposób i tak wszyscy są natychmiast zsynchronizowani

Mister IT Guru
źródło
Gdy pamięć zostanie zsynchronizowana, musisz powiadomić aplikację, więc wrócisz do punktu wyjścia lub aplikacja będzie musiała sondować pamięć za każdym razem, gdy ktoś wejdzie na te listy odtwarzania. W obu przypadkach wydajność byłaby okropna.
Chris S
Aplikacja nie musi sondować pamięci za każdym razem, gdy ktoś uzyskuje dostęp do list odtwarzania, wystarczy tyle razy w ciągu godziny, aby aplikacja działała bez przestarzałych danych. Ponadto, jeśli S3 jest używany jako backend, dlaczego aplikacja musiałaby najpierw sondować pliki? Zawsze będą aktualne
Mister IT Guru,
0

Opcją, która nie została jeszcze wymieniona, jest zarchiwizowanie wszystkich plików w jednym skompresowanym pliku. Powinno to znacznie zmniejszyć całkowity rozmiar i usunąć cały narzut związany z obsługą milionów pojedynczych plików. Zastępując cały zestaw plików w jednej dużej aktualizacji, możesz mieć pewność, że usunięte pliki zostaną usunięte z replik.

Minusem jest oczywiście to, że niepotrzebnie przesyłasz wiele plików. To może, ale nie musi być zrównoważone zmniejszonym rozmiarem dzięki kompresji. Nie mam też pojęcia, ile czasu zajęłoby skompresowanie tylu plików.

Supr
źródło