Przechowywanie i tworzenie kopii zapasowych 10 milionów plików w systemie Linux

25

Prowadzę stronę internetową, na której około 10 milionów plików (okładek książek) jest przechowywanych w 3 poziomach podkatalogów, w zakresie [0-f]:

0/0/0/
0/0/1/
...
f/f/f/

Prowadzi to do około 2400 plików w katalogu, co jest bardzo szybkie, gdy musimy pobrać jeden plik. Jest to zresztą praktyka sugerowana przez wiele pytań .

Jednak kiedy muszę wykonać kopię zapasową tych plików, przeglądanie katalogów 4k zawierających 10 milionów plików zajmuje wiele dni.

Zastanawiam się więc, czy mógłbym przechowywać te pliki w kontenerze (lub w kontenerach 4k), z których każdy działałby dokładnie jak system plików (jakiś rodzaj zamontowanego kontenera ext3 / 4?). Wydaje mi się, że byłoby to prawie tak samo wydajne, jak bezpośredni dostęp do pliku w systemie plików, a miałoby to tę wielką zaletę, że bardzo skutecznie zostało skopiowane na inny serwer.

Wszelkie sugestie, jak to zrobić najlepiej? Lub jakaś realna alternatywa (noSQL, ...)?

Benzoes
źródło
Z jakiego systemu plików obecnie korzystasz?
cmcginty
NetApp jest chętnie być opcją, jeśli możesz obniżyć ceny
Ian Ringrose
Używam ext4 pod CentOS 5.6
Benjamin
1
Ciekawe, dlaczego „wiele dni zajmuje przeglądanie katalogów 4k zawierających 10 milionów plików”, co wydaje się zbyt wolne. Zakładając 150 bajtów na nazwę ścieżki, 10-metrowe nazwy plików tworzą 1,5 GB danych, więc może to być dostępna pamięć / procesor (w tym sortowanie wyniku). Sprawdź także, czy włączenie / wyłączenie dir_index pomaga: lonesysadmin.net/2007/08/17/... plus różne wskazówki na serverfault.com/questions/183821/…
RichVel
Uwaga 5 lat później: migrowałem wszystko do Amazon S3, który doskonale nadaje się do przechowywania tak dużej liczby plików. Ponadto nie muszę już dzielić plików na 3 poziomy podkatalogów, ponieważ w przypadku S3 nie robi to żadnej różnicy (ścieżka jest ścieżką, niezależnie od tego, czy zawiera ukośniki, czy nie). I mogę spać lepiej, wiedząc, że moje dane są bezpiecznie replikowane w kilku lokalizacjach.
Benjamin

Odpowiedzi:

11

Opcje szybkiego dostępu i tworzenia kopii zapasowych milionów plików

Pożycz od osób z podobnymi problemami

To brzmi bardzo podobnie do łatwiejszego problemu, z którym borykają się serwery wiadomości USENET i buforowanie serwerów proxy: setki milionów małych plików, do których dostęp jest losowy. Możesz wziąć od nich podpowiedź (z tym, że zazwyczaj nie muszą oni robić kopii zapasowych).

http://devel.squid-cache.org/coss/coss-notes.txt

http://citeseer.ist.psu.edu/viewdoc/download;jsessionid=4074B50D266E72C69D6D35FEDCBBA83D?doi=10.1.1.31.4000&rep=rep1&type=pdf

Oczywiście cykliczny charakter systemu plików wiadomości cyklicznych jest dla ciebie nieistotny, ale koncepcja niższego poziomu posiadania wielu plików / urządzeń dyskowych z zapakowanymi obrazami i szybkiego indeksu z informacji dostarczonych przez użytkownika w celu wyszukiwania informacji o lokalizacji jest bardzo odpowiednia.

Dedykowane systemy plików

