IRQ Balance regelt onder Linux de verdeling van hardware-interrupts over CPU-kernen en bepaalt daarmee of de netwerkbelasting gelijkmatig wordt verdeeld of dat bepaalde kernen worden afgeremd. Ik laat je zien hoe je irqbalance doelgericht kunt inzetten, wanneer ik overschakel naar handmatige IRQ-affiniteit en welke instellingen geschikt zijn voor servers met een hoge netwerkbelasting echt tellen.
Centrale punten
Voordat ik in detail treed, vat ik de belangrijkste beslissingen samen die mij in projecten met een hoge I/O-belasting altijd goed van pas zijn gekomen. Ik vind het zinvol om de automatische verdeling via irqbalance als uitgangspunt te nemen, het effect te meten en selectief aanpassingen te doen. Bij deterministische workloads koppel ik afzonderlijke IRQ's handmatig aan bepaalde kernen en sluit ik de overige CPU's uit van de automatische verdeling. Ik houd al in een vroeg stadium rekening met NUMA-nabijheid, omdat dit de latentie verlaagt en de doorvoer waarborgt. Met duidelijke monitoring herken ik knelpunten sneller en los ik deze op zonder onnodige Risico's.
Deze lijst laat zien waar ik bij de configuratie extra op let:
- Automatisch Eerst: irqbalance inschakelen, het effect meten
- affiniteit gericht: kritieke IRQ's vastzetten, jitter verminderen
- Verboden CPU's: Ruimte vrijhouden voor app-threads
- NUMA Let op: houd IRQ’s dicht bij het geheugenknooppunt
- Controle: /proc/interrupts en latenties controleren
IRQ-basisprincipes in het kort uitgelegd
Een interruptverzoek (IRQ) is een signaal waarmee hardware taken aan de CPU overdraagt en daarmee een lopende taak onderbreekt. Als er te veel van deze signalen bij dezelfde kern binnenkomen, neemt de belasting daar toe en wordt de reactietijd traag, terwijl andere kernen onbenut blijven; dat is precies wat ik wil bereiken met Distributie vermijden. irqbalance verdeelt deze IRQ’s dynamisch over meerdere kernen en beoordeelt met regelmatige tussenpozen de systeemstatus. Ik bekijk daarvoor eerst /proc/onderbrekingen en kijk in de kolommen hoeveel IRQ’s er per CPU binnenkomen. Als bepaalde kolommen te groot worden, pas ik dit actief aan en verminder zo onnodige Hotspots.
Automatische verdeling met irqbalance
Op moderne distributies start ik met de service irqbalance, die standaard de IRQ-verdeling periodiek aanpast. Ik schakel deze service handmatig in met systemctl enable --now irqbalance en controleer ik de status voordat ik ingrijpender maatregelen neem; zo maak ik gebruik van de beschikbare Automatisch. De configuratiebestanden bevinden zich, afhankelijk van het systeem, in /etc/sysconfig/irqbalance of /etc/default/irqbalance, daar kan ik CPU's of IRQ's uitsluiten. De variabele is bijzonder nuttig IRQBALANCE_BANNED_CPUS als 64-bits masker om bepaalde kernen voor applicaties te reserveren. Wie zich verder wil verdiepen in praktijkvoorbeelden, vindt hier een beknopte inleiding tot de Netwerkprestaties, waarnaar ik in workshops vaak verwijs en die ik in projecten toepas.
IRQ-affiniteit handmatig veilig implementeren
Als workloads erg gevoelig zijn voor jitter of als bepaalde kernen uitsluitend vrij moeten blijven voor user-space-processen, stel ik de IRQ-affiniteit handmatig in. Hiervoor schrijf ik bitmaskers na /proc/irq/IRQ-NUMMER/smp_affinity en bepaal op welke kerns een interrupt mag worden uitgevoerd; dat maakt het mogelijk om te plannen Gedrag. Eerst bepaal ik de relevante IRQ-nummers met grep in /proc/onderbrekingen. Voor netwerkapparaten wijs ik RX/TX-wachtrijen vaak toe aan kernen die dicht bij de app-threads liggen, terwijl ik andere kernen vrijhoud. Deze korte uitleg geeft een goed inzicht in deze aanpak Gids voor IRQ-affiniteit, die ik regelmatig als uitgangspunt gebruik.
De volgende tabel toont veelgebruikte bitmaskers en wat ze betekenen. Ik gebruik deze voorbeelden om configuraties snel en foutloos in te stellen en het effect vervolgens te controleren met /proc/onderbrekingen naar verifiëren.
| Doel | Voorbeeldmasker (hex) | kernen | Commentaar |
|---|---|---|---|
| Alleen CPU0 | 0x1 | 0 | Eenvoudige test, weinig verspreiding |
| Alleen CPU1 | 0x2 | 1 | Scheidt IRQ's van CPU0, verlaagt Interferentie |
| CPU0–CPU1 | 0x3 | 0–1 | Verdeeld over twee kernen, licht Hulp |
| CPU2–CPU3 | 0xC | 2-3 | Handig als 0–1 voor app-threads gratis blijf |
| CPU0–CPU3 | 0xF | 0–3 | Brede spreiding over 4 kernen, mengt Belasting |
Meting: /proc/interrupts correct uitlezen
Ik open het bestand /proc/onderbrekingen en zie per rij een IRQ en per kolom de tellers per CPU; dat maakt onevenwichtigheden meteen duidelijk zichtbaar. Als een kolom aanzienlijk sneller groeit dan andere, concentreert de belasting zich daar. Vervolgens controleer ik welke driver hierbij betrokken is en of RSS/RPS al wordt verdeeld. Daarnaast start ik irqbalance tijdelijk op de voorgrond met debug-uitvoer, om zijn beslissingen te begrijpen en verkeerde inschattingen te voorkomen. Na elke wijziging controleer ik de tellers opnieuw en meet ik de latentie onder belasting, zodat ik effecten kan aantonen en onnodige Risico's kan vermijden.
CPU-isolatie en verboden maskers
Ik stel IRQBALANCE_BANNED_CPUS, om bepaalde kernen consequent uit te sluiten van de automatische toewijzing; zo houd ik resources vrij voor app-threads. In nieuwere configuraties maak ik bovendien gebruik van IRQBALANCE_BANNED_IRQS, wanneer afzonderlijke apparaten zelfstandig op één kern moeten draaien; dat vermindert storingen voor gevoelige Werklasten. In scenario’s met lage latentie schakel ik irqbalance doelbewust uit en wijs ik IRQ’s statisch toe, zodat er geen herverdeling plaatsvindt die het proces verstoort. Wie de CPU-toewijzing bij interruptverwerking beter wil begrijpen, vindt nuttige achtergrondinformatie over de Afhandeling van interrupts op servers. Belangrijk blijft: eerst meten, dan vaststellen en het effect opnieuw controleren, om verrassingen in de Operatie te vermijden.
NUMA-aspecten en nabijheid
Op NUMA-systemen zorg ik ervoor dat IRQ’s zoveel mogelijk worden doorgestuurd naar de kernen van die NUMA-knoop waarin de betreffende gegevens in het geheugen zijn opgeslagen; dit vermindert de latentie en verhoogt Doorvoer. Ik combineer dit met CPU-affiniteit voor de applicatie, zodat threads en interrupts lokaal ten opzichte van elkaar worden uitgevoerd. irqbalance werkt goed op NUMA, maar indien nodig pas ik het aan met banned-maskers. Het is van cruciaal belang om de belasting niet over knooppunten te verspreiden als deze toch lokaal kan worden gehouden. Wie deze nabijheid handhaaft, profiteert van constante responstijden en spaart kostbare Cache-bronnen.
Netwerkintensief: RSS, RPS/RFS en XPS
Voordat ik IRQ-maskers nauwkeurig afstem, controleer ik de NIC-functies zoals RSS en kernelmechanismen zoals RPS/RFS en XPS; deze hebben een grote invloed op de verdeling van pakketten. RSS verdeelt wachtrij-interrupts al over meerdere kernen, terwijl RPS/RFS de verwerking in de kernel en XPS de verzendpaden vormgeven; dit voorkomt onnodige Hotspots. Ik stem deze mechanismen af op mijn IRQ-strategie, zodat ze elkaar niet tegenwerken. Als de wachtrijen, de IRQ-affiniteiten en de app-affiniteit op elkaar zijn afgestemd, verloopt de netwerk-I/O aanzienlijk soepeler. Daarna voer ik opnieuw metingen uit onder reële belasting, voordat ik verdere Stappen zet.
MSI-X, Multi-Queue en een overzichtelijke wachtrijindeling
Veel 10–100G-NIC’s maken gebruik van MSI-X en stellen per RX/TX-wachtrij eigen interruptvectoren beschikbaar. Ik controleer dit eerst met ethtool -l eth0 (aantal kanalen) en /proc/onderbrekingen, hoeveel wachtrijen er werkelijk actief zijn en hoe ze heten (bijv. eth0-TxRx-0, eth0-TxRx-1). Het doel is om het aantal wachtrijen af te stemmen op het aantal gebruikte kernen per NUMA-knooppunt en deze deterministisch vast te zetten. Met ethtool -L eth0 combined N stel ik het aantal wachtrijen in; daarna rangschik ik de resulterende IRQ’s via smp_affinity geschikte kernen. Ik zorg ervoor dat RX/TX-paren van dezelfde wachtrij op dezelfde kern of in ieder geval op dezelfde socket worden geplaatst, zodat Cache-locatie van toepassing is. Belangrijk: wijzigingen in het aantal wachtrijen en de affiniteit controleer ik direct in /proc/onderbrekingen en met een korte belastingstest (pps/doorvoersnelheid), voordat ik verder ga met optimaliseren.
Interrupt-coalescentie en NAPI-budget
Vooral bij hoge pakketfrequenties beïnvloeden de coalescentiewaarden de effectiviteit van mijn IRQ-strategie. Met ethtool -c eth0 zie ik of rx-usecs en rx-monturen zijn ingesteld. Meer coalescentie vermindert het aantal IRQ’s per seconde en bespaart CPU-vermogen, maar verhoogt de latentie en jitter. Ik pas de instellingen voorzichtig aan: kleine stapjes, telkens meten (p95/p99-latentie en CPU-belasting). Aan de zendzijde heeft dit tx-usecs analoog. Daarnaast pas ik het NAPI-gedrag aan via net.core.netdev_budget en net.core.netdev_budget_usecs, wanneer NET_RX in SoftIRQ's begint op te stapelen. Als het aantal drops toeneemt in /proc/net/softnet_stat, verhoog ik bij wijze van test het budget of verdeel ik de RX-wachtrijen consequenter; als de systeemlatentie te hoog wordt, schroef ik het weer terug. Ik houd rekening met GRO/LRO en TSO/GSO in onderlinge samenhang: overmatige aggregatie verlaagt de IRQ-belasting, maar kan latentiepieken veroorzaken – ik stem deze af op het applicatieprofiel.
SoftIRQ's transparant lezen
Naast HardIRQ's bepaal ik ook de belasting van de SoftIRQ's. Met cat /proc/softirqs Ik observeer NET_RX en NET_TX per CPU; als bepaalde kolommen de overhand hebben, komt er te veel werk terecht in de ksoftirqd-threads. Een top -H laat me snel zien welke ksoftirqd/N Kernen belasten. Ik meet dieper met perf top of korte perf record Uitvoeren om hotspots in het stuurprogramma of de stackverwerking te identificeren. Als ksoftirqd-threads actief worden (in plaats van directe verwerking in de IRQ-context), neemt de latentie vaak aanzienlijk toe; ik reageer hierop met een betere wachtrijverdeling, een groter NAPI-budget of gerichte CPU-pinning van de betreffende ksoftirqd-threads via taskset -pc. Belangrijk: ik leg deze aanpassingen vast, omdat ze subtiele gevolgen hebben en ik in geval van twijfel snel een rollback nodig heb.
SMT/Hyper-Threading en topologie op de juiste manier gebruiken
Met SMT ingeschakeld deel ik één fysieke kern met twee logische CPU’s. Ik controleer de sibling-relaties via lscpu -e en /sys/devices/system/cpu/cpuX/topology/thread_siblings_list. Voor latentiegevoelige paden vermijd ik het om de app-thread en de bijbehorende IRQ op dezelfde fysieke kern (verschillende SMT-threads) te plaatsen; ze concurreren namelijk om uitvoereenheden en caches. Ik geef de voorkeur aan combinaties waarbij bijvoorbeeld een app-thread op CPU2 draait en de bijbehorende RX-wachtrij op CPU3 (andere fysieke kern, hetzelfde NUMA-knooppunt). Als SMT de consistentie verstoort, plan ik in plaats daarvan met minder, maar exclusieve fysieke kernen en bespaar ik mezelf onrustige Interferenties.
Virtualisatie: KVM, vhost en SR-IOV
In gevirtualiseerde omgevingen beschouw ik de host en de gast als afzonderlijke entiteiten. Op de host verdeel ik fysieke NIC-IRQ’s netjes over de kernen van het betreffende NUMA-knooppunt. Als de gast virtio-net gebruikt, ontstaan er extra IRQ’s voor vhost-threads; ik herken ze in /proc/onderbrekingen en koppel vhost-workers consistent aan de wachtrijen van de fysieke NIC. Op gastniveau stel ik ook RSS/XPS- en IRQ-affiniteiten in, voor zover het virtio-stuurprogramma meerdere wachtrijen biedt. Bij SR-IOV loont het de moeite om elke gast een of meer VF’s met eigen MSI-X-vectoren toe te wijzen en deze in de gast te pinnen; de isolatie verbetert de latentie en voorspelbaarheid. Ik houd me aan een duidelijk schema: vCPU’s van de gast op speciale pCPU’s, bijbehorende IRQ’s op nabijgelegen kernen, en de emulator-/vhost-threads niet vermengen met rekenintensieve app-threads – zo blijft het datapad planbaar.
CPU-frequentie, C-states en NOHZ-tuning
IRQ-latenties hebben eronder te lijden wanneer kernen in diepe C-toestanden terechtkomen of agressief klokken. Voor gevoelige workloads stel ik de CPU-governor in op prestatie (cpupower frequency‑set -g performance) en beperk ik diepe C-toestanden via opstart- of stuurprogramma-opties om de opstarttijden te beperken. Op zwaar belaste servers heeft dit vaak een positiever effect dan welke fijnafstemming van affiniteiten dan ook. Bij zeer strenge latentieprofielen voeg ik toe nohz_full= en rcu_nocbs= voor geïsoleerde kernen, zodat de tick-timer en RCU-callbacks elkaar niet verstoren; de housekeeping-CPU’s definieer ik bewust afzonderlijk. Deze aanpassingen test ik echter apart, omdat ze neveneffecten kunnen hebben op de planning en het energieverbruik. Het blijft cruciaal om de meetwaarden vóór en na de wijziging zorgvuldig te vergelijken, anders loop ik het risico dat ik bij Optimalisaties in het donker.
Systemd, cgroups en app-isolatie
Naast IRQ-pinning scheid ik app-threads met Cgroups en systemd-affinity. Via CPUAffiniteit= In Unit-bestanden en de CPU-controllers (cgroup v2) wijs ik diensten vaste cores toe. Zo voorkom ik dat threads door de scheduler worden verplaatst naar de CPU’s die ik voor IRQ’s heb gereserveerd. In containeromgevingen stel ik cpuset.cpus en controleer cpuset.cpus.effective, zodat toezeggingen over middelen ook daadwerkelijk worden nagekomen. Belangrijk: IRQBALANCE_BANNED_CPUS stuurt alleen aan waar irqbalance niet verdeelt; kernel-threads zoals ksoftirqd blijven de scheduler volgen. Voor strikte isolatie heb ik dus een combinatie nodig van IRQ-affiniteiten, CPU-affiniteit van de diensten en eventueel geïsoleerde kernels. Zo blijven het gegevenspad en de toepassing duidelijk gescheiden en de Belasting mengt zich niet op ongecontroleerde wijze.
Veelvoorkomende fouten en oplossingen
Ik schakel irqbalance nooit zomaar uit zonder de belastingprofielen te kennen; anders hopen de IRQ’s zich al snel op een paar kernen op. Het is eveneens ongewenst om alle kernen voor alle IRQ’s open te stellen, hoewel gevoelige threads exclusief Bronnen nodig hebben. Nog een fout: wijzigingen niet afzonderlijk testen en de effecten niet meten; zo blijft het onduidelijk wat daadwerkelijk helpt. Ik houd ook rekening met Hyper-Threading-paren: de app-thread en de bijbehorende IRQ kunnen beter niet dezelfde fysieke kern delen. Ik documenteer elke stap en maak terugzetpunten, zodat ik bij problemen snel terug kan naar de laatste goed Terug naar de configuratie.
Praktische checklist voor servers
Ik begin altijd met een uitgangssituatie: irqbalance ingeschakeld, de systeembelasting vaststellen, /proc/interrupts in de gaten houden en de latenties meten; pas daarna pas ik de instellingen aan. In de tweede stap sluit ik af met IRQBALANCE_BANNED_CPUS selecteer ik de kernen die voor app-threads gereserveerd moeten blijven; zo voorkom ik onnodige IRQ-onderbrekingen. Vervolgens pin ik kritieke IRQ's via smp_affinity op een klein aantal, zorgvuldig gekozen kernen en zorg ervoor dat de NUMA-afstand binnen de grenzen blijft. Vervolgens controleer ik RSS/RPS/RFS en XPS, evenals de offloading-opties van de NIC, om de werklast op een zinvolle manier te verdelen. Tot slot test ik onder productielast, vergelijk ik de statistieken en behoud ik alleen die wijzigingen waarvan aantoonbaar is dat ze werk.
Configuratiebestanden en systemd-opdrachten
Ik activeer de dienst met systemctl enable --now irqbalance en controleer met systemctl status irqbalans de looptijd; zo stel ik de Service zeker klaar. In /etc/sysconfig/irqbalance of /etc/default/irqbalance ik zet IRQBALANCE_BANNED_CPUS en optioneel IRQBALANCE_BANNED_IRQS. Wijzigingen neem ik over met systemctl restart irqbalance en houd tegelijkertijd de tellers in de gaten in /proc/onderbrekingen. Voor tests gebruik ik de foreground-modus van irqbalance om beslissingen in realtime te volgen. Pas als ik het gedrag begrijp, neem ik de aanpassingen definitief op in het Configuratie.
Wanneer ik irqbalance uitschakel
In realtime-opstellingen of bij toepassingen die uiterst gevoelig zijn voor latentie, stop ik `irqbalance` en wijs ik IRQ’s statisch toe, zodat er geen herverdeling plaatsvindt die storingen veroorzaakt. Ik isoleer de kernen voor deze workloads en laat verkeers-IRQ’s bewust op andere kernen draaien; zo blijven applicatiethreads planbaar. Ook bij strikt gescheiden tenant-omgevingen is deze aanpak de moeite waard, omdat ik zo interferenties tussen VM’s of containers verminder. Als er stuurprogramma’s zijn die minder goed werken met de automatische instelling, sluit ik hun IRQ’s uit via een verbodenlijst. Zodra de belastingpatronen weer variabeler worden, activeer ik irqbalance opnieuw en controleer ik het effect met nieuwe Gemeten waarden.
Kort samengevat
Ik begin met irqbalance, meet het effect en pas het selectief aan, in plaats van overal blindelings in te grijpen; zo behoud ik het overzicht over het systeem en Transparantie. Voor gevoelige workloads wijs ik geschikte IRQ’s toe, isoleer ik kerns voor applicaties en houd ik rekening met NUMA-nabijheid. Met banned-maskers bepaal ik waar irqbalance mag werken en voorkom ik ongewenste verschuivingen. Ik controleer regelmatig /proc/onderbrekingen, latentie en doorvoersnelheid, zodat wijzigingen op een betrouwbare manier worden onderbouwd. Wie op deze manier te werk gaat, benut het potentieel van IRQ Balance ten volle en houdt servers onder netwerkbelasting merkbaar reactief.


