Deskryptory plików mogą ograniczać samodzielnie hostowany domowy serwer, ponieważ Linux używa ich jako skończonych odniesień do otwartych zasobów I/O. Usługa może mieć wolne CPU, RAM i przepustowość sieci, ale nadal nie być w stanie zaakceptować połączenia, otworzyć pliku multimedialnego, zapisać logu, utworzyć potoku lub obserwować innego zasobu po wyczerpaniu budżetu deskryptorów.
Limit może istnieć na kilku warstwach: proces, usługa systemd, środowisko kontenera, użytkownik lub całe jądro. Widocznym objawem jest często „Zbyt wiele otwartych plików”, ale wyczerpany zasób może faktycznie stanowić gniazda, potoki, uchwyty zdarzeń lub wyciek, a nie zwykłe pliki.
Co reprezentuje deskryptor pliku na domowym serwerze?
Deskryptor pliku to mała, lokalna dla procesu liczba całkowita odnosząca się do otwartego zasobu jądra. pliki, gniazda i potoki zużywają deskryptory, co pozwala na stosowanie tych samych wzorców odczytu, zapisu, sondowania i zamykania w różnych typach zasobów.
Reverse proxy używa deskryptorów do nasłuchujących gniazd i zaakceptowanych połączeń klientów. Baza danych używa ich do plików danych, logów, gniazd i potoków. Serwer multimedialny może mieć deskryptory dla plików biblioteki, metadanych, komunikacji podprocesów i aktywnych strumieni.
Numer deskryptora to tylko odniesienie procesu. Jądro śledzi również podstawowy otwarty plik lub obiekt gniazda, jego stan, przesunięcia, bufory i własność, aż każde odniesienie zostanie zamknięte.
Jakie limity deskryptorów może faktycznie osiągnąć usługa?
Linux stosuje więcej niż jeden limit, więc kilka limitów deskryptorów może zawieść niezależnie. Obecny miękki limit kontroluje normalną alokację, podczas gdy twardy limit ogranicza, jak wysoko można podnieść ten miękki limit.
Jednostka systemd może odziedziczyć lub nadpisać inny limit niż interaktywna powłoka. Kontener może odziedziczyć domyślne ustawienia czasu wykonywania różniące się od hosta, podczas gdy jądro nadal egzekwuje ogólnosystemową pojemność otwartych plików.
Dlatego `ulimit -n` w jednej powłoce może nie opisywać dotkniętej usługi. Odpowiednia wartość należy do uruchomionego procesu i jego kontekstu usługi lub kontenera, a nie tylko do sesji logowania administratora.
Dlaczego połączenia sieciowe zużywają tę samą skończoną pulę?
Każde zaakceptowane połączenie TCP i większość wychodzących gniazd wymaga deskryptorów. ponowne użycie połączeń zmniejsza powtarzane tworzenie gniazd, redukując zarówno pracę związaną z konfiguracją, jak i liczbę jednocześnie przechodzących połączeń.
Reverse proxy, pula baz danych, usługa WebSocket, downloader, agent monitorujący i aplikacja multimedialna mogą korzystać z tych samych budżetów deskryptorów na poziomie procesu lub hosta przez różne procesy.
Zamknięte połączenia mogą przez jakiś czas pozostawać reprezentowane gdzie indziej w stosie sieciowym, ale deskryptor aplikacji powinien zostać zwolniony po zamknięciu gniazda. Utrzymujący się wzrost otwartych deskryptorów gniazd wskazuje na długotrwałe obciążenie lub wyciek, a nie tylko na normalne czyszczenie TCP.
Co zawodzi, gdy nie można przydzielić nowego deskryptora?
Gdy proces osiąga własny limit, wyczerpanie deskryptorów blokuje nowe zasoby I/O. Limit systemowy może wpływać na kilka niezwiązanych usług zamiast tylko na proces, który zużył najwięcej uchwytów.
Serwer może przestać akceptować nowych klientów, podczas gdy istniejące sesje trwają dalej. Logowanie może zawieść, przeładowania konfiguracji mogą się nie powieść, wyszukiwania DNS mogą nie otworzyć gniazd, a aplikacje mogą zgłaszać mylące błędy bazy danych lub magazynu.
Awaria może się rozprzestrzeniać, ponieważ narzędzia diagnostyczne, sesje SSH, menedżery usług lub haki restartu również potrzebują deskryptorów. Limit zasobów mający na celu ograniczenie jednego obciążenia może utrudnić odzyskanie po wyczerpaniu zasobów hosta.
Dlaczego wyciek deskryptora różni się od prawdziwego szczytu?
Prawdziwy szczyt rośnie wraz z liczbą jednoczesnych użytkowników lub otwartą pracą i spada, gdy ta praca się kończy. wyciek deskryptora rośnie bez zwalniania zasobów, ponieważ aplikacja traci lub zatrzymuje referencje zamiast je zamykać.
Podniesienie limitu pomaga prawdziwej usłudze o dużej współbieżności tylko wtedy, gdy aplikacja, pamięć, gniazda i systemy podrzędne są zaprojektowane na większe obciążenie. W przypadku wycieku jedynie wydłuża czas do ponownego wystąpienia tego samego błędu.
Monitoruj liczbę deskryptorów według typu i wieku, a nie tylko łącznie. Tysiące oczekiwanych gniazd klientów mają inne znaczenie niż stale rosnąca liczba usuniętych plików dziennika, potoków, obiektów zdarzeń czy połączeń do jednej niedostępnej zależności.
Dlaczego podniesienie limitu może ukryć prawdziwy problem?
Kontenery i demony mogą otrzymywać limity z kilku warstw konfiguracji, a limity kontenerów mogą różnić się od limitów hosta. Zmiana tylko jednej warstwy może nie zmienić efektywnego limitu.
Znacznie wyższy limit pozwala również wymknąć się spod kontroli usłudze, która zużyje więcej pamięci jądra i więcej gniazd przed ograniczeniem. Poprawna wartość powinna uwzględniać oczekiwaną współbieżność, otwarte pliki, obserwacje, potoki, margines bezpieczeństwa i zachowanie przy awarii.
Najpierw zmierz aktualny limit, bieżące użycie, tempo wzrostu i typy deskryptorów. Napraw wycieki i nieograniczone zachowanie połączeń, a następnie podnieś efektywny limit usługi, gdy obserwowany prawidłowy szczyt się do niego zbliża z uzasadnionym marginesem.
| Presja deskryptorów | Typowy wzorzec | Poprawna reakcja |
|---|---|---|
| Prawidłowa współbieżność | Liczba rośnie wraz z ruchem i spada potem | Przetestuj pojemność i podnieś efektywny limit usługi |
| Wycieki deskryptorów | Liczba rośnie stale i nie spada | Znajdź niezamknięty zasób i napraw obsługę cyklu życia |
| Niezgodność kontenera lub systemd | Limit powłoki wygląda na wysoki, ale usługa kończy się szybko | Sprawdź działający proces oraz limity usługi/runtime |
| Wyczerpanie systemowe | Kilka niepowiązanych usług nie może otworzyć zasobów | Zidentyfikuj największych konsumentów i zachowaj dostęp do odzyskiwania |
FAQ
Czy każdy otwarty plik używa dokładnie jednego deskryptora?
Zazwyczaj jedno odniesienie procesu używa jednego deskryptora, ale zduplikowane deskryptory, dziedziczone deskryptory i wiele procesów może odnosić się do tego samego otwartego obiektu.
Czy serwer domowy może osiągnąć limity deskryptorów plików przy niskim użyciu CPU?
Tak. Pojemność deskryptorów jest niezależna od wykorzystania CPU. Usługa oczekująca może utrzymywać wiele gniazd lub plików, wykonując przy tym niewiele obliczeń.
Czy zwiększenie ulimit naprawia każdy błąd Too many open files?
Nie. Usługa może używać innego limitu systemd lub kontenera, host może osiągnąć systemowy limit, a aplikacja może mieć wycieki deskryptorów.
Czy obserwacje inotify to to samo co otwarte deskryptory plików?
Instancja inotify używa deskryptora i może zawierać wiele obserwacji. Limity obserwacji i limity deskryptorów to powiązane zasoby jądra, ale nie są identyczne.
Ostateczne wnioski
Limit deskryptorów plików ogranicza serwer samodzielny, ponieważ są to skończone odniesienia procesów do plików, gniazd, potoków i wielu zasobów zdarzeniowych. Ich wyczerpanie może blokować nowe zadania, nawet gdy podstawowe wskaźniki sprzętowe wyglądają na zdrowe. Stabilna pojemność wymaga mierzenia efektywnych limitów procesów i usług, rozróżniania prawidłowej współbieżności od wycieków oraz podnoszenia limitów dopiero po zrozumieniu cyklu życia zasobów.
Centrum Technologii i Sztucznej Inteligencji
Więcej do przeczytania

Stan bieżący a stan trwały w Home Assistant: co musi przetrwać ponowne uruchomienie?
Home Assistant nie zachowuje trwale każdej bieżącej wartości; konfiguracja, rejestry, wybrane przywracane stany, historia i dane wdrożeniowe pełnią różne funkcje podczas ponownego uruchamiania.

Jak Home Assistant uwierzytelnia sesje lokalne i zdalne?
Lokalne i zdalne sesje Home Assistant korzystają z tego samego modelu tożsamości po stronie serwera; zdalny dostęp zmienia trasę i granicę TLS, ale nie...

Dlaczego zapytania do historii Home Assistant mogą zwalniać w miarę przyrostu danych rejestratora?
Wzrost liczby rekordów może zwiększyć koszt zapytań do historii, gdy żądany zakres obejmuje więcej wierszy, rośnie liczba chybień pamięci podręcznej lub operacje na pamięci...