Oczywiście są to tylko podobne pojęcia do tego, o czym rozmawiali ludzie, tworząc system plików w pliku i montując go w pętli zwrotnej, tyle że można napisać własny kod systemu plików. Oczywiście, ponieważ powiedziałeś, że twój system jest w większości do odczytu, możesz tak naprawdę dedykować partycję dyskową (lub partycję lvm dla elastyczności w doborze) do tego jednego celu. Aby utworzyć kopię zapasową, zamontuj system plików tylko do odczytu, a następnie wykonaj kopię bitów partycji.

LVM

Wspomniałem LVM powyżej jako przydatne do dynamicznego określania rozmiaru partycji, dzięki czemu nie trzeba tworzyć kopii zapasowej dużej ilości pustego miejsca. Ale oczywiście LVM ma inne funkcje, które mogą być bardzo przydatne. W szczególności funkcja „migawki”, która pozwala chwilowo zamrozić system plików. Przypadkowe rm -rflub cokolwiek innego nie zakłóciłoby migawki. W zależności od tego, co dokładnie próbujesz zrobić, może to być wystarczające dla potrzeb tworzenia kopii zapasowych.

RAID-1

Jestem pewien, że znasz już macierz RAID i prawdopodobnie już używasz jej w celu zapewnienia niezawodności, ale RAID-1 może być również używany do tworzenia kopii zapasowych, przynajmniej jeśli używasz programowego RAID (możesz go używać ze sprzętowym RAID, ale tak naprawdę daje niższą niezawodność, ponieważ może wymagać odczytu tego samego modelu / kontrolera wersji). Koncepcja polega na tym, że tworzysz grupę RAID-1 z jednym dyskiem więcej, niż potrzebujesz do podłączenia do normalnych potrzeb w zakresie niezawodności (np. Trzeci dysk, jeśli używasz programowego RAID-1 z dwoma dyskami lub być może dużym dyskiem i sprzętem- RAID5 z mniejszymi dyskami z programowym RAID-1 na sprzętowym RAID-5). Kiedy przyjdzie czas na wykonanie kopii zapasowej, zainstaluj dysk, poproś mdadm o dodanie tego dysku do grupy RAID, poczekaj, aż wskaże on kompletność, opcjonalnie poproś o weryfikację, a następnie usuń dysk. Oczywiście,

Seth Robertson
źródło
Bardzo kompletna odpowiedź, która podsumowuje dobre rozwiązania. Myślę, że zachowam istniejącą strukturę systemu plików i użyję migawek LVM, co wydaje się idealne dla mojego przypadku użycia.
Benjamin
9

Możesz zamontować wirtualny system plików za pomocą menedżera pętli zwrotnej, ale chociaż przyspieszy to proces tworzenia kopii zapasowej, może to mieć wpływ na normalne operacje.

Inną alternatywą jest wykonanie kopii zapasowej całego urządzenia za pomocą dd. Na przykład dd if=/dev/my_device of=/path/to/backup.dd.


źródło
+1 Tworzenie kopii zapasowej samego urządzenia jest dobrym pomysłem.
asm
3
Powinieneś, jeśli użyjesz tego podejścia, przetestować przywracanie (cóż, zawsze powinieneś to zrobić), ponieważ jeśli twój dane wejściowe to dysk taki jak / dev / sdd, dd zapisze sheme i rozmiary partycji. Jeśli przywrócisz go na mniejszy dysk, pojawią się błędy, a jeśli przywrócisz go na większy dysk, zostanie on obcięty. Będzie działać najlepiej, jeśli przywrócisz dane na inny przykład tego samego typu dysku. Przywracanie tylko partycji (/ dev / sdd1) będzie mniej kłopotliwe.
użytkownik nieznany
1
Należy pamiętać, że jeśli urządzenie działa w LVM, można również wykonać kopię zapasową bez odmontowywania dysku za pomocą migawek LVM.
bdonlan
Drugie podejście do tworzenia kopii zapasowych migawek LVM. Wykorzystałem lvm w przeszłości do replikacji na żywo DR. Używanie dd w połączeniu z migawkami ułatwia szybkie tworzenie kopii zapasowych na poziomie bloku.
slashdot
Starałem ddsię nci to ma dobrą pracę! Mogę jednak mieć niespójne / uszkodzone dane, w przeciwieństwie do używania migawek LVM zamiast partycji na żywo.
Benjamin
8

