Arquitectura Backend y Diseño de Colas de LibreQoS
Esta página explica cómo se integran los sistemas backend de LibreQoS en tiempo de ejecución:
Tratamiento de paquetes en el plano de datos (
XDP/eBPF->tc-> árbol de colas)Diseño de jerarquía de colas (
mq+HTB+ qdiscs hoja)Comportamiento de AQM (
fq_codel,CAKE) y por qué puede haber beneficios por debajo de la tasa máximaActualizaciones del plano de control (Scheduler,
lqosd, Bakery, incremental vs recarga completa)Límites de diseño prácticos para operadores
Para un análisis profundo de colas, consulte HTB + fq_codel + CAKE: Comportamiento Detallado de Colas.
Contexto de Fuente
Esta página incorpora detalles de publicaciones públicas del devblog:
1) Modelo Mental del Backend
LibreQoS tiene dos planos que cooperan:
Plano de datos:
clasificar paquetes rápidamente
mapear paquetes a clases de cola
aplicar comportamiento de equidad y latencia a velocidad de línea
Plano de control:
calcular el estado deseado desde
network.jsonyShapedDevices.csvaplicar el conjunto más pequeño de cambios de cola que sea seguro
evitar recargas innecesarias
En términos operativos:
XDP/eBPFy mapas de lookup determinan identidad de paquete y ruta de CPU.Linux Traffic Control (
tc) aplica la política de colas.Bakery gestiona deltas de actualización y límites de recarga.
2) Invariantes de Ejecución
Estos invariantes ayudan a evaluar si el comportamiento backend es saludable.
Invariante |
Por qué importa |
Síntoma cuando se rompe |
Primera verificación |
|---|---|---|---|
Cada circuito moldeado mapea a un padre válido en la jerarquía |
Sin padre no hay ubicación efectiva de cola |
Suscriptores sin shaping o fuera de límites esperados |
Validar relaciones de padre en |
Los supuestos de raíz multi-cola coinciden con NIC/entorno real |
La distribución en CPU depende del modelo de colas |
Un núcleo saturado y otros ociosos, shaping inestable bajo carga |
Verificar modelo de colas de NIC y layout |
El mapeo del plano de datos es estable entre XDP y |
Mapeo erróneo causa asignación de cola incorrecta |
Contadores de clase inesperados, tráfico mal contabilizado |
Comparar class IDs esperados vs contadores |
Cambios del plano de control quedan dentro de límites incrementales seguros |
Reduce disrupción por reconstrucciones completas |
Ventanas frecuentes de recarga con impacto en paquetes |
Revisar patrón de cambios: estructurales vs velocidad/mapeo |
El número de colas cabe en presupuesto de CPU/RAM |
Escala de qdisc hoja impacta recursos directamente |
Crecimiento de memoria, recargas lentas, jitter bajo churn |
Monitorear cantidad de colas, margen de RAM y cadencia de cambios |
3) Ruta End-to-End de Paquetes y Control
4) Diseño del Plano de Datos
4.1 Pipeline XDP y clasificación
LibreQoS realiza trabajo temprano de paquetes en XDP cuando es posible:
Parsear encabezados una sola vez.
Resolver identidad (ruta flujo/cache/LPM).
Adjuntar metadata de mapeo para etapas posteriores.
Una dirección clave de optimización es reducir lookups repetidos:
usar hits de hot-cache para direcciones/flujos activos
usar LPM como fallback cuando corresponde
evitar trabajo duplicado entre XDP y
tccuando la metadata puede pasarse hacia adelante
4.2 Por qué cpumap es central
cpumap se usa para distribuir trabajo entre núcleos y evitar que shaping se quede limitado a una sola ruta de cola. Esto es parte clave para escalar de «funciona» a «funciona a nivel ISP».
4.3 Cache, generaciones y reducción de presión por locks
La progresión general descrita en notas de desarrollo/devblogs:
reducir wipes completos de mapas
mover manejo de estado obsoleto hacia modelo por generación/epoch
reducir mantenimiento con locks pesados en hot paths
Operativamente, esto ayuda a estabilizar latencia y CPU bajo actualizaciones frecuentes.
5) Jerarquía de Colas: mq -> HTB -> qdisc hoja
El modelo de colas de LibreQoS es intencionalmente por capas:
raíz
mqpara distribución multi-colaHTBpara envolventes jerárquicas de tasaqdisc hoja (
CAKEofq_codel) para equidad/AQM dentro de esas envolventes
5.1 Internals de HTB que importan en producción
Mecánicas importantes:
Tokens: cada paquete consume tokens según su tamaño.
Refill timing: el refill de tokens sigue el timing del kernel (
jiffies).quantum: bytes servidos antes de que el scheduler rote foco de clase.r2q: influye en los valores derivados de quantum y su comportamiento.
Por qué importa para operadores:
valores muy pequeños o muy grandes de quantum pueden afectar la suavidad de equidad
relaciones padre/hijo en shaping importan más que «recetas» aisladas de una sola clase
HTB es la envolvente de tasa; los qdiscs hoja no reemplazan la política HTB
6) AQM en LibreQoS: fq_codel y CAKE
6.1 División de responsabilidades
División práctica:
HTB: política jerárquica de ancho de banda y límites
fq_codel/CAKE: equidad de cola y control de delay dentro de esa política
6.2 Por qué AQM sigue ayudando incluso por debajo de la saturación de la tasa de línea
Incluso cuando un enlace no está saturado, fq_codel y CAKE siguen afectando el comportamiento de los paquetes. La lógica de drop (CoDel/BLUE/COBALT) suele permanecer inactiva, pero el scheduler de fair-queueing sigue intercalando flujos, evitando que las ráfagas de un flujo monopolicen el punto de serialización del enlace. Esto mantiene responsivo el tráfico sensible a la latencia.
Veamos cómo funciona esto:
Un paquete se encola para ser enviado (desde cualquier origen). Entra en TC y se empareja con el qdisc de SQM.
Se genera una clave de flujo (y se determina el tin si se usa CAKE con diffserv). Se registra el tiempo de encolado para saber cuánto tiempo ha estado esperando el paquete.
Con fq_codel y con CAKE, el paquete queda ahora en una cola específica de ese flujo (qué tan específica depende de la configuración y del hashing).
Ahora ocurre el dequeue: la interfaz indica que puede aceptar más paquetes. Cuando el enlace no está saturado, esto tiende a suceder rápidamente.
Luego, fq_codel y CAKE programan paquetes entre flujos (conceptualmente round-robin usando deficit scheduling; CAKE además aplica prioridad por tin).
En el momento del dequeue se evalúa el tiempo de permanencia en cola (sojourn time). En condiciones de congestión esto puede activar la lógica de drop de CoDel o de BLUE/COBALT. Sin embargo, cuando el enlace no está saturado, esos mecanismos rara vez están activos.
Sin embargo, el queueing por flujo sigue importando.
Los paquetes se extraen de múltiples colas de flujo en un orden justo antes de llegar a la cola del dispositivo. En la capa física, el enlace finalmente serializa el tráfico un bit a la vez, por lo que el orden en que los paquetes llegan a ese punto de serialización sigue afectando el comportamiento de la latencia.
Incluso sin congestión sostenida:
La capacidad de respuesta de los flujos bien comportados se mantiene estable. Es menos probable que paquetes cortos de control (DNS, SSH, ACKs de TCP, etc.) queden atrapados detrás de ráfagas de otro flujo.
La naturaleza de las ráfagas se reduce antes de que los paquetes lleguen al punto de serialización. En lugar de que un flujo descargue una gran ráfaga, el scheduler intercala los flujos.
Así que, incluso cuando la lógica de drop de AQM está mayormente inactiva, la parte de fair-queueing de SQM sigue haciendo trabajo útil al controlar cómo los paquetes llegan al medio físico.
6.3 CAKE vs fq_codel en términos de LibreQoS
Patrón general:
Preferir CAKE cuando la prioridad es suavidad con tráfico mixto y buen comportamiento por defecto.
Preferir fq_codel cuando domina la presión por cantidad de colas/recursos y la QoE observada sigue siendo aceptable.
Revalidar tras cambios grandes de topología o cantidad de colas.
Realidad de recursos:
ambos son flow-aware y mantienen estado
CAKE puede tener mayor huella de memoria/CPU con poblaciones grandes de colas
6.4 Cuándo los beneficios bajo la tasa máxima pueden ser menores
Menor latencia bajo carga mixta es común, pero no está garantizada en todos los escenarios.
Se esperan ganancias menores cuando:
el cuello de botella está fuera de la ruta de cola controlada
el tráfico es escaso y casi no hay contención real
se aplica shaping en una sola dirección y el problema principal está en la dirección opuesta
límites de hardware fuerzan un diseño de colas con poca aislación en picos
Conclusión operativa:
Tratar las ganancias de AQM como resultado de dinámica de colas y control de contención, y validar empíricamente con tráfico real.
7) Bakery y Comportamiento de Recarga
Bakery existe para evitar reconstrucciones innecesarias de colas y reducir penalidades de recarga.
Flujo general:
Construir estado deseado.
Hacer diff entre estado deseado y activo.
Aplicar el delta más pequeño y seguro.
Disparar recarga completa solo cuando el tipo de cambio cruza límites de mutación en vivo.
7.1 Colas perezosas y expiración
Controles clave:
lazy_queues: diferir creación de partes de la jerarquía hasta uso real.lazy_expire_seconds: remover estado de cola inactivo tras timeout.
Efecto práctico:
menor consumo de memoria para endpoints inactivos
menos churn para poblaciones grandes de suscriptores parcialmente activos
7.2 Límite entre incremental y recarga completa
Tipo de cambio |
Normalmente incremental seguro |
Suele requerir recarga completa |
Por qué |
|---|---|---|---|
Cambio solo de IP de circuito |
Sí |
No |
Actualización de mapeo puede aplicarse sin reconstruir árbol |
Cambio de velocidad de circuito/sitio (subconjunto) |
Sí |
A veces |
Depende del impacto estructural y class handles disponibles |
Virtualización runtime de nodos TreeGuard (subárbol soportado / ruta de rebalanceo top-level) |
Sí |
No |
Bakery ahora la aplica como un plan runtime vivo: nodos no top-level usan reparent/prune/restore, y nodos top-level soportados usan una ruta de rebalanceo y migración entre colas |
Cambios masivos en todos los circuitos |
A veces |
Frecuente |
Límites de escala y cardinalidad de transacciones |
Re-parent/reestructura topológica |
Rara vez |
Sí |
Restricciones de mutación de subárbol HTB |
Alta/baja de circuitos |
Sí (pequeño/mediano) |
A veces |
Límites de handles y fronteras de corrección en el diff |
Esta tabla refleja comportamiento de diseño de Bakery y restricciones de mutación de Linux tc discutidas en el devblog.
7.3 Reglas rápidas para límites de recarga
Preferir deltas pequeños y frecuentes de mapeo/velocidad sobre churn estructural grande.
Agrupar cirugía topológica en ventanas planificadas.
Esperar mayor riesgo cuando coinciden muchos circuitos y muchos cambios estructurales.
Diseñar la cadencia operativa para priorizar cambios incrementalmente seguros.
7.4 Salvaguardas de seguridad para recargas completas
Las recargas completas actuales de Bakery aplican verificaciones conservadoras de seguridad antes y durante reconstrucciones grandes de colas:
Un preflight de qdisc estima los qdisc planificados por interfaz y además separa qdisc de infraestructura, hojas
cakey hojasfq_codel.Ese mismo preflight aplica una proyección conservadora de memoria y bloquea de forma estricta las recargas completas claramente inseguras antes de arrancar
tc -batch.El piso de memoria de Bakery escala con la RAM del host: mantiene al menos 2 GiB disponibles, o un octavo de la RAM total en sistemas más grandes.
Durante la aplicación por fragmentos de una recarga completa, Bakery vuelve a revisar la memoria del host en los límites de cada fragmento y aborta el resto de la aplicación si la memoria disponible cae por debajo del piso escalado más la memoria qdisc proyectada para el lote.
Estas salvaguardas están sesgadas intencionalmente hacia falsos positivos en recargas grandes para fallar temprano con diagnósticos en lugar de entrar en una espiral OOM.
8) Límites de Diseño para Operadores
8.1 Límites de observabilidad
Señal |
Fuerte para |
Débil para |
|---|---|---|
Contadores de colas y métricas de shaping |
Diagnóstico de tendencias, congestión y validación de política |
Causalidad exacta paquete-por-paquete |
Drops/marks de CAKE/fq_codel |
Detectar presión persistente de cola y efectos de política |
Asignar culpa end-to-end a nivel aplicación |
CPU/RAM y tiempos de comando |
Planificación de capacidad y riesgo de recarga |
Aislar origen exacto de cada microburst |
8.2 Factores de riesgo de capacidad y mitigaciones
Factor de riesgo |
Síntoma típico |
Mitigación |
|---|---|---|
Cantidad muy alta de colas con CAKE en todas |
Crecimiento de RAM y overhead del scheduler |
Usar |
Actualizaciones frecuentes de árbol completo |
Ventanas breves de disrupción de paquetes |
Aumentar uso de cambios incrementalmente seguros; agrupar cambios estructurales |
Mapeo de padre incompleto en jerarquía |
Suscriptores sin shaping esperado |
Validar relaciones de padre en |
Virtualización/NIC con colas débiles o una sola cola |
Mala distribución y shaping inestable |
Asegurar ruta multi-cola y verificar supuestos de mapeo |
9) Matriz de Troubleshooting: Síntoma a Causa
Síntoma |
Causa backend común |
Primeras verificaciones |
Dirección correctiva típica |
|---|---|---|---|
Picos de latencia sin throughput totalmente al límite |
Microbursts, aislación de flujo insuficiente, o mismatch direccional |
Comparar latencia vs tendencias de cola/drop; verificar shaping en ambas direcciones |
Ajustar estrategia de qdisc hoja y diseño direccional |
Un CPU muy caliente y otros subutilizados |
Desbalance de steering o ruta multi-cola débil |
Revisar uso de CPU y contadores por rama de cola |
Corregir supuestos de mapeo y verificar estructura |
Suscriptores aparecen sin shaping intermitentemente |
Mismatch en mapeo padre/jerarquía |
Validar referencias de nodo padre y creación de clases |
Corregir jerarquía, aplicar y verificar presencia de clases |
Disrupciones cortas frecuentes durante cambios |
Demasiados cambios que disparan recarga completa |
Clasificar cambios recientes: estructural vs incremental |
Reagrupar operaciones hacia deltas incrementales seguros |
Crecimiento de RAM al escalar |
Demasiados qdisc hoja activos o huella CAKE agresiva |
Medir cantidad de colas y tendencia de memoria en ventanas de cambio |
Usar colas perezosas/expiración y considerar fq_codel selectivo |
Dashboard muestra más tráfico del esperado |
Alcance del contador difiere de tráfico final post-drop |
Comparar métricas de dashboard con contexto |
Ajustar runbooks a semántica de métricas |
10) Flujo de Validación de Cambios
Usa este flujo ligero para cambios con impacto backend.
10.1 Antes del cambio
Clasificar tipo de cambio: mapeo/velocidad/estructura.
Estimar alcance: cantidad de circuitos/clases afectados.
Capturar línea base:
tendencia de latencia
comportamiento de drop/mark
margen de CPU y RAM
snapshot de clases/qdiscs
tc
10.2 Durante el cambio
Vigilar comportamiento del plano de control:
ocurrencia de aplicación incremental vs recarga completa
warnings/errores de comandos y runtime
Vigilar señales del plano de datos:
anomalías de crecimiento de cola
deriva de latencia por dirección
discontinuidades de contadores por clase
10.3 Después del cambio
Revalidar las mismas señales de la línea base.
Confirmar presencia de jerarquía/clases en circuitos modificados.
Verificar expectativas de latencia y throughput del suscriptor.
Si hay degradación, revertir o reducir alcance y reaplicar en lotes más pequeños.
10.4 Checklist mínimo de comandos
Ajusta nombres de interfaz a tu entorno.
tc -s qdisc show dev <ifname>
tc -s class show dev <ifname>
journalctl -u lqosd --since "15 min ago"
11) Secuencia Práctica de Ajuste
Orden recomendado:
Validar primero jerarquía topológica y mapeos de padre.
Confirmar cantidad de colas y margen de memoria.
Validar comportamiento de distribución
mq/multi-core.Elegir CAKE vs fq_codel según QoE observada y presupuesto de recursos.
Ajustar cadencia de cambios para favorecer deltas incrementalmente seguros.
Revalidar tras cambios grandes de plan de velocidad, topología o cadencia de integración.
12) Glosario
XDP: hook de paquetes de alto rendimiento más temprano en Linux.eBPF: procesamiento programable en kernel.LPM: lookup de prefijo más largo para mapeo de identidad.cpumap: mapa XDP para dirigir procesamiento a CPUs.tc: subsistema Linux Traffic Control.qdisc: objeto de disciplina de cola entc.mq: estructura raíz multi-cola.HTB: scheduler/shaper Hierarchical Token Bucket.fq_codel: fair queueing + control de delay CoDel.CAKE: qdisc integrado de shaping/equidad/AQM.Bakery: subsistema LibreQoS de diff de estado y actualización incremental.epoch/generation: enfoque de envejecimiento de estado para evitar limpiezas globales con locks pesados.