Chcielibyśmy przechowywać miliony plików tekstowych w systemie plików Linux, aby móc spakować i udostępnić dowolną kolekcję jako usługę. Wypróbowaliśmy inne rozwiązania, takie jak baza danych kluczy / wartości, ale nasze wymagania dotyczące współbieżności i równoległości sprawiają, że korzystanie z macierzystego systemu plików jest najlepszym wyborem.
Najprostszym sposobem jest przechowywanie wszystkich plików w folderze:
$ ls text_files/
1.txt
2.txt
3.txt
co powinno być możliwe w systemie plików EXT4 , który nie ma ograniczenia liczby plików w folderze.
Dwa procesy FS będą następujące:
- Napisz plik tekstowy ze złomowania w Internecie (liczba plików w folderze nie powinna mieć wpływu).
- Spakuj wybrane pliki według listy nazw plików.
Moje pytanie brzmi: czy przechowywanie do dziesięciu milionów plików w folderze wpłynie na wydajność powyższych operacji lub ogólną wydajność systemu, inaczej niż tworzenie drzewa podfolderów dla plików, w których będą żyć?
źródło
dir_index
, które często jest domyślnie włączone, przyspieszy wyszukiwanie, ale może ograniczyć liczbę plików w katalogu.ls -l
wszystko inne,stat
co jest każdym i-węzłem w katalogu (np.bash
Globbing / tabulacja), będzie sztucznie szybsze niż po pewnym zużyciu (usuń niektóre pliki, napisz nowe). ext4 może to zrobić lepiej niż XFS, ponieważ XFS dynamicznie przydziela miejsce dla i-węzłów vs. danych, więc myślę, że możesz skończyć z bardziej rozproszonymi i-węzłami. (Ale to tylko domysły oparte na bardzo małej szczegółowej wiedzy; ledwo używałem ext4). Idź zabc/def/
podkatalogami.ZipOutputStream
, pokonałby prawie każdy wolny rodzimy system plików Linux - wątpię, czy chcesz zapłacić za GPFS IBM. Pętla przetwarzająca zestaw wyników JDBC i sprawiająca, że strumień zip to prawdopodobnie zaledwie 6-8 linii kodu Java.Odpowiedzi:
ls
Polecenia TAB nawet uzupełnianie lub symbole ekspansji przez powłokę, zwykle przedstawić wyniki w celu alfanumerycznej. Wymaga to przeczytania całego wykazu katalogów i posortowania go. Mając dziesięć milionów plików w jednym katalogu, ta operacja sortowania zajmie nie bez znaczenia czas.Jeśli możesz się oprzeć pokusie ukończenia TAB i np. Napisać nazwy plików do skompresowania w całości, nie powinno być problemów.
Innym problemem związanym z symbolami wieloznacznymi może być rozszerzenie symboli wieloznacznych, które może powodować powstanie większej liczby nazw plików niż mieści się w wierszu polecenia o maksymalnej długości. Typowa maksymalna długość wiersza poleceń będzie więcej niż wystarczająca w większości sytuacji, ale kiedy mówimy o milionach plików w jednym katalogu, nie jest to już bezpieczne założenie. Gdy maksymalna długość wiersza poleceń zostanie przekroczona przy interpretacji symboli wieloznacznych, większość powłok po prostu zawiedzie cały wiersz poleceń bez jego wykonania.
Można to rozwiązać, wykonując operacje wieloznaczne za pomocą
find
polecenia:lub podobną składnię, gdy tylko jest to możliwe.
find ... -exec ... \+
Automatycznie uwzględniać długość linii poleceń maksymalna i wykona polecenie tyle razy, ile wymagane podczas montażu maksymalną ilość nazw do każdego wiersza poleceń.źródło
ls
polecenie nie dowie się, że lista katalogów jest już posortowana, i tak poświęcą trochę czasu na uruchomienie algorytmu sortowania. Poza tym przestrzeń użytkownika może używać zlokalizowanego porządku sortowania (LC_COLLATE), który może różnić się od tego, co system plików może robić wewnętrznie.Jest to niebezpiecznie zbliżone do opartego na opiniach pytania / odpowiedzi, ale postaram się przedstawić kilka faktów w moich opiniach.
mv * /somewhere/else
), Może się nie powieść z powodzeniem, lub wynik może być zbyt duży do użycia.ls
wyliczenie bardzo dużej liczby plików potrwa dłużej niż niewielka liczba plików.Jedną z rekomendacji jest podzielenie nazwy pliku na dwie, trzy lub cztery znaki i użycie ich jako podkatalogów. Na przykład
somefilename.txt
może być przechowywany jakosom/efi/somefilename.txt
. Jeśli używasz nazw numerycznych, podziel je od prawej do lewej zamiast od lewej do prawej, aby uzyskać bardziej równomierny rozkład. Na przykład12345.txt
może być przechowywany jako345/12/12345.txt
.Możesz użyć odpowiednika opcji,
zip -j zipfile.zip path1/file1 path2/file2 ...
aby uniknąć dołączania pośrednich ścieżek podkatalogów do pliku ZIP.Jeśli serwujesz te pliki z serwera WWW (nie jestem do końca pewien, czy to istotne), ukrywanie tej struktury na korzyść katalogu wirtualnego z regułami przepisywania w Apache2 jest banalne. Zakładam, że to samo dotyczy Nginx.
źródło
*
Ekspansja uda, chyba że zabraknie pamięci, ale chyba podwyższyć limit stacksize (Linux) lub zastosować powłokę gdziemv
jest wbudowane lub mogą być wbudowane (ksh93, zsh), przy czymexecve()
funkcja systemowa może zakończyć się niepowodzeniem z błędem E2BIG.zip -j - ...
i przesyłanie strumienia wyjściowego bezpośrednio do połączenia sieciowego klientazip -j zipfile.zip ...
. Zapisanie rzeczywistego pliku zip na dysku oznacza, że ścieżka danych jest odczytywana z dysku-> kompresuj-> zapisuj na dysk-> czytaj z dysku-> wysyłaj do klienta. To może nawet trzykrotnie zwiększyć wymagania IO dysku w porównaniu z odczytem z dysku-> kompresuj-> wysyłaj do klienta.Prowadzę stronę internetową, która obsługuje bazę danych filmów, programów telewizyjnych i gier wideo. Dla każdego z nich jest wiele obrazów z telewizorem zawierającym dziesiątki obrazów na program (np. Migawki odcinków itp.).
W końcu jest dużo plików graficznych. Gdzieś w zakresie ponad 250 000. Wszystkie są przechowywane w zamontowanym blokowym urządzeniu magazynującym, w którym czas dostępu jest rozsądny.
Moja pierwsza próba zapisania zdjęć była w jednym folderze jako
/mnt/images/UUID.jpg
Natknąłem się na następujące wyzwania.
ls
przez zdalny terminal po prostu się zawiesił. Proces poszedłby zombie iCTRL+C
nie złamałby go.ls
polecenie szybko zapełni bufor wyjściowy iCTRL+C
nie zatrzyma niekończącego się przewijania.Skończyło się na tym, że musiałem przechowywać pliki w podfolderach, wykorzystując czas utworzenia do utworzenia ścieżki. Takich jak
/mnt/images/YYYY/MM/DD/UUID.jpg
. To rozwiązało wszystkie powyższe problemy i pozwoliło mi utworzyć pliki zip, które były kierowane na datę.Jeśli jedynym identyfikatorem pliku, który masz, jest liczba, a te liczby mają tendencję do działania w sekwencji. Dlaczego nie grupa je
100000
,10000
i1000
.Na przykład, jeśli masz plik o nazwie
384295.txt
ścieżka to:Jeśli wiesz, osiągniesz kilka milionów. Użyj
0
prefiksów dla 1 000 000źródło
Aby utworzyć nowy plik, należy przeskanować plik katalogu w poszukiwaniu wystarczającej ilości wolnego miejsca na nowy wpis katalogu. Jeśli nie zostanie znalezione wystarczająco duże miejsce do zapisania nowego wpisu katalogu, zostanie ono umieszczone na końcu pliku katalogu. Wraz ze wzrostem liczby plików w katalogu rośnie także czas skanowania katalogu.
Tak długo, jak pliki katalogów pozostają w pamięci podręcznej systemu, nie będzie to miało negatywnego wpływu na wydajność, ale jeśli dane zostaną zwolnione, odczytanie pliku katalogu (zwykle bardzo rozdrobnionego) z dysku może zająć sporo czasu. Dysk SSD poprawia to, ale w przypadku katalogu z milionami plików nadal może wystąpić zauważalny spadek wydajności.
Może to również wymagać dodatkowego czasu w katalogu z milionami plików. W systemie plików z hashowanymi pozycjami katalogu (jak EXT4) różnica ta jest minimalna.
Drzewo podfolderów nie ma żadnej z powyższych wad wydajności. Ponadto, jeśli podstawowy system plików zostanie zmieniony tak, aby nie miał zaszyfrowanych nazw plików, metodologia drzewa nadal będzie działać dobrze.
źródło
Po pierwsze: zapobiegaj sortowaniu „ls” za pomocą „ls -U”, może zaktualizuj swój ~ / bashrc tak, aby miał „alias ls =" ls -U "lub podobny.
W przypadku dużego zestawu plików możesz wypróbować to w następujący sposób:
utwórz zestaw plików testowych
sprawdź, czy wiele nazw plików powoduje problemy
użyj xargs parmeter-batching i zip (domyślne) zachowanie dodawania plików do zip, aby uniknąć problemów.
To działało dobrze:
źródło