Jak zapewne wiesz, twoim problemem jest lokalizacja. Typowe wyszukiwanie dysku zajmuje około 10 ms. Tak więc wywołanie „stat” (lub open ()) na 10 milionach losowo umieszczonych plików wymaga 10 milionów wyszukiwań, około 100 000 sekund lub 30 godzin.

Musisz więc umieścić swoje pliki w większych pojemnikach, tak aby odpowiednią liczbą była przepustowość dysku (zwykle 50-100 MB / s dla pojedynczego dysku), a nie czas poszukiwania. Możesz także rzucić na nią RAID, co pozwala zwiększyć przepustowość (ale nie skraca czasu wyszukiwania).

Prawdopodobnie nie mówię ci niczego, czego jeszcze nie wiesz, ale mam na myśli to, że Twój pomysł „pojemnika” na pewno rozwiąże problem i zrobi to prawie każdy pojemnik. Mocowania Loopback prawdopodobnie będą działać tak dobrze, jak wszystko.

Nemo
źródło
Tak, lokalizacja jest kluczowa. Spójrz na swoje wzorce użytkowania. Większość problemów jest zgodna z zasadą Pareto (80% procesów uderzających w 20% danych), więc jeśli możesz dowiedzieć się, które pliki należy buforować w pamięci RAM lub po prostu umieścić na osobnej partycji z innym układem katalogów, więc zajmuje mniej wyszukiwań katalogów lub szuka, prawdopodobnie by to bardzo pomogło. Rozłożenie często używanych plików na różnych wrzecionach dysków, aby można było wyszukiwać równolegle, również może pomóc. +1 dla @nemo za wywołanie lokalizacji odniesienia.
Marcin
5

Istnieje kilka opcji. Najprostszym i powinno działać ze wszystkimi systemami plików Linux, jest ddskopiowanie całej partycji ( /dev/sdb3lub /dev/mapper/Data-ImageVol) do jednego obrazu i zarchiwizowanie tego obrazu. W przypadku przywracania pojedynczych plików, loopback zamontuj obraz ( mount -o loop /usr/path/to/file /mountpoint) i skopiuj potrzebne pliki. Aby przywrócić pełne partycje, możesz odwrócić kierunek początkowej ddkomendy, ale tak naprawdę potrzebujesz partycji o identycznym rozmiarze.

Sądząc z twojego przypadku użycia, domyślam się, że pojedyncze przywracanie plików jest bardzo rzadkim zdarzeniem, jeśli w ogóle nastąpi. Właśnie dlatego kopia zapasowa oparta na obrazach ma tutaj sens. Jeśli musisz częściej przeprowadzać indywidualne przywracanie, używanie etapowych migawek LVM będzie znacznie wygodniejsze; ale nadal musisz wykonać kopię zapasową opartą na obrazie w przypadku krytycznych katastrof „straciliśmy wszystko”. Przywracanie oparte na obrazie zwykle idzie o wiele szybciej niż przywracanie oparte na tar, ponieważ po prostu przywraca bloki, nie wymaga wielu operacji na metadanych przy każdym otwieraniu / zamykaniu, a także może być bardzo sekwencyjną operacją dysku dla dalszy wzrost prędkości.

Alternatywnie, jak wspomniał film Google @casey o połowie, XFS to świetny system plików (jeśli jest złożony). Jednym z ładniejszych narzędzi XFS jest xfsdumpnarzędzie, które zrzuci cały system plików do jednego pliku i generalnie zrobi to szybciej niż tarmoże. Jest to narzędzie specyficzne dla systemu plików, więc może korzystać z wewnętrznych elementów fs w sposób, którego nie potrafi tar.

sysadmin1138
źródło
Wiele dobrych odpowiedzi! XFS wydaje się być interesujący, ale obawiam się, że jest trochę poza moim zasięgiem.
Benjamin
2

