- irqbalance reparteix les interrupcions de maquinari entre nuclis per evitar colls d'ampolla en sistemes SMP, i és especialment útil en servidors d'alt trànsit.
- El rendiment real depèn de combinar irqbalance amb NAPI, cues de xarxa, buffers TCP ben dimensionats, qdisc moderns i algorismes de control de congestió com a BBR.
- Ajustaments avançats de la NIC (ring buffers, RSS/RPS, offloads) i l'assignació manual d'afinitat d'IRQ permeten afinar encara més la distribució de càrrega entre CPU.
- L'optimització global de Linux es completa amb canvis en memòria, swap, zram, sistemes de fitxers temporals i paràmetres d'escriptori i aplicacions com Firefox.
Quan comences a trastejar amb el rendiment d'un sistema GNU/Linux, tard o d'hora apareix un protagonista recurrent: irqbalance i el repartiment d'interrupcions de maquinari entre CPU. Se'n parla en fòrums, en documentació de distribucions i en tutorials de “tunejar” el sistema perquè voli… però poques vegades s'explica bé què fa de veritat, en quins escenaris aporta i en quins no notaràs absolutament res.
A més, tot això del balanceig d'IRQs s'enreda amb altres conceptes avançats: NAPI, cues de recepció del nucli, buffers de la NIC, algorismes de control de congestió TCP, RSS/RPS, BBR, ajustaments de sysctl, dimonis de rendiment com preload, swap comprimida amb zram, optimització de GTK, fitxers temporals en RAM, etc. És molt fàcil perdre's entre paràmetres, ordres i fitxers de configuració sense tenir clar què toca cada cosa.
Què és IRQbalance i per a què serveix realment a Linux
irqbalance és un dimoni d‟espai d‟usuari que s‟encarrega de repartir les interrupcions de maquinari (IRQs) entre els diferents nuclis de CPU en sistemes SMP (multiprocessador o multinucli). El seu objectiu no és màgic: simplement intenta que no tota la feina d'atendre dispositius (xarxa, discos, USB, etc.) caigui sempre sobre el mateix nucli.
Quan un dispositiu genera una IRQ, el nucli executa un controlador d'interrupció. Si moltes d'aquestes interrupcions es concentren en una sola CPU, aquesta CPU es pot saturar mentre les altres estan mig ocioses. irqbalance analitza el volum d'interrupcions per dispositiu i assigna cada IRQ a un nucli “adequat” per repartir càrrega, intentant alhora minimitzar pèrdues de memòria cau i respectar afinitats lògiques (per exemple, mantenir relacionades les IRQs d'una mateixa interfície de xarxa).
En sistemes amb una única CPU o nuclis que comparteixen completament la memòria cau L2, el mateix irqbalance detecta que no té res útil a fer i es tanca. No és un error: simplement no hi ha marge de millora. En canvi, en servidors amb diverses CPUs físiques o molts nuclis, sobretot amb trànsit de xarxa intens o E/S elevada, sí que pot marcar diferències en latència i estabilitat.
El dimoni es pot executar en segon pla (mode servei) o de manera puntual amb l'opció –oneshot. A més, permet excloure IRQs concretes mitjançant l'opció --banirq i evitar que utilitzeu certs nuclis amb la màscara de CPU definida a la variable d'entorn IRQBALANCE_BANNED_CPUS. Tot això es controla normalment des del seu fitxer de configuració, que en moltes distribucions es troba a /etc/default/irqbalance o /etc/irqbalance.env.
Balanceig d'IRQ: kernel vs irqbalance i quan es nota
Linux ja té el seu propi mecanisme intern per decidir a quina CPU s'atenen cada IRQ, sense necessitat d'irqbalance. El nucli pot fixar afinitats d'interrupció i distribuir-les seguint heurístiques simples, i en moltes màquines d'escriptori això és més que suficient: l'usuari mitjà no notarà cap diferència activant o desactivant irqbalance.
Per això és relativament habitual que algú provi irqbalance en el vostre distro d'escriptori i digui: “no noto cap millora, però tampoc res de dolent”. És perfectament normal. En un portàtil amb 4 nuclis i una sola targeta de xarxa sense una càrrega d'E/S seriosa, el scheduler de Linux i els mecanismes interns del nucli (NAPI, cues de xarxa, etc.) ja mantenen la cosa raonablement equilibrada.
On sí que cobra sentit és en servidors amb múltiples nuclis i trànsit intensiu: bases de dades grans, proxies inversos, servidors web d'alt trànsit, emmagatzematge de còpies de seguretat, màquines virtuals molt carregades, etc. Aquí, tenir moltes IRQ de xarxa o de disc clavades en un únic nucli es pot convertir en un coll d'ampolla. Distribuir-les bé redueix cues, temps de servei i pics de latència.
Alguns usuaris en lloc de fer servir irqbalance prefereixen parametritzar el nucli amb opcions com acpi_irq_balance al GRUB. Aquest paràmetre influeix en com ACPI i el nucli assignen les IRQs, però no ofereix la mateixa flexibilitat dinàmica que irqbalance, que reavalua el repartiment segons la càrrega real. Són enfocaments diferents: el primer és més estàtic i de baix nivell; el segon, més adaptatiu.
En entorns de latència ultrabaixa (per exemple, determinades plataformes de trading o xarxes amb DPDK), passa justament el contrari: irqbalance sol deshabilitar-se i les IRQ es fixen a mà a nuclis concrets, juntament amb mapeigs curosos entre cues de la NIC i CPUs. En aquests escenaris, es persegueix el control absolut i se sacrifica part de l'automatització.
Interrupcions, NAPI i cues de xarxa: com encaixa IRQbalance
Per entendre millor el paper d'irqbalance cal baixar una capa més i mirar com maneja Linux les interrupcions de xarxa i la recepció de paquets. El subsistema de xarxa del nucli combina diverses peces clau: NAPI, cues de recepció (DMA buffer), paràmetres de net.core.*, algorismes de gestió de cues (qdisc) i escalat lateral (RSS/RPS).
NAPI (New API) és el mecanisme mitjançant el qual el nucli redueix la tempesta d'interrupcions quan arriba molt de trànsit. En lloc de disparar una IRQ per cada paquet, la NIC genera una interrupció que indica “hi ha feina pendent”, i el nucli sondeja la cua de recepció fins a buidar-la o esgotar un pressupost de temps/paquets. Això redueix jitter i millora el rendiment, encara que també podeu introduir alguna variació de latència.
La cua on aterren els paquets abans de ser processats per la pila de xarxa és el que se sol anomenar cua de recepció del nucli o DMA Buffer. La seva capacitat ve delimitada per paràmetres com:
net.core.netdev_max_backlog: màxim de paquets a la cua de recepció programari quan el nucli no pot processar-los al ritme que arriben.net.core.netdev_budget_usecs: “pressupost” de temps en microsegons que té NAPI per buidar cues a cada cicle.net.core.dev_weight: nombre de paquets que es processen per interfície a cada ronda dins d'aquest pressupost.
Si netdev_max_backlog és molt baix i la NIC fica més paquets dels que el nucli pot assumir, començarem a veure “dropped packets” a /proc/net/softnet_stat. Un valor típic per començar a afinar a servidors de gran trànsit és de l'ordre de 4000 paquets, configurat a /etc/sysctl.conf amb alguna mena:
net.core.netdev_max_backlog = 4000
Després de modificar-lo, s'aplica amb sysctl -p o amb un sysctl -w puntual. D'aquesta manera, la cua absorbeix millor pics d'arribada sense perdre paquets, sempre que la resta de la ruta de processament aguanti.
En tot aquest circuit, irqbalance decideix a quina CPU s'atenen les IRQ associades a la interfície de xarxa. Si concentrem totes les interrupcions de la NIC en un únic nucli, aquest nucli correrà les rutines NAPI i drenarà la cua en solitari. Si repartim bé les IRQ i fem servir mecanismes com RSS o RPS, diverses CPUs poden col·laborar a processar paquets, cosa que redueix cues i pèrdues.
Afinar cues, buffers i finestra TCP per a trànsit intensiu
Quan un servidor mou moltes dades (per exemple, còpies de seguretat, trànsit FTP, fitxers grans o bases de dades replicant), no n'hi ha prou amb “tenir irqbalance activat”. Cal harmonitzar diversos nivells: cues de kernel, buffers de targeta, mides de finestra TCP i paràmetres de congestió, de manera que tots remen en la mateixa direcció.
El primer bloc d'ajust és al buffer de recepció de paquets i finestra TCP. Linux exposa paràmetres com:
net.ipv4.tcp_rmem: tripleta (mínim, per defecte, màxim) de memòria de recepció TCP per socket.net.ipv4.tcp_wmem: equivalent per a enviament.net.core.rmem_maxynet.core.wmem_max: màxims durs de buffer que pot demanar una aplicació.
Una forma pràctica d'ajustar-los per a un enllaç Gigabit de baixa latència és calcular el BDP (Bandwidth-Delay Product) i aplicar un factor d'escala (gràcies a l'opció de TCP window scaling, activada per defecte a la majoria de kernels moderns). A la pràctica, molts administradors acaben amb valors de màxim de diversos megabytes, per exemple:
net.ipv4.tcp_rmem = 4096 16384 10880000
net.ipv4.tcp_wmem = 4096 16384 10880000
Aquest màxim de ~ 10,8 MB ve de càlculs concrets per a enllaços d'1 Gbps amb RTT molt baix (~0,00017 s). Com més gran és el cabal o la latència, més gran ha de ser el buffer per aprofitar l'amplada de banda sense quedar limitat per la finestra.
És important relacionar aquest màxim amb la mida de la cua de recepció de paquets. Si netdev_max_backlog = 4000 i cada paquet efectiu ronda 1480 bytes, aquesta cua representa uns ~5,9 MB. El buffer de finestra TCP ha de ser més gran que el que cap a la cua, o perdrem paquets per saturar abans el buffer que la cua.
Per vigilar si hi ha pèrdues, es poden usar ordres com:
cat /sys/class/net/eth0/statistics/rx_dropped: paquets perduts a la NIC.watch -n 1 -t -d cat /proc/net/softnet_stat: columnes processats, caiguts, temps espremut, etc. per CPU.watch -n 1 -t -d "netstat -s | grep err": errors a la pila de xarxa.
Si netstat indica errors però /proc/net/softnet_stat no, el més probable és que les pèrdues estiguin fora del nostre host (en el camí, tallafocs intermedi, etc.). Sempre hi haurà una mica de pèrdua a causa dels algorismes de control de congestió, però ha de romandre sota control i correlacionar-se amb els pics de trànsit.
Gestió de cues (qdisc), QoS i control de congestió TCP
Tot i que les cues internes del nucli són crítiques, també ho és la disciplina de cues (qdisc) associada a les interfícies de xarxa. És el que determina com s'ordenen, agrupen i descarten els paquets a la sortida, i pot marcar diferències davant de fenòmens com el bufferbloat.
Linux ofereix diverses qdisc rellevants:
- pfifo_fast: antiga disciplina per defecte, un FIFO amb tres bandes de prioritat.
- fq_code: combinació de fair queuing amb CoDel per combatre el bufferbloat, molt recomanable per a routers i ús general.
- fq: fair queuing senzill, molt útil a servidors d'alta càrrega.
- cake (sch_cake): la més avançada avui dia, però requereix compilar o disposar del mòdul al nucli.
El qdisc per defecte es veu amb:
sysctl net.core.default_qdisc
I es pot canviar en calent amb:
sysctl -w net.core.default_qdisc=fq_codel
Per assegurar que una interfície concreta utilitza una disciplina determinada, es recorre a tc:
sudo tc qdisc replace dev eth0 root fq_code
Lligat a això, el algorisme de control de congestió TCP marca també diferències en entorns WAN o amb trànsit massiu. El kernel ofereix diversos (cúbic, ren, etc.), i en versions modernes s'hi inclou Extensió BB desenvolupat per Google, que sol millorar els cabals sostinguts sense disparar la latència. S'activa amb:
sudo sysctl -w net.ipv4.tcp_congestion_control=bbr
El llistat d'algoritmes disponibles es pot inspeccionar veient els mòduls tcp_* en /lib/modules/<versión>/kernel/net/ipv4/. Combinar BBR amb un qdisc adequat (fq/fq_codel) i una bona configuració de buffers dóna com a resultat fluxos de dades molt més estables.
Ajustaments avançats de la NIC: ring buffers, RSS, RPS i offloads
La targeta de xarxa en si també té el seu propi joc de cues i buffers: els ring buffers de recepció (RX) i transmissió (TX). La seva mida màxima depèn del maquinari i es visualitza amb:
ethtool -g ethX
els camps “Pre-set maximums” indiquen quant es pot augmentar. Si la targeta permet, es poden pujar RX i TX a valors tipus 4096, 8192 o 16384 amb:
ethtool -G ethX rx 4096 tx 4096
Si apareix un error tipus “Cannot set device ring parameters: Invalid argument”, aquest valor supera les capacitats de la NIC i caldrà provar divisors menors.
Per a evitar que una sola CPU es mengi tota la feina de recepció, moltes NIC modernes implementen RSS (Receive Side Scaling), creant diverses cues maquinari associades a diferents nuclis. A Linux, aquesta distribució es veu amb:
cat /proc/interrupts | grep
En targetes sense RSS es pot “emular” una cosa semblant amb RPS (Receive Packet Steering), assignant CPUs a les cues programari de la interfície:
fet f > /sys/class/net/enp4s0f0/queues/rx-0/rps_cpus
El valor és una màscara hexadecimal. Per exemple, f en binari (1111) indica utilitzar els quatre primers nuclis. Cal que el nucli estigui compilat amb CONFIG_RPS perquè funcioni.
També es pot jugar amb offloads de checksum i segmentació per descarregar treball de la CPU al processador de la NIC. Amb ethtool -k es veuen les capacitats activades, i es poden encendre coses com:
ethtool -K ethX rx on (verificació de checksum a recepció)
ethtool -K ethX tso on (TCP segmentation offload)
Perquè aquests canvis siguin persistents, se solen col·locar en scripts de xarxa (/etc/network/interfaces a Debian/Ubuntu, /etc/sysconfig/network-scripts/ifcfg-ethX a Red Hat) o en regles d'udev.
Afinar l´afinitat d´IRQ a mà i conviure amb IRQbalance
En nuclis antics o en casos on volem control fi, es pot assignar manualment quina CPU atén una IRQ concreta. Tota la informació és a /proc/irq y /proc/interrupts. Un flux típic seria:
- Veure interrupcions: cat / proc / interrupts i localitzar la línia de la interfície de xarxa (ex. IRQ 25 per a enp0s8).
- Comprovar afinitat actual: cat /proc/irq/25/smp_affinity (màscara hex: 02 = CPU1, 01 = CPU0, 04 = CPU2, etc.).
- Canvia-la: fet 1 > /proc/irq/25/smp_affinity per moure-la a la CPU0.
D'aquesta manera podeu, per exemple, descarregar a una CPU saturada movent una IRQ a un altre nucli menys ocupat. Si tens irqbalance instal·lat i actiu, és important dir-li que no toqui aquesta interrupció concreta, afegint una opció com:
OPTIONS=»–banirq=25″
en /etc/default/irqbalance, o bé usant l'opció --banirq=25 en arrencar el dimoni. Així el deixes fora de la seva lògica de repartiment automàtic i respectes la teva assignació manual.
Perquè canvis com echo 1 > /proc/irq/25/smp_affinity sobrevisquin als reinicis, se solen afegir al clàssic /etc/rc.local (si està habilitat) oa unitats de systemd específiques.
Altres ajustaments de rendiment relacionats: swap, zram, fitxers temporals, preload
Tot aquest treball de millorar la resposta de xarxa i el repartiment d'IRQ sol venir acompanyat de altres afinats de sistema que, encara que no estan directament lligats a irqbalance, completen el quadre de rendiment.
En l'àmbit de memòria, molts administradors redueixen el ús agressiu de swap modificant /etc/sysctl.conf amb paràmetres com:
- vm.canvi: quant prefereix el nucli utilitzar swap (0-100, per defecte 60). Valors baixos (1-10) prioritzen RAM.
- vm.vfs_cache_pressure: pressió sobre la memòria cau d'inodes i dentries. Reduir-ho ajuda a mantenir metadades a RAM.
- vm.dirty_writeback_centisecs y vm.dirty_expire_centisecs: freqüència i venciment d'escriptura de pàgines brutes al disc.
- vm.dirty_ratio y vm.dirty_background_ratio: percentatge de memòria que es pot omplir de dades brutes abans de forçar escriptures.
Amb valors adequats (per exemple vm.swappiness = 1, vm.vfs_cache_pressure=50, etc.) s'aconsegueix que el sistema espremi més la RAM abans de començar a paginar, una cosa desitjable en servidors amb molta memòria.
Una altra mesura clàssica és moure directoris temporals a RAM muntant-los com tmpfs en /etc/fstab:
tmpfs /tmp tmpfs noatime,nodiratime,nodev,nosuid,mode=1777,defaults 0 0
tmpfs /var/tmp tmpfs noatime,nodiratime,nodev,nosuid,mode=1777,defaults 0 0
Amb això, els accessos temporals (compilacions, fitxers de treball d'aplicacions, etc.) es fan a velocitat de RAM i es redueix el desgast a discos SSD.
També és habitual en entorns de pocs recursos activar zram-swap: un dispositiu d'intercanvi comprimit a RAM. S'instal·la des d'un dipòsit (per exemple amb Git clonant zram-swap i executant la seva install.sh) i crea un dispositiu de blocs comprimit on el sistema intercanvia abans de recórrer, si n'hi ha, a la swap en disc. Es guanya memòria efectiva a costa d´una mica més de CPU, el que en moltes càrregues compensa.
Finalment, dimonis com precàrrega analitzen quines aplicacions s'executen més sovint i precarreguen els seus binaris i llibreries a RAM, accelerant les seves arrencades a costa de consumir memòria. Té sentit en escriptoris amb força RAM; en servidors molt ajustats se'n sol prescindir.
GTK, GRUB, Firefox i altres ajustaments de “qualitat de vida”
Més enllà del rendiment pur de servidor, molts tutorials inclouen seccions llarguíssimes sobre optimitzar lexperiència descriptori: temps de resposta de menús GTK, fonts, temes foscos, so, comportament del ratolí, etc. Encara que no afecten directament irqbalance ni el trànsit de xarxa, sí que contribueixen a fer que el sistema se senti més àgil.
A GTK2, GTK3 i GTK4 es poden ajustar desenes de paràmetres en arxius com ~/.gtkrc-2.0, ~/.config/gtk-3.0/settings.ini o ~/.config/gtk-4.0/settings.ini: animacions, temps de doble clic, mida de cursors, disseny de la barra de títol, ús de temes foscos, comportament de tooltips, antialiasing de fonts, etc. Aquests fitxers s'editen a mà (amb nano) o afegint línies via echo >> des de terminal.
També se solen ajustar les versions “globals” d'aquests paràmetres a /etc/gtk-2.0/gtkrc, /etc/gtk-3.0/settings.ini y /etc/gtk-4.0/settings.ini, perquè afectin tots els usuaris, sempre respectant que en aquests casos cal ser root (via su - o sudo).
El temps d'espera del gestor de arrencada GRUB s'escurça editant /etc/default/grub i modificant GRUB_TIMEOUT (per exemple, de 10 a 3 segons), i afegint paràmetres al nucli com noresume o acpi_irq_balance en GRUB_CMDLINE_LINUX_DEFAULT. Després s'executa update-grub (Debian/Ubuntu) o grub-mkconfig -o /boot/grub/grub.cfg (Arch i derivades).
En el cas del navegador, hi ha fitxers com user.js Firefox que permeten aplicar lots de preferències orientats a accelerar la navegació: nombre de connexions, comportament de memòria cau, compressió, websockets, etc. El procediment habitual és restablir el perfil, obrir el directori del perfil des de “Informació per solucionar problemes”, tancar Firefox, enganxar user.js a la carpeta del perfil i tornar a obrir el navegador.
Tot i que tot això és paral·lel al tema d'irqbalance, il·lustra una idea important: l'optimització de Linux és un procés holístic. No es tracta només d'un dimoni o paràmetre màgic, sinó d'anar ajustant CPU, memòria, disc, xarxa, escriptori i aplicacions fins que encaixi amb l'ús real de la màquina.
Mirant tot el conjunt -repartiment d'IRQs amb irqbalance oa mà, NAPI i cues ajustades, buffers TCP dimensionats, qdisc moderns com fq_codel o fq, control de congestió BBR, ring buffers ampliats, RSS/RPS activats, swap i zram sota control, temporals en RAM i irqbalance és només una peça més d'un puzle força gran. El seu paper és vital en servidors de múltiples nuclis i trànsit intens, irrellevant a molts escriptoris i contraproduent en sistemes de latència extrema on es prefereix fixar afinitats a mà; entendre bé aquest context és la clau per decidir si convé deixar-lo actuar, limitar-lo o directament desactivar-lo.
Redactor apassionat del món dels bytes i la tecnologia en general. M'encanta compartir els meus coneixements a través de l'escriptura, i això és el que faré en aquest bloc, mostrar tot el més interessant sobre gadgets, programari, maquinari, tendències tecnològiques, i més. El meu objectiu és ajudar-te a navegar pel món digital de forma senzilla i entretinguda.