Monitoramento de TI: check_load e sanidade

Existe uma grande vítima de chutes e ajustes insanos de “thresholds” no mundo do monitoramento: o “load averages”, ou simplesmente “load”, para os mais íntimos. E os chutes em seus valores para “warning” e “critical” começam a aparecer exatamente pelo motivo menos desejado: a falta de entendimento sobre o que é e o que representam esses valores.

Os loads são apresentados em três valores distintos, porém correlatos: um representando a média do último minuto, outro a de cinco e outro a de quinze. E essa apresentação (em três valores) tem um motivo de ser: observar a tendência, algo normalmente ignorado no monitoramento.

A primeira confusão com os loads surge no entendimento empírico equivocado de que ele representa uso de recursos, mas não é bem assim. O load é calculado a partir do tempo que processos “seguram” a fila, algo que reflete o consumo. Loads altos costumam, sim, representar problemas… mas esses problemas são geralmente decorrentes de configurações equivocadas que impactam no aproveitamento inadequado dos recursos de hardware.

A falta de um entendimento adequado sobre o que os load averages representam acaba exigindo ajustes cegos de thresholds acompanhados do péssimo argumento “é assim mesmo” ou “esse servidor trabalha muito”. Tende-se a acreditar que um servidor com loads altos está trabalhando acima do esperado quando, na verdade, está trabalhando de forma inadequada, pois processos estão “segurando” a fila.

Monitorar load averages exige a observação do estado atual, da tendência (se está aumentando ou diminuindo) e picos. O estado atual e os picos podem ser diretamente observados no primeiro valor exibido, o da média do último minuto. Os outros demais valores (cinco e quinze minutos) permitem observar a tendência e devem ser considerados para comparação entre si e o último minuto. Julgar separadamente valores que representam a mesma coisa é, infelizmente, um erro muito comum.

Outro erro recorrente é o ajuste de thresholds “prevendo” uma normalidade operacional, removendo a objetividade desses indicadores e tornando-os cada vez mais subjetivos ao passo que os thresholds vão passando por novos ajustes ao longo do tempo sem qualquer lógica envolvida. Esses thresholds devem ser objetivos e estáticos, pois representam a situação do servidor e seus serviços, não uma normalidade operacional.

Idealmente, o load não deve ser superior a 1 (um) para cada núcleo de processamento disponível, mas deve-se considerar picos. E considerar picos envolve a alteração do “nível” do alarme. Se o load aumenta, o nível sobe. Mas se a tendência é a normalização (ou diminuição), o nível também deve seguir essa tendência.

Para ilustrar melhor, vamos seguir com exemplos. Supondo que um determinado servidor possua 4 núcleos, definimos o limite de OK para 4 (4,00, 4,00, 4,00). A partir disso, vamos trabalhar com multiplicadores, onde 1, 1.5 e 2 tendem a representar bem valores para um monitoramento “saudável”. Podemos, então, seguir com uma fórmula (onde X é o número de núcleos disponíveis e Y o valor representando o load):

  • 1 minuto: WARNING para Y>X*1.5; CRITICAL para Y>X*2;
  • 5 minutos: WARNING para Y>X; CRITICAL para Y>X*1.5;
  • 15 minutos: WARNING para Y>X; CRITICAL para Y>X*1.5.

Observe que para 1 minuto consideramos multiplicadores maiores. Dessa forma consideramos picos e evitamos alarmes falsos, já que devemos, ainda, considerar a tendência comparando 1, 5 e 15 minutos.

Utilizando a fórmula acima, vamos analisar, então, algumas situações (considerando 4 núcleos):

  • load: 4,00, 4,00, 4,00 — situação limite, até aqui o monitoramento deve retornar OK
  • load: 7,00, 5,00, 4,00 — WARNING para 1 e 5 minutos com tendência a aumento
  • load: 9,00, 5,50, 4,50 — CRITICAL para 1 e WARNING para 5 minutos com tendência a aumento
  • load: 5,00, 7,00, 5,50 — WARNING para 1 e CRITICAL para 5 minutos com tendência a redução
  • load: 4,00, 6,50, 8,00 — OK para 1, CRITICAL para 5 e CRITICAL para 15 minutos com tendência a redução