Być może odpowiedź jest uproszczona, ale moją pierwszą myślą było użycie czegoś takiego jak GridFS, który jest oparty na MongoDB . Wiele sterowników podstawowego języka obsługuje go od razu po wyjęciu z pudełka, więc powinieneś być w stanie po prostu zamienić go z sekcjami odczytu pliku w kodzie. Możesz także po prostu ustawić ścieżki do istniejących plików jako klucze do tych plików.

Jednym z problemów, które możesz mieć, jest to, że Mongo ma tendencję do dość szybkiego zwalniania, jeśli cały czas szuka dysku. Z 10 milionami plików, spodziewam się, że większość twoich danych będzie na dysku. Fragmenty plików w GridFS mają, jak pamiętam, 4 MB, więc jeśli twoje pliki są większe, będziesz musiał wykonać kilka kosztownych operacji, aby uzyskać jeden plik. Wydaje mi się, że kluczem będzie fragmentowanie plików na podstawie już i tak uporządkowanej struktury katalogów, aby można było uruchomić kilka instancji Mongo na kilku polach w celu zmniejszenia obciążenia. Jednak nie wiem, jakie są twoje wymagania dotyczące wydajności, więc mogę to przesadzić.

Jaka jest z tego korzyść? Wydajność, która jest bardzo zbliżona do odczytu dysku, jeśli jest wykonana poprawnie Ponadto Mongo oferuje kilka świetnych wbudowanych sposobów szybkiego tworzenia kopii zapasowych całego pokosu danych w instancji DB, a nawet przy wciąż działającej bazie danych.

davelab
źródło
Na pewno spojrzę na GridFS, którego nie znałem, ale myślę, że skończę, utrzymując wszystko oparte na systemie plików, aby zmniejszyć ilość pracy, ponieważ wszystko już działa!
Benjamin
1

Jeśli byłbyś zadowolony z modelu urządzenia do przechowywania danych, może warto rozważyć NexentaStor . Działa ZFS na OpenSolaris pod maską, ale cała administracja odbywa się poprzez web GUI.

Istnieje kilka funkcji, które mogą pomóc w rozwiązaniu problemu.

  • Wersja Enterprise obsługuje formę zdalnej replikacji opartej na migawkach, która nie wymaga skanowania przez cały system plików.

  • Jeśli nie masz nic przeciwko brudzeniu rąk, ZFS ma bardzo przydatną komendę ZFS diff, która skutecznie informuje, które pliki zostały dodane, zmodyfikowane lub usunięte od ostatniej migawki, bez potrzeby skanowania całego systemu plików. Możesz włączyć to do systemu tworzenia kopii zapasowych, aby znacznie skrócić czas wymagany do wykonywania przyrostowych kopii zapasowych.

Tom Shaw
źródło
Dzięki, popatrzę na to. Może to jednak trochę skomplikuje mój projekt!
Benjamin
1

Możesz użyć standardowego dumpnarzędzia do tworzenia kopii zapasowych systemu plików EXT4 z dużą ilością plików. To narzędzie najpierw sprawdza, które bloki są używane w systemie plików, a następnie tworzy ich kopie zapasowe w kolejności dysków, eliminując większość wyszukiwań.

Istnieje odpowiednie restorenarzędzie do przywracania kopii zapasowych utworzone przez dump.

Obsługuje przyrostowe kopie zapasowe przy użyciu plików kopii zapasowych poziomu 1 zmodyfikowanych z ostatniej kopii zapasowej poziomu 0 (pełnej), poziomu 2 - zmodyfikowanych z kopii zapasowej poziomu 1 i tak dalej.

Tometzky
źródło
0

W przypadku przyrostowych kopii zapasowych jedną z opcji byłoby posiadanie drugiego drzewa cienia dla nowych okładek. Oznacza to, że masz główne drzewo, które jest używane do wszystkich operacji odczytu. Miałbyś także newfiles/012345.....jpgkatalog; nowo dodane okładki tworzą tutaj hardlink, a także w głównym drzewie. Podczas wykonywania kopii zapasowych można od czasu do czasu wykonać kopię zapasową głównego drzewa, ale newfilesznacznie częściej wykonywać kopię zapasową (znacznie mniejszego) drzewa.

