Harmonogram wejść/wyjść systemu Linux decyduje o tym, w jaki sposób system sortuje i nadaje priorytety operacjom odczytu i zapisu na dyskach SSD, NVMe i HDD oraz wysyła je do urządzenia. W niniejszym przewodniku wyjaśniam w praktyczny sposób, kiedy Noop, mq-deadline oraz BFQ są najlepszym wyborem w zakresie hostingu – wraz z dostosowaniem, testami i jasnymi krokami działania.
Punkty centralne
- Noop: Minimalne obciążenie dysków SSD/NVMe i maszyn wirtualnych
- mq-deadline: Zrównoważone opóźnienia i przepustowość dla serwerów
- BFQ: Uczciwość i szybka reakcja w przypadku wielu użytkowników
- blk-mq: Konstrukcja z wieloma kolejkami dla nowoczesnego sprzętu
- Strojenie: Testy według obciążenia pracą zamiast sztywnych zasad
Jak działa harmonogram operacji wejścia/wyjścia w hostingu Linux
Harmonogram operacji wejścia/wyjścia systemu Linux porządkuje żądania operacji wejścia/wyjścia w kolejkach, przeprowadza scalanie i decyduje o dostarczeniu do urządzenia w celu Opóźnienie i zwiększyć przepustowość. Nowoczesne jądra wykorzystują blk-mq, czyli Multi-Queue, aby wiele rdzeni procesora mogło równolegle inicjować operacje wejścia/wyjścia. Jest to odpowiednie rozwiązanie dla dysków SSD NVMe, które oferują wiele kolejek i wysoką równoległość, skracając w ten sposób kolejki. W hostingu często spotykają się szerokie obciążenia mieszane: serwery internetowe dostarczają wiele małych odczytów, bazy danych generują synchroniczne zapisy, a kopie zapasowe generują strumienie. Odpowiedni harmonogram redukuje zatory, utrzymuje stabilny czas odpowiedzi i chroni Serwer-Doświadczenie pod obciążeniem.
blk-mq w praktyce: none vs. noop i domyślne ustawienia jądra
Od wersji jądra 5.x standardową ścieżką jest konstrukcja wielokolejkowa. W tym przypadku brak odpowiednik „Noop“ dla blk-mq, podczas gdy noop historycznie pochodzi ze ścieżki pojedynczej kolejki. Na urządzeniach NVMe zazwyczaj tylko brak dostępne; na SATA/SAS często widuje się mq-deadline, opcjonalnie bfq i w zależności od dystrybucji również kyber. Domyślne ustawienia są różne: NVMe zazwyczaj uruchamia się z brak, SCSI/SATA często z mq-deadline. Dlatego zawsze sprawdzam dostępne opcje za pomocą cat /sys/block//queue/scheduler i podejmuję decyzję dla każdego urządzenia. Gdzie tylko brak można wybrać, jest to zamierzone – dodatkowe sortowanie nie wnosi tu praktycznie żadnej wartości dodanej.
Noop w zastosowaniu serwerowym: kiedy minimalizm wygrywa
Noop wykonuje przede wszystkim scalanie sąsiednich bloków, ale nie sortuje ich, co znacznie zmniejsza obciążenie procesora. niski Na dyskach SSD i NVMe kontrolery i oprogramowanie układowe przejmują inteligentną kolejność, więc dodatkowe sortowanie w jądrze nie przynosi prawie żadnych korzyści. W maszynach wirtualnych i kontenerach często planuję Noop, ponieważ hiperwizor i tak planuje globalnie. Na dyskach obrotowych rezygnuję z Noop, ponieważ brak sortowania zwiększa tam czasy wyszukiwania. Jeśli chcesz bezpiecznie wyodrębnić kontekst sprzętowy, najpierw sprawdź typ pamięci – pomocne będzie tutaj spojrzenie na NVMe, SSD i HDD, zanim uruchomię harmonogram ustalam.
mq-deadline: terminy, kolejność i jasne priorytety
mq-deadline nadaje operacjom odczytu krótkie terminy, a operacjom zapisu nieco dłuższe, aby Czas reakcji w sposób zauważalny. Harmonogram sortuje również według adresów bloków, skracając tym samym czas wyszukiwania, co jest szczególnie pomocne w przypadku dysków twardych i macierzy RAID. W serwerach internetowych i baz danych mq-deadline zapewnia dobrą równowagę między opóźnieniem a przepustowością. Chętnie używam go, gdy obciążenia są mieszane i zarówno odczyty, jak i zapisy są stale w kolejce. W celu precyzyjnego dostrojenia sprawdzam głębokość żądania, zachowanie zapisu zwrotnego i pamięć podręczną kontrolera, aby logika terminu była spójna. chwyty.
BFQ: sprawiedliwość i szybkość reakcji dla wielu użytkowników jednocześnie
BFQ rozdziela przepustowość proporcjonalnie i przydziela budżety dla poszczególnych procesów, co jest zauważalne. uczciwy działa, gdy wielu użytkowników generuje równolegle operacje wejścia/wyjścia. Zadania interaktywne, takie jak powłoki administracyjne, edytory lub wywołania API, pozostają szybkie, mimo że w tle działają kopie zapasowe. Na dyskach HDD BFQ często osiąga wysoką wydajność, ponieważ wykorzystuje fazy sekwencyjne i mądrze wykorzystuje krótkie okna bezczynności. Na bardzo szybkich dyskach SSD powstaje niewielki dodatkowy nakład pracy, który rozważam w stosunku do zauważalnej szybkości reakcji. Użytkownicy cgroups i ioprio mogą uzyskać jasne gwarancje dzięki BFQ i uniknąć kłopotów spowodowanych hałaśliwymi sąsiadami. Unikać.
QoS w codziennym użytkowaniu: ioprio, ionice i Cgroups v2 z BFQ
Dla czystych Ustalanie priorytetów Łączę BFQ z regułami procesowymi i regułami cgroup. Na poziomie procesów ustawiam za pomocą ionice Klasy i priorytety: ionice -c1 (w czasie rzeczywistym) dla odczytów krytycznych pod względem opóźnień, ionice -c2 -n7 (najlepszy wysiłek, niski) dla kopii zapasowych lub indeksowania, ionice -c3 (Idle) dla wszystkiego, co ma działać tylko w czasie bezczynności. W Cgroups v2 używam io.weight dla wartości względnych (np. 100 vs. 1000) oraz io.max dla twardych limitów, np. echo "259:0 rbps=50M wbps=20M" > /sys/fs/cgroup//io.max. Dzięki BFQ wagi są bardzo precyzyjnie przekształcane w udziały w przepustowości – idealne rozwiązanie dla hostingu współdzielonego i hostów kontenerowych, na których Sprawiedliwość jest ważniejsza niż maksymalna moc surowa.
Porównanie praktyczne: jaki wybór sprzętu jest odpowiedni
Wybór zależy w dużej mierze od typu pamięci i architektury kolejki, dlatego najpierw sprawdzam Urządzenie i kontrolery. Dyski SSD i NVMe zazwyczaj korzystają z Noop/none, natomiast dyski HDD działają płynniej z mq-deadline lub BFQ. W konfiguracjach RAID, sieciach SAN i wszechstronnych hostach często preferuję mq-deadline, ponieważ logika Deadline i sortowanie dobrze ze sobą współgrają. Środowiska wieloużytkownikowe z wieloma sesjami interaktywnymi często zyskują dzięki BFQ. Poniższa tabela zawiera przejrzyste podsumowanie mocnych stron i sensownych obszarów zastosowań. razem:
| harmonogram | Sprzęt | Mocne strony | Słabe strony | Scenariusze hostingu |
|---|---|---|---|---|
| Noop/brak | SSD, NVMe, maszyny wirtualne | Minimalne obciążenie, czyste scalanie | Bez sortowania na dyskach twardych niekorzystne | Serwer Flash, kontener, sterowany hiperwizorem |
| mq-deadline | HDD, RAID, serwer uniwersalny | Ścisły priorytet odczytu, sortowanie, stałe opóźnienie | Więcej logiki niż Noop | Bazy danych, zaplecze internetowe, obciążenia mieszane |
| BFQ | HDD, wielu użytkowników, hosty podobne do komputerów stacjonarnych | Uczciwość, szybkość reakcji, dobre sekwencje | Nieco większe obciążenie bardzo szybkich dysków SSD | Usługi interaktywne, hosting współdzielony, serwer deweloperski |
Konfiguracja: sprawdź harmonogram i ustaw go na stałe
Najpierw sprawdzam, który harmonogram jest aktywny, na przykład za pomocą cat /sys/block/sdX/queue/scheduler, i zanotuj Opcja w nawiasach kwadratowych. Aby dokonać tymczasowej zmiany, wpisuję na przykład echo mq-deadline | sudo tee /sys/block/sdX/queue/scheduler. Aby ustawienia były trwałe, używam reguł udev lub parametrów jądra, takich jak scsi_mod.use_blk_mq=1 oraz mq-deadline w wierszu poleceń. W przypadku urządzeń NVMe sprawdzam ścieżki pod /sys/block/nvme0n1/queue/ i ustaw wybór dla każdego urządzenia. Ważne: dokumentuję zmiany, aby konserwacja i przywracanie poprzedniego stanu przebiegały bez zgadywania. odnieść sukces.
Wytrwałość i automatyzacja w działaniu
W codziennym życiu przedkładam powtarzalność nad automatyzację. Sprawdziły się trzy sposoby:
- Reguły udev: Przykład dla wszystkich dysków twardych (rotacyjny=1)
echo 'ACTION=="add|change", KERNEL=="sd*", ATTR{queue/rotational}=="1", ATTR{queue/scheduler}="mq-deadline"' > /etc/udev/rules.d/60-io-scheduler.rules, toudevadm control --reload-rules && udevadm trigger. - systemd-tmpfiles: Dla konkretnych urządzeń definiuję
/etc/tmpfiles.d/blk.confz takimi zdaniami jakw /sys/block/sdX/queue/scheduler - - - - mq-deadline, które zapisują podczas uruchamiania systemu. - Zarządzanie konfiguracją: W Ansible/Salt tworzę klasy urządzeń (NVMe, HDD) i rozdzielam spójne ustawienia domyślne wraz z dokumentacją i funkcją przywracania.
Uwaga: windy= jako parametr jądra obowiązywał dla starej ścieżki pojedynczej kolejki. W blk-mq sam decyduję o wyborze na urządzenie. W przypadku stosów (dm-crypt, LVM, MD) ustawiam domyślną wartość na najwyższym urządzeniu, więcej na ten temat poniżej.
Obciążenia w hostingu: rozpoznawanie wzorców i właściwe działanie
Najpierw analizuję obciążenie: wiele małych odczytów wskazuje na interfejsy internetowe, synchronizacyjne zapisy w bazach danych i potokach dzienników, duże sekwencyjne strumienie w kopiach zapasowych lub Archiwum. Narzędzia takie jak iostat, vmstat oraz blktrace pokazują kolejki, opóźnienia i efekty scalania. W przypadku zauważalnego czasu bezczynności procesora spowodowanego operacjami wejścia/wyjścia odsyłam do Zrozumienie oczekiwania na operacje wejścia/wyjścia, aby w sposób uporządkowany wyeliminować wąskie gardła. Następnie testuję 1–2 kandydatów do harmonogramu w identycznych przedziałach czasowych. Decydujące znaczenie mają wyniki pomiarów, a nie przeczucia lub mity.
Pogłębienie praktyki pomiarowej: powtarzalne benchmarki
Aby podejmować trafne decyzje, korzystam z kontrolowanych fio-Profile i potwierdź za pomocą rzeczywistych testów aplikacji:
- Losowe odczyty (Internet/pamięć podręczna):
fio --name=rr --rw=randread --bs=4k --iodepth=32 --numjobs=4 --runtime=120 --time_based --filename=/mnt/testfile --direct=1 - Losowa mieszanka (DB):
fio --name=randmix --rw=randrw --rwmixread=70 --bs=8k --iodepth=64 --numjobs=8 --runtime=180 --time_based --direct=1 - Sekwencyjnie (Kopia zapasowa):
fio --name=seqw --rw=write --bs=1m --iodepth=128 --numjobs=2 --runtime=120 --time_based --direct=1
Równolegle loguję się iostat -x 1, pidstat -d 1 i zanotuj opóźnienia P95/P99 fio. Do przeprowadzania szczegółowych diagnoz stosuję blktrace lub narzędzia eBPF, takie jak biolatencja Ważne: pomiary wykonuję o tej samej porze dnia, przy takim samym obciążeniu i przy plikach o tej samej wielkości. Efekty pamięci podręcznej minimalizuję za pomocą direct=1 i czystych warunków wstępnych (np. wstępne wypełnienie wolnego miejsca na dysku).
Systemy plików i harmonogramy operacji wejścia/wyjścia: liczy się współdziałanie
System plików wpływa na charakterystykę operacji wejścia/wyjścia, dlatego bardzo dokładnie sprawdzam jego tryb dziennika, głębokość kolejki i zachowanie synchronizacji. dokładnie. EXT4 i XFS działają wydajnie z mq-deadline, podczas gdy ZFS sam buforuje i agreguje wiele danych. Na hostach z ZFS często obserwuję mniejszy efekt harmonogramu, ponieważ ZFS już formułuje dane wyjściowe. Do porównań używam identycznych opcji montowania i obciążeń. Osoby rozważające różne opcje znajdą w EXT4, XFS lub ZFS pomocne perspektywy na Przechowywanie-Tuning.
Writeback, pamięć podręczna i bariery: często pomijana połowa
Harmonogramy mogą działać tylko tak dobrze, jak pozwala na to podsystem zapisu zwrotnego. Dlatego zawsze sprawdzam:
- parametr dirty:
sysctl vm.dirty_background_bytes,vm.dirty_bytes,vm.dirty_expire_centisecskontrolować, kiedy i jak agresywnie jądro zapisuje dane. W przypadku baz danych często obniżam szczyty burst, aby utrzymać stabilność P99. - Bariery/Flush: Opcje takie jak EXT4
barieralub domyślne operacje opróżniania XFS zabezpieczam tylko wtedy, gdy przejmuje je sprzęt (np. BBWC). „nobarrier“ bez zabezpieczenia przed przepięciem jest ryzykowny. - Pamięć podręczna zapisu urządzenia: Sprawdzam ustawienia pamięci podręcznej zapisu kontrolera, aby
fsyncnaprawdę trafia na nośnik, a nie tylko do pamięci podręcznej.
Wygładzając writeback, odciążasz harmonogram – terminy pozostają niezawodne, a BFQ musi mniej pracować nad nagłymi falami flush.
Wirtualizacja, kontenery i chmura: kto naprawdę planuje?
W maszynach wirtualnych hiperwizor kontroluje fizyczny przepływ danych wejściowych/wyjściowych, dlatego często wybieram opcję Noop/none w systemie-gościu, aby uniknąć podwójnego Logika . Na samym hoście używam mq-deadline lub BFQ w zależności od urządzenia i zadania. W przypadku woluminów w chmurze (np. sieciowej pamięci blokowej) część planowania odbywa się w backendzie, dlatego mierzę rzeczywiste opóźnienia zamiast polegać na założeniach. W przypadku hostów kontenerowych o bardzo zróżnicowanym obciążeniu BFQ często zapewnia lepszą interaktywność. W jednorodnych klastrach wsadowych z pamięcią flash Noop dominuje, ponieważ liczy się każdy czas procesora, a kontrolery są wydajne. praca.
RAID, LVM, MD i Multipath: gdzie działa harmonogram
W ułożonych w stosy blokach ustawiam harmonogram na Najlepsze urządzenie ponieważ tam znajdują się odpowiednie kolejki:
- LVM/dm-crypt: Harmonogram na
/dev/dm-*Odpowiednio/dev/mapper/. Fizyczne PV pozostawiam zazwyczaj na poziomiebrak, aby uniknąć podwójnego scalania/sortowania. - MD-RAID: Am
/dev/mdXdecyzja; poniżejsdXUrządzenia pozostają spokojnebrak. RAID sprzętowy jest traktowany jak pojedyncze urządzenie blokowe. - Wielodrożność: W modułach mapujących ścieżki wielokrotne (
/dev/mapper/mpatha); urządzenia ścieżki poniżej nabrak.
Ważne: Dzielę testy według basen i poziom redundancji (RAID1/10 vs. RAID5/6). Macierze RAID z parzystością są bardziej wrażliwe na losowe zapisy; w tym przypadku mq-deadline często wygrywa dzięki konsekwentnym terminom odczytu i uporządkowanemu wyjściu.
Strategie tuningu: krok po kroku do niezawodnej wydajności
Zaczynam od pomiaru podstawowego: aktualne czasy odpowiedzi, przepustowość, 95./99. percentyl i CPU.Obciążenie. Następnie zmieniam tylko jeden czynnik, zazwyczaj harmonogram, i powtarzam to samo obciążenie. Narzędzia takie jak fio pomagają w kontroli, ale potwierdzam każdą hipotezę rzeczywistymi testami aplikacji. W przypadku baz danych odpowiednie są własne testy porównawcze, które odzwierciedlają transakcje i zachowanie fsync. Dopiero gdy pomiar jest stabilny, zapisuję wybór i dokumentuję go. Dlaczego.
Głębokość kolejki, odczyt z wyprzedzeniem i powinowactwo procesora
Oprócz harmonogramu, parametry kolejki mają duży wpływ na praktykę:
- Głębokość kolejki:
/sys/block//queue/nr_requestsOgraniczona liczba oczekujących żądań na kolejkę sprzętową. NVMe obsługuje dużą głębokość (wysoka przepustowość), dyski HDD korzystają z umiarkowanej głębokości (bardziej stabilne opóźnienia). - Readahead:
/sys/block//queue/read_ahead_kbOdpowiednioblockdev --getra/setra. Nieco wyższa dla obciążeń sekwencyjnych, niska dla obciążeń losowych. - rq_affinityZ
/sys/block//queue/rq_affinityW punkcie 2 dbam o to, aby zakończenie operacji wejścia/wyjścia trafiało przede wszystkim do rdzenia procesora, który je generuje – zmniejsza to koszty międzyprocesorowe. - rotacyjny: Sprawdzam, czy dyski SSD
rotacyjny=0zgłoś, aby jądro nie stosowało heurystyki HDD. - Scalenia:
/sys/block//queue/nomergesmoże zmniejszyć liczbę połączeń (2=wyłączone). W przypadku mikrolatencji NVMe może to być częściowo korzystne, ale w przypadku dysków HDD jest to zazwyczaj niekorzystne. - io_poll (NVMe): Polling może zmniejszyć opóźnienia, ale wymaga procesora. Aktywuję go celowo w przypadku Niskie opóźnienia-Wymagania.
Szczegółowe informacje o parametrach harmonogramu
W zależności od harmonogramu dostępne są przydatne opcje precyzyjnej regulacji:
- mq-deadline:
/sys/block//queue/iosched/read_expire(ms, zazwyczaj niewielki),write_expire(większy),fifo_batch(wielkość partii),front_merges(0/1). Uważam, żeread_expirekrótko, aby chronić odczyty P95, i dostosujfifo_batchw zależności od urządzenia. - BFQ:
slice_idle(czas bezczynności do wykorzystania sekwencji),niskie opóźnienie(0/1) dla interaktywności o szybkiej reakcji. Dziękibfq.weightW Cgroups bardzo precyzyjnie kontroluję względne udziały. - brak/noop: Prawie żadnych śrub regulacyjnych, ale Otoczenie (głębokość kolejki, odczyt z wyprzedzeniem) decyduje o wynikach.
Zawsze zmieniam tylko jeden parametr i dokładnie zapisuję tę zmianę – dzięki temu wiadomo, co miało jaki efekt.
Częste pułapki i jak ich unikać
Mieszane pule HDD i SSD za kontrolerem RAID zafałszowują wyniki testów, dlatego oddzielam pomiary dla każdego z nich. Grupa. Nie zapominam, że harmonogram dotyczy każdego urządzenia blokowego – mapery LVM i urządzenia MD traktuję oddzielnie. Trwałość często się wymyka: bez reguły udev lub parametru jądra po ponownym uruchomieniu przywracane są ustawienia domyślne. Grupy C i priorytety I/O często pozostają niewykorzystane, mimo że znacznie zwiększają sprawiedliwość. Zawsze sprawdzam głębokość kolejki, writeback i opcje systemu plików, aby wybrana logika mogła w pełni wykorzystać swój potencjał. pokazy.
Rozwiązywanie problemów: dokładne odczytanie objawów
Kiedy wartości pomiarowe ulegają zmianie, interpretuję wzorce i wyznaczam konkretne działania:
- Wysokie opóźnienie P99 przy wielu odczytach: Sprawdź, czy zapisy wypierają odczyty. Przetestuj za pomocą mq-deadline.,
read_expireobniżyć, wygładzić writeback (vm.dirty_*dostosować). - 100% util na dysku twardym, niska przepustowość: Dominują poszukiwania. Wypróbuj BFQ lub mq-deadline, zmniejsz Readahead, zmniejsz głębokość kolejki.
- Dobra wydajność, ale interfejs użytkownika działa nierówno: Interaktywność ulega pogorszeniu. Aktywuj BFQ, usługi krytyczne poprzez
ionice -c1lub preferują wagi Cgroup. - Duże zróżnicowanie w zależności od pory dnia: Podzielone zasoby. Izolowanie za pomocą cgroupów, wybór harmonogramu dla każdej puli, przenoszenie kopii zapasowych poza godziny szczytu.
- Limity czasu NVMe w dmesg: Backend lub kwestia oprogramowania układowego.
io_pollWyłączyć na próbę, sprawdzić oprogramowanie sprzętowe/sterownik, zweryfikować redundancję ścieżki (multipath).
W skrócie: jasne decyzje dotyczące codziennego hostingu
W przypadku pamięci flash i gości często wybieram Noop, aby zaoszczędzić na kosztach ogólnych i umożliwić pracę kontrolerów. W serwerach uniwersalnych z dyskami HDD lub RAID mq-deadline zapewnia niezawodną latencję i wysoką użyteczność. W przypadku wielu aktywnych użytkowników i interaktywnego obciążenia BFQ zapewnia sprawiedliwy podział i zauważalną szybkość reakcji. Przed każdym zapisaniem dokonuję pomiarów przy użyciu rzeczywistych obciążeń i obserwuję efekty na P95/P99. W ten sposób podejmuję zrozumiałe decyzje, utrzymuję systemy w dobrym stanie i stabilizuję Serwer-Wydajność w codziennej działalności.


