Nos encontramos con un comportamiento extraño en el que vemos una alta utilización de la CPU pero un promedio de carga bastante bajo.
El comportamiento se ilustra mejor con los siguientes gráficos de nuestro sistema de monitoreo.
Aproximadamente a las 11:57 la utilización de la CPU va del 25% al 75%. El promedio de carga no cambia significativamente.
Ejecutamos servidores con 12 núcleos con 2 hiperprocesos cada uno. El sistema operativo ve esto como 24 CPU.
Los datos de utilización de la CPU se recopilan ejecutando /usr/bin/mpstat 60 1
cada minuto. Los datos para la all
fila y la %usr
columna se muestran en el cuadro anterior. Estoy seguro de que esto muestra el promedio por datos de CPU, no la utilización "apilada". Si bien vemos un 75% de utilización en el gráfico, vemos un proceso que muestra el uso de aproximadamente 2000% de CPU "apilada" top
.
La cifra promedio de carga se toma de /proc/loadavg
cada minuto.
uname -a
da:
Linux ab04 2.6.32-279.el6.x86_64 #1 SMP Wed Jun 13 18:24:36 EDT 2012 x86_64 x86_64 x86_64 GNU/Linux
Linux dist es Red Hat Enterprise Linux Server release 6.3 (Santiago)
Ejecutamos un par de aplicaciones web Java bajo una carga bastante pesada en las máquinas, piense 100 solicitudes / s por máquina.
Si interpreto los datos de utilización de la CPU correctamente, cuando tenemos un 75% de utilización de la CPU, significa que nuestras CPU están ejecutando un proceso el 75% del tiempo, en promedio. Sin embargo, si nuestras CPU están ocupadas el 75% del tiempo, ¿no deberíamos ver un promedio de carga más alto? ¿Cómo podrían las CPU estar ocupadas al 75% mientras solo tenemos 2-4 trabajos en la cola de ejecución?
¿Estamos interpretando nuestros datos correctamente? ¿Qué puede causar este comportamiento?
fuente
Respuestas:
Al menos en Linux, el promedio de carga y la utilización de CPU son en realidad dos cosas diferentes. El promedio de carga es una medida de cuántas tareas están esperando en una cola de ejecución del núcleo (no solo el tiempo de CPU sino también la actividad del disco) durante un período de tiempo. La utilización de la CPU es una medida de qué tan ocupada está la CPU en este momento. La mayor carga que un solo subproceso de CPU vinculado al 100% durante un minuto puede "contribuir" al promedio de carga de 1 minuto es 1. Una CPU de 4 núcleos con hyperthreading (8 núcleos virtuales) todo al 100% durante 1 minuto contribuiría 8 a El promedio de carga de 1 minuto.
Muchas veces estos dos números tienen patrones que se correlacionan entre sí, pero no puedes pensar en ellos como lo mismo. Puede tener una carga alta con casi un 0% de utilización de la CPU (como cuando tiene muchos datos de E / S atascados en un estado de espera) y puede tener una carga de 1 y 100% de CPU, cuando tiene un proceso único en ejecución inclinación completa Además, durante cortos períodos de tiempo, puede ver la CPU cerca del 100%, pero la carga aún está por debajo de 1 porque las métricas promedio aún no se han "recuperado".
He visto que un servidor tiene una carga de más de 15,000 (sí, realmente no es un error tipográfico) y un CPU% cercano al 0%. Sucedió porque un recurso compartido de Samba tenía problemas y muchos clientes comenzaron a quedarse atascados en un estado de espera de E / S. Lo más probable es que si está viendo un número de alta carga regular sin actividad de CPU correspondiente, está teniendo algún tipo de problema de almacenamiento. En las máquinas virtuales, esto también puede significar que hay otras máquinas virtuales que compiten fuertemente por los recursos de almacenamiento en el mismo host de VM.
La alta carga tampoco es necesariamente algo malo, la mayoría de las veces solo significa que el sistema se está utilizando a su máxima capacidad o tal vez está más allá de su capacidad de mantenerse al día (si el número de carga es mayor que el número de núcleos de procesador). En un lugar donde solía ser un administrador de sistemas, tenían a alguien que observaba el promedio de carga en su sistema primario más de cerca que Nagios. Cuando la carga era alta, me llamaban 24/7 más rápido de lo que se podría decir SMTP. La mayoría de las veces, nada estaba realmente mal, pero asociaron el número de carga con algo que estaba mal y lo vieron como un halcón. Después de verificar, mi respuesta generalmente fue que el sistema solo estaba haciendo su trabajo. Por supuesto, este fue el mismo lugar donde la carga se elevó a más de 15000 (aunque no es el mismo servidor), por lo que a veces significa que algo está mal. Debe considerar el propósito de su sistema. Si es un caballo de batalla, espere que la carga sea naturalmente alta.
fuente
La carga es un número muy engañoso. Tómelo con un grano de sal.
Si genera muchas tareas en una sucesión muy rápida que se completa muy rápidamente, el número de procesos en la cola de ejecución es demasiado pequeño para registrar la carga para ellos (el núcleo cuenta la carga una vez cada cinco segundos).
Considere este ejemplo, en mi host que tiene 8 núcleos lógicos, este script de Python registrará un gran uso de CPU en la parte superior (alrededor del 85%), pero casi ninguna carga.
Otra implementación, esta evita
wait
en grupos de 8 (lo que sesgaría la prueba). Aquí, el padre siempre intenta mantener el número de hijos en el número de CPU activas, por lo que será mucho más ocupado que el primer método y, con suerte, más preciso.La razón de este comportamiento es que el algoritmo pasa más tiempo creando procesos secundarios que ejecutando la tarea real (contando hasta 10000). Las tareas aún no creadas no pueden contar para el estado 'ejecutable', pero tomarán% sys en el tiempo de CPU a medida que se generan.
Por lo tanto, la respuesta realmente podría ser en su caso que cualquier trabajo que se esté realizando genera un gran número de tareas en rápida sucesión (hilos o procesos).
fuente
Si el promedio de carga no aumenta mucho, solo significa que las especificaciones de hardware y la naturaleza de las tareas a procesar dan como resultado un buen rendimiento general, evitando que se acumulen en la cola de tareas durante algún tiempo.
Si hubo un fenómeno de contención porque, por ejemplo, la complejidad promedio de la tarea es demasiado alta o el tiempo promedio de procesamiento de la tarea toma demasiados ciclos de CPU, entonces sí, el promedio de carga aumentaría.
ACTUALIZACIÓN
Puede que no esté claro en mi respuesta original, por lo que estoy aclarando ahora:
La fórmula exacta de cálculo promedio de carga es:
loadvg = tasks running + tasks waiting (for cores) + tasks blocked
.Definitivamente puede tener un buen rendimiento y acercarse a un promedio de carga de 24 pero sin penalizar el tiempo de procesamiento de las tareas. Por otro lado, también puede tener entre 2 y 4 tareas periódicas que no se completan con la suficiente rapidez, luego verá crecer el número de tareas en espera (para ciclos de CPU) y eventualmente alcanzará un promedio de carga alto. Otra cosa que puede suceder es que las tareas ejecuten operaciones de E / S síncronas pendientes y luego bloqueen un núcleo, reduzcan el rendimiento y hagan que la cola de tareas de espera crezca (en ese caso, es posible que la
iowait
métrica cambie)fuente
El promedio de carga incluye tareas que están bloqueadas en el disco IO, por lo que puede tener una utilización de CPU nula y un promedio de carga de 10 con solo 10 tareas que intentan leer desde un disco muy lento. Por lo tanto, es común que un servidor ocupado comience a sacudir el disco y toda la búsqueda causa muchas tareas bloqueadas, elevando el promedio de carga, mientras que el uso de la CPU cae, ya que todas las tareas están bloqueadas en el disco.
fuente
Si bien la respuesta de Matthew Ife fue muy útil y nos condujo en la dirección correcta, no fue exactamente lo que causó el comportamiento en nuestro caso. En nuestro caso, tenemos una aplicación Java multiproceso que utiliza la agrupación de subprocesos, por lo que no se realiza ningún trabajo para crear las tareas reales.
Sin embargo, el trabajo real que realizan los subprocesos es de corta duración e incluye esperas de E / S o esperas de sincronización. Como Matthew menciona en su respuesta, el sistema operativo muestrea el promedio de carga, por lo que se pueden perder las tareas de corta duración.
Hice un programa Java que reproducía el comportamiento. La siguiente clase Java genera una utilización de CPU del 28% (650% apilada) en uno de nuestros servidores. Al hacer esto, el promedio de carga es de aproximadamente 1.3. La clave aquí es el sueño () dentro del hilo, sin él el cálculo de carga es correcto.
Para resumir, la teoría es que los subprocesos en nuestras aplicaciones están inactivos mucho y luego realizan un trabajo de corta duración, por lo que las tareas no se muestrean correctamente mediante el cálculo del promedio de carga.
fuente
El promedio de carga es el número promedio de procesos en la cola de la CPU. Es específico para cada sistema, no puede decir que una LA es genéricamente alta en todos los sistemas, y otra es baja. Entonces tiene 12 núcleos, y para que LA aumente significativamente, el número de procesos debe ser realmente alto.
Otra pregunta es qué se entiende por el gráfico "Uso de CPU". Si se toma de SNMP, como debería ser, y su implementación de SNMP es
net-snmp
, entonces solo se apila la carga de CPU de cada una de sus 12 CPU. Entonces, paranet-snmp
la cantidad total de carga de la CPU es 1200%.Si mis suposiciones son correctas, entonces el uso de la CPU no aumentó significativamente. Por lo tanto, LA no aumentó significativamente.
fuente
all
fila. Estoy bastante seguro de que es un promedio en todas las CPU, no está apilado. Por ejemplo, cuando se produce el problema, top muestra 2000% de uso de CPU para un proceso. Ese es el uso apilado.El escenario aquí no es particularmente inesperado, aunque es un poco inusual. Lo que toca Xavier, pero no se desarrolla mucho, es que aunque Linux (por defecto) y la mayoría de los sabores de Unix implementan la multitarea preventiva, en una máquina saludable, las tareas rara vez se adelantan. A cada tarea se le asigna un intervalo de tiempo para ocupar la CPU, solo se adelanta si excede este tiempo y hay otras tareas esperando para ejecutarse (tenga en cuenta que la carga informa el número promedio de procesos tanto en la CPU como en espera de ejecutarse) . La mayoría de las veces, un proceso rendirá en lugar de ser interrumpido.
(en general, solo debe preocuparse por la carga cuando se acerca el número de CPU, es decir, cuando el planificador comienza a adelantar tareas).
Todo se trata del patrón de actividad, la utilización claramente aumentada de la CPU por algunas tareas (muy probablemente una pequeña minoría) no estaba teniendo un efecto adverso en el procesamiento de otras tareas. Si pudiera aislar las transacciones que se están procesando, esperaría que vea un nuevo grupo emergente durante la desaceleración, mientras que el conjunto de tareas existente no se vio afectado.
actualizar
Un escenario común en el que puede ocurrir una CPU alta sin un gran aumento en la carga es donde una tarea desencadena una (o una secuencia) de otras tareas, por ejemplo, al recibir una solicitud de red, el controlador dirige la solicitud a un hilo separado, el hilo separado luego realiza algunas llamadas asincrónicas a otros procesos ... el muestreo de la secuencia de ejecución hace que la carga se informe más baja de lo que realmente es, pero no aumenta linealmente con el uso de la CPU; la cadena de tareas activadas no habría sido ejecutable sin el evento inicial, y debido a que ocurren (más o menos) secuencialmente, la cola de ejecución no se infla.
fuente
all
fila aún muestra el promedio por CPU. Aclararé la pregunta.