Ir al contenido

Valores derivados

La etapa de derivación del colector calcula valores junto a las muestras en bruto. De cada uno: sus entradas, cuándo se omite en vez de escribirse y dónde lo pone cada destino. Los eventos discretos que provoca la misma etapa están en Reglas de detección.

La etapa de derivación existe para las derivaciones que necesitan estado entre muestras, que unen la capa del kernel con la capa de la API, o que deben calcularse una sola vez para que cada destino que las lleva lleve los mismos números (qué destinos tienen sitio para ellas está en la tabla de abajo) — nada de lo cual hace una consulta de un panel, y nada de lo cual debería pagar el agente. El agente envía deltas de ticks en bruto y nunca divide; el colector puede hacerlo. Nada de esta etapa se ejecuta en el router.

La rigen dos reglas:

  • Un valor derivado se escribe junto a sus entradas, nunca en su lugar, para que el almacén pueda recalcularlo si más adelante se descubre que la derivación estaba mal.
  • Una detección es un evento discreto en la línea temporal, un «mira aquí» — nunca una serie continua y nunca un veredicto.

La propia escalera de escalada del asignador como un único ordinal. Cada entrada ya se envía y se dibuja por separado; lo que añade el ordinal es que la escalera está ordenada, así que una sola serie dice hasta dónde llegó. Gana el peldaño más alto alcanzado en los deltas de /proc/vmstat de la muestra:

Valor Peldaño A partir de los deltas de /proc/vmstat de la muestra
0 ninguno nada de lo de abajo
1 kswapd escaneó pgscan_kswapd > 0
2 reclaim directo: un hilo escaneó por sí mismo pgscan_direct > 0
3 una asignación se bloqueó o se sacó una página a swap allocstall > 0 o pswpout > 0
4 actuó el OOM killer oom_kill > 0

cycles_per_packet, instructions_per_packet y cache_misses_per_packet: cuentas de PMU sumadas sobre los núcleos, divididas entre los paquetes que softnet procesó en la muestra, sumados sobre los núcleos: el coste de reenvío del router en la única unidad que permite comparar dos configuraciones. Un cambio de reglas que reduce a la mitad los ciclos por paquete es una mejora real; uno que reduce a la mitad el tiempo ocupado mientras el tráfico también se reducía a la mitad no lo es. Todavía no consta ninguna comparación así entre dos configuraciones (no probado).

Ausentes sin PMU, en una muestra sin paquetes, y en una muestra con un reinicio de contador (suspect), donde un delta es una cota inferior y no una medida.

Paquetes procesados por interrupción de dispositivo — todas las filas de /proc/interrupts salvo el temporizador y las interrupciones entre procesadores — que es la profundidad de agrupamiento de NAPI. La cuenta de dispositivo es el total de interrupciones de la muestra menos las filas del temporizador y las filas IPI presentes en su top-K.

Ausente en una muestra sin paquetes o con un reinicio de contador (suspect), y cuando la fila del temporizador no está en el top-K de la muestra, porque entonces la cuenta de dispositivo no se puede separar del total.

Un paquete descartado, o más squeezes de softnet de los que esa CPU suele tener — por encima de su percentil 90 móvil y al menos 3 — en una muestra cuya cuenta de paquetes estaba en su mediana móvil o por debajo. Es la prueba del propio kernel de una ráfaga más corta que el intervalo de muestreo, que es la única forma en que esta herramienta puede ver dentro de uno. La marca es verdadera cuando cualquier CPU cumple la condición.

Las referencias móviles abarcan diez segundos de reloj de pared a cualquier cadencia: 100 muestras a 10 Hz, 500 a 50 Hz, 1 000 a 100 Hz, acotadas entre 10 y 2 000 muestras. No se marca ninguna muestra hasta que su CPU tiene al menos diez muestras de historia.

Por qué un percentil y no «cualquier squeeze»: los squeezes pueden ser el fondo de un router. En el router medido, alrededor del 11,2 % de las muestras por CPU llevan un squeeze y el 1,2 % exactamente dos, así que «cualquier squeeze» marcaría la normalidad del equipo varias veces por minuto. La referencia es la del propio equipo: en otra placa o con otra mezcla de tráfico su percentil será el de ese equipo, y no se ha medido si diez segundos son el intervalo adecuado allí (Probado en).

Tres muestras marcadas en una CPU en 60 s es lo que provoca la detección microburst; una muestra marcada se queda en un dato.

Verdadero cuando el agente informó de un reinicio de contador en la muestra: un contador que retrocedió sin un desbordamiento de 32 bits. La fila en bruto se conserva; los valores por paquete de arriba — los tres cocientes de la PMU y packets_per_irq — se omiten.

En cada ronda de la API que trajo los contadores por puerto, el colector calcula, sobre los deltas desde la lectura anterior, la proporción del fast path del tráfico que cada interfaz entrega a la CPU: de los bytes que llegaron a la CPU en esa interfaz, la parte que RouterOS contó por el fast path y no por el camino lento. El denominador no es el mismo contador en todas las interfaces, porque RouterOS no cuenta lo mismo en todos los tipos — gana el primer contador presente en las dos lecturas:

Interfaz fp_rx_share es Por qué ese denominador
un puerto del switch (ether…, sfp-sfpplus1) Δfp-rx-byte / Δdriver-rx-byte su rx-byte es el total del cable, incluidas las tramas que el chip del switch reenvió por hardware; driver-rx-byte es lo que llegó a la CPU
una interfaz software (bridge, VLAN, PPPoE) Δfp-rx-byte / Δrx-byte (o rx-bytes) no tiene contadores del driver, y su rx-byte ya es lo que la CPU envió y recibió

fp_tx_share es el mismo cociente en el otro sentido — Δfp-tx-byte entre Δdriver-tx-byte, Δtx-byte o Δtx-bytes — y se omite mientras fp-tx-byte no haya contado nunca, más abajo. Cada proporción está limitada a 1, con los cuatro deltas de bytes escritos en la misma fila; ahí rx_bytes y tx_bytes son los denominadores de la proporción, no los totales del cable.

No es una proporción del cable. Una trama que el chip del switch reenvió por hardware no está en ninguno de los dos números: nunca llegó a la CPU. La parte de los bytes del cable de un puerto que se queda la CPU — driver-rx-byte frente a rx-byte — es otra pregunta, y la responde a partir de los contadores en bruto el panel apilado “Where a port’s receive bytes went”; la etapa de derivación no la calcula.

Un puerto del switch cuyo fp-rx-byte es igual a su driver-rx-byte da alrededor del 100 %: cada byte que el puerto entrega a la CPU se cuenta en el driver, capaz de fast path, así que la línea del puerto dice poco. La proporción informa sobre las interfaces software, como un bridge o un cliente PPPoE (medido).

La proporción de tx se omite mientras fp-tx-byte no haya contado nunca. Un router puede dejar fp-tx-byte a 0 en todas las interfaces tras cientos de GB transmitidos: eso se lee como un contador que RouterOS no mantiene allí y no como un fast path que no reenvió nada, y una proporción calculada a partir de él sería un 0 % fabricado. Mientras el fp-tx-byte acumulado de una interfaz sea 0, el colector no escribe fp_tx_share para ella, y sus tx_bytes y fp_tx_bytes son 0. Todavía no se ha producido ninguna proporción de tx a partir de contadores en vivo, y no está establecido por qué RouterOS deja ese contador a 0 (no probado).

También falta una proporción para un sentido que no movió bytes, cuyo contador retrocedió, o cuyo contador del fast path el puerto no informa, y la fila entera falta cuando no se pudo diferenciar el denominador de ninguno de los dos sentidos. La primera lectura de cada interfaz siembra y no escribe nada.

Un delta que no se pudo calcular — su contador ausente, que retrocedió, u omitido junto con la proporción de tx — se escribe como 0 junto a la proporción ausente: las filas de InfluxDB y SQL y el objeto fastpath de Elasticsearch llevan rx_bytes, fp_rx_bytes, tx_bytes y fp_tx_bytes siempre. Esto está leído en el código (internal/derive/derive.go) y no observado (Probado en). En ese caso, lee la proporción, no el delta.

La proporción es por lectura, y en una interfaz que mueve pocos paquetes oscila entre 0 y 100 % de una lectura a otra, por lo que el panel “Fast-path share of the traffic each interface hands the CPU” la pondera por bytes en cada intervalo — los bytes por fast path del intervalo entre los bytes del intervalo — en vez de dibujar el valor de cada lectura. La forma de Prometheus de ese panel es el gauge por lectura del colector y conserva ese ruido.

Destino Junto a las muestras del kernel Junto a las lecturas de contadores
InfluxDB, Telegraf, stdout lp mikroscope_derived: mem_pressure, burst, suspect, y los cocientes que se pudieron calcular mikroscope_derived_iface{interface}
SQL (--sql, --postgres) mikroscope_derived, cocientes NULL donde no se calcularon mikroscope_derived_iface
file, stdout json una línea {"derived":…} tras su muestra no se escribe; los contadores en bruto están en la línea {"api":…}
Prometheus gauges mikroscope_derived_* de la muestra más reciente; mikroscope_collector_bursts_total mikroscope_derived_fastpath_share{interface,direction}
OTLP gauges mikroscope.derived.* mikroscope.derived.fastpath_share{interface,direction}
Graphite rutas derived.* api.iface.<if>.fp_rx_share, fp_tx_share
Elasticsearch derived en el documento del kernel fastpath en el documento de la API
Loki — —

Tres destinos escriben los nombres del lado del kernel a su manera, y llevan menos. Prometheus escribe mikroscope_derived_memory_pressure, mikroscope_derived_cycles_per_packet, mikroscope_derived_instructions_per_packet, mikroscope_derived_cache_misses_per_packet y mikroscope_derived_packets_per_interrupt de la muestra más reciente; burst solo le llega como el contador mikroscope_collector_bursts_total, y suspect no le llega. OTLP escribe mikroscope.derived.memory_pressure, mikroscope.derived.cycles_per_packet, mikroscope.derived.instructions_per_packet, mikroscope.derived.cache_misses_per_packet y mikroscope.derived.packets_per_irq. Graphite escribe derived.mem_pressure, derived.cycles_per_packet, derived.instructions_per_packet, derived.cache_misses_per_packet y derived.packets_per_irq. Ni OTLP ni Graphite llevan burst ni suspect. En los tres, un cociente que no se pudo calcular se omite en vez de escribirse como 0.