...

Harmonogram wejścia/wyjścia Linux: Noop, mq-deadline i BFQ w hostingu – wyjaśnienie

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, to udevadm control --reload-rules && udevadm trigger.
  • systemd-tmpfiles: Dla konkretnych urządzeń definiuję /etc/tmpfiles.d/blk.conf z takimi zdaniami jak w /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_centisecs kontrolować, 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 bariera lub 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 fsync naprawdę 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 poziomie brak, aby uniknąć podwójnego scalania/sortowania.
  • MD-RAID: Am /dev/mdX decyzja; poniżej sdX Urządzenia pozostają spokojne brak. 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 na brak.

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_requests Ograniczona 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_kb Odpowiednio blockdev --getra/setra. Nieco wyższa dla obciążeń sekwencyjnych, niska dla obciążeń losowych.
  • rq_affinityZ /sys/block//queue/rq_affinity W 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=0 zgłoś, aby jądro nie stosowało heurystyki HDD.
  • Scalenia: /sys/block//queue/nomerges moż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, że read_expire krótko, aby chronić odczyty P95, i dostosuj fifo_batch w 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ęki bfq.weight W 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_expire obniż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 -c1 lub 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_poll Wyłą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.

Artykuły bieżące