Veja que não faz sentido os dois últimos casos serem julgados críticos (CRITICAL) já que a tendência é a de queda do load. Nesses casos faz sentido a redução do nível do alarme para cada diminuição considerando a sequência 15, 5 e 1 minutos. O retorno, então, seria OK, já que a tendência é a de normalizar a situação.

Poderíamos, então (considerando representação por load_1, load_5 e load_15), dizer o seguinte:

  • em CRITICAL: se load_5 < load_15, julga-se WARNING, e, se load_1 < load_5, julga-se OK
  • em CRITICAL: se load_5 < load_15 e load_1 > load_5, continuamos a considerar WARNING

Considerando, então, que threshold de load não deve ser variável, mas que o nível do alarme deve ser, teremos maior sanidade no monitoramento, “forçaremos” equipes de infraestrutura e sistemas a adequarem as configurações, garantiremos o melhor uso possível dos recursos de hardware disponíveis, evitaremos falso-positivos e não perderemos alarmes que representam possíveis problemas.

Utilizando os conceitos acima expostos, então, podemos ter (em C, por exemplo) um check_load (para Nagios) mais são, conforme segue:

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>

int main()
{
        double load[3];
        char *status=”OK”;
        float warn[3], crit[3], ec=0;
        int cores=sysconf(_SC_NPROCESSORS_ONLN);

        getloadavg(load,3);
        warn[0]=cores*1.5; crit[0]=cores*2; warn[1]=cores; crit[1]=cores*1.5; warn[2]=cores; crit[2]=cores*1.5;

        if (load[0] > warn[0]) ec=1; if (load[1] > warn[1]) ec=1; if (load[2] > warn[2]) ec=1;
        if (load[0] > crit[0]) ec=2; if (load[1] > crit[1]) ec=2; if (load[2] > crit[2]) ec=2;
        if (ec != 0 && load[1] < load[2]) ec–; if (ec != 0 && load[0] < load[1]) ec–;
        if (ec == 1) status=”WARNING”; if (ec == 2) status=”CRITICAL”;

        printf(“%s – load average: %.2f, %.2f, %.2f|load1=%.3f;%.3f;%.3f;0; load5=%.3f;%.3f;%.3f;0; load15=%.3f;%.3f;%.3f;0;\n”, status, load[0], load[1], load[2], load[0], warn[0], crit[0], load[1], warn[1], crit[1], load[2], warn[2], crit[2]);

        return ec;
}

Observe as três linhas em negrito. Na primeira coletamos a quantidade de processadores (núcleos, na verdade) online. Na segunda aplicamos os multiplicadores 1, 1.5 e 2, valores considerados razoáveis para nos mostrar “fugas” da normalidade. E na terceira fazemos a redução do nível de alarme conforme tendência de queda do load.

Se pudermos padronizar o check_load, eliminando variações de thresholds, e, mantivermos essa sanidade lógica, tenderemos a aproveitar melhor os recursos de hardware disponíveis, eliminando a necessidade de crescimento de infraestrutura pelo mau aproveitamento decorrente especialmente de falhas de configurações.

Miniero

Mais artigos deste autor »

SysAdmin com vasta experiência em projetos de grande porte, data centers, performance tuning, segurança e clustering. Um verdadeiro "escovador de bits" que possui uma fome insaciável por conhecimento nas mais diversas áreas de estudos possíveis, de matrizes elétricas a microprocessadores, de aritmética a mecânica quântica, de meros verbos a psicologia.


Deixe seu comentário

Seu endereço de e-mail não será publicado. Campos com * são obrigatórios!