Pamiętaj, że aby zachować newfilesmałe drzewo, przed utworzeniem nowej kopii zapasowej głównego drzewa możesz opróżnić drzewo nowych plików:

mv newfiles newfiles_
mkdir newfiles
rm -rf newfiles_

Gdy to zrobisz, oczywiście jesteś zobowiązany do utworzenia nowej kopii zapasowej głównego drzewa.

bdonlan
źródło
Ciekawe podejście, dziękuję za udostępnienie. Ale obawiam się, że wymagałoby to wielu zmian w aplikacji i trudno byłoby utrzymać aplikację i potrzeby przechowywania w dwóch osobnych warstwach.
Benjamin
0

Dodanie odrobiny współbieżności zwykle pomaga.

Mam podobny problem jak ty; w moim przypadku muszę wykonać kopię zapasową około 30 milionów plików, w większości plików HTML, PHP lub JPEG. Dla mnie BackupPC + rsync przez ssh działa w porządku; pełna kopia zapasowa trwa około jednego dnia, ale przyrosty zwykle kończą się za kilka godzin.

Sztuczka polega na dodaniu każdego katalogu poziomu głównego (0, 1, 2 ... a, b, c ...) jako nowego celu do skopiowania w BackupPC i umożliwienia równoległego wykonywania kopii zapasowej, aby jednocześnie tworzyła kopie zapasowe katalogów a / , b / , c / * i tak dalej. W zależności od podsystemu dysku wszystko od kilku procesów do około 10 procesów jest prawdopodobnie najszybszym sposobem wykonania kopii zapasowej.

Migawki LVM i kopie zapasowe na poziomie bloków są również opcją, ale dzięki BackuPC i kopii zapasowej na poziomie plików możesz w razie potrzeby przywrócić pojedyncze pliki lub katalogi.

Janne Pikkarainen
źródło
Dziwi mnie, że jednoczesne tworzenie kopii zapasowych katalogów głównych rozwiązuje problem. Spodziewałbym się, że będzie to wolniejsze. Czy wszystkie katalogi są na tym samym dysku? Czy używasz dysku SSD?
Benjamin
Pliki danych są przechowywane w sieci SAN.
Janne Pikkarainen
W porządku, teraz ma sens, że uzyskujesz wydajność dzięki jednoczesnemu dostępowi do kilku plików, ponieważ Twoje różne foldery najprawdopodobniej znajdują się fizycznie na różnych dyskach w sieci SAN lub przynajmniej replikowane na kilku dyskach, co pozwala na równoczesny dostęp. Opieram się tylko na RAID-1, więc sądzę, że po dwóch równoległych dostępach moja prędkość prawdopodobnie spadnie.
Benjamin
0

Benzoes,

Myślę, że twój problem można rozwiązać za pomocą liczby plików na poziomie katalogu!

Czy czas dostępu zmienia się w znaczący sposób, jeśli przechowujesz 20 000 plików w katalogu?

Czy zastanawiałeś się też nad przechowywaniem metadanych systemu plików na osobnym dysku o szybszym dostępie (np. Dysku SSD)?

Dragos
źródło
0

Zamiast tego poleciłbym starą dobrą relacyjną bazę danych.

Użyłbym PostgreSQL z, powiedzmy, 256 tabelami partycjonowanymi (cover_00, cover_01, ..., cover_ff) z danymi obrazu jako byteakolumną (binarną) z pamięcią zewnętrzną, z identyfikatorem pliku jako kluczem podstawowym. Odzyskiwanie obrazu byłoby szybkie (dzięki indeksowi klucza podstawowego), gwarantowana byłaby integralność danych (baza danych zgodna z ACID), kopie zapasowe byłyby w kolejności dysków, więc nie trzeba zbyt wiele szukać.

Tometzky
źródło