CPU steal time no VPS: como detectar vizinho ruidoso
Entenda o erro de CPU steal time no VPS, leia a coluna st do vmstat e diferencie vizinho ruidoso de sobrecarga causada pelos seus próprios processos.
O que o steal time da CPU mede realmente
O steal time da CPU é a parte do tempo em que a sua CPU virtual estava pronta para executar, sem nada para aguardar, enquanto o hypervisor atribuía o núcleo físico a outro guest. O trabalho ficou na fila. O núcleo estava a executar outra máquina virtual. O Linux contabiliza esses ciclos separadamente e apresenta-os como st. É assim que distingue entre "o meu servidor está ocupado" e "o meu servidor está à espera da sua vez".
Essa diferença é precisamente a razão de existir deste contador. O tempo que os seus próprios processos passam na CPU é apresentado como us (user) ou sy (system). O tempo que uma tarefa passa bloqueada à espera do armazenamento é apresentado como wa (I/O wait). Uma vCPU (CPU virtual) que está pronta para executar, na run queue, sem operações de I/O pendentes, mas que continua sem executar, é apresentada como st. Nada dentro do seu servidor pode eliminar esse estado, porque a decisão de agendamento é tomada uma camada abaixo, no host.
Isto resulta diretamente de como um VPS partilha uma máquina física entre vários guests. A causa habitual é um vizinho: outro guest no mesmo node está a consumir muitos recursos, por isso o host divide os núcleos entre os dois. Existe uma segunda causa que muitas vezes passa despercebida. Muitos providers limitam uma vCPU partilhada a uma fração de um núcleo físico e, em vários hypervisors, esse limite imposto é contabilizado como steal dentro do guest. Assim, uma leitura elevada de st indica que o núcleo não lhe foi atribuído. Não indica sempre quem o utilizou.
De onde vem o valor de steal
O kernel não consegue medir steal sozinho porque não consegue ver o host. O hypervisor fornece esse valor. No KVM, o host escreve um contador por vCPU numa página partilhada com o guest, e o guest acumula-o quando o kernel é compilado com CONFIG_PARAVIRT_TIME_ACCOUNTING, o que acontece em todos os kernels das distribuições. O Xen comunica o mesmo valor através da sua área de estado de execução. O total chega ao userspace num único local:
head -1 /proc/statEssa linha cpu contém dez contadores, em ticks de USER_HZ desde o boot, nesta ordem: user, nice, system, idle, iowait, irq, softirq, steal, guest, guest_nice. Steal é o oitavo valor depois do rótulo. Todas as ferramentas abaixo, vmstat, top, mpstat e qualquer exporter do Prometheus, leem esse mesmo campo e convertem duas amostras numa percentagem.
Uma consequência é mais importante do que as restantes. Se o hypervisor nunca exportar o contador, o campo permanece a zero para sempre, e todas as ferramentas baseadas nele comunicam um 0.0 tranquilo enquanto o host está sobrecarregado. O KVM e o Xen exportam esse valor. Os guests em VMware e Hyper-V normalmente comunicam um zero constante. Verifique a plataforma antes de confiar num zero:
systemd-detect-virtO comando apresenta o nome da plataforma, como kvm, xen, vmware ou microsoft, e none em bare metal. Dentro de um contentor, comunica o runtime em vez disso, como lxc, docker ou podman, o que informa sobre o contentor e não sobre a máquina subjacente. Em kvm, um zero é uma evidência real de que o host está a tratar bem o guest. Numa plataforma que nunca preenche esse campo, um zero não é evidência de nada, e a contenção tem de ser avaliada através da medição do tempo de execução de trabalho real.
Como verificar o tempo de CPU steal numa VPS?
vmstat faz parte do pacote procps. Está presente em quase todas as imagens VPS de Ubuntu e Debian, mas pode não existir em algumas imagens mínimas de contentores. Instale-o antes de depender dele.
sudo apt-get update
sudo apt-get install -y procps
vmstat --version
vmstat 1 5vmstat --version apresenta uma linha como vmstat from procps-ng 4.0.4. Se essa linha for apresentada, a ferramenta está instalada e está a ler contadores reais do kernel. Depois, vmstat 1 5 recolhe uma amostra por segundo, cinco vezes.
procs -----------memory---------- ---swap-- -----io---- -system-- -------cpu-------
r b swpd free buff cache si so bi bo in cs us sy id wa st gu
1 0 0 3216484 98304 1284360 0 0 4 18 62 110 3 1 96 0 0 0
2 0 0 3216232 98304 1284360 0 0 0 0 248 431 6 2 84 0 8 0Procure a coluna st no bloco cpu, à direita. As versões atuais do procps-ng apresentam uma coluna gu depois dela para o tempo do guest KVM. Por isso, st é a segunda coluna a contar da direita, e não a última. Leia a coluna pelo nome do cabeçalho, porque essa posição mudou entre versões.
Duas práticas tornam esta leitura mais fiável. A primeira linha de dados é a média desde o boot, por isso ignore-a e leia as linhas seguintes. Uma única amostra também não é uma medição, porque o steal ocorre em picos. Execute vmstat 1 60 e monitorize um minuto completo antes de tirar conclusões.
top apresenta o mesmo valor na linha de resumo %Cpu(s), no campo identificado como st:
%Cpu(s): 6.2 us, 2.1 sy, 0.0 ni, 83.9 id, 0.0 wa, 0.0 hi, 0.3 si, 7.5 stPara obter detalhes por CPU, acrescente sysstat:
sudo apt-get install -y sysstat
mpstat -P ALL 1 5mpstat apresenta uma linha por CPU com uma coluna %steal. Essa coluna mostra se todas as vCPUs são afetadas ou apenas uma. Para manter o histórico necessário num pedido de suporte, guarde as amostras em vez de as ler no ecrã:
date -u | tee -a ~/steal.log
mpstat -P ALL 1 5 | tee -a ~/steal.logExecute isso a partir do cron durante as horas em que suspeita do problema. O ficheiro permite deixar de dizer a um fornecedor que "parecia lento na noite passada" e mostrar exatamente os dez minutos afetados.
O que significam os valores de steal?
- Um
0.0estável. O estado é saudável ou a plataforma não reporta steal. Confirme comsystemd-detect-virtantes de tirar conclusões. - Picos de alguns pontos percentuais durante alguns segundos. É normal em qualquer nó partilhado. Uma máquina vizinha inicia uma compilação ou o host executa as cópias de segurança.
- Entre 1 e 5 por cento de forma sustentada num plano partilhado. É esperado. O preço reflete a utilização de CPU partilhada.
- Entre 5 e 10 por cento de forma sustentada. Existe uma degradação de desempenho mensurável. Comece a registar evidências e compare as mesmas horas ao longo de vários dias.
- Acima de 10 por cento durante várias horas. O nó está sobrecarregado para a sua carga de trabalho. Este é o nível que justifica abrir um pedido de suporte ou mudar de nó.
Use estes intervalos como guia de interpretação, não como uma especificação, porque nenhum fornecedor publica uma garantia de steal num plano partilhado. Avalie-os em função do que executa. Um job em lote noturno pode suportar 15 por cento de steal sem que alguém note. Um serviço sensível à latência mostra o efeito no p99 muito antes de a média parecer preocupante. Por isso, cargas de trabalho sensíveis à latência, como bots de trading devem usar cores dedicados.
Qual é o custo do steal time?
A aritmética é curta. Se uma fração s do seu tempo de CPU for consumida, uma tarefa que precisa de uma quantidade fixa de CPU demora 1 / (1 - s) vezes mais tempo no relógio. Para uma tarefa que precisa de 60 segundos de CPU:
The data behind this chart
[
{
"steal_percent": 0,
"wall_clock_seconds": "60.0"
},
{
"steal_percent": 3,
"wall_clock_seconds": "61.9"
},
{
"steal_percent": 8,
"wall_clock_seconds": "65.2"
},
{
"steal_percent": 15,
"wall_clock_seconds": "70.6"
},
{
"steal_percent": 25,
"wall_clock_seconds": "80.0"
},
{
"steal_percent": 40,
"wall_clock_seconds": "100.0"
}
]Com 3 por cento, um valor comum num plano partilhado, essa tarefa demora 61.9 segundos em vez de 60.0. Ninguém abre um chamado por causa disso. Com 8 por cento, demora 65.2 segundos. Com 40 por cento, a mesma tarefa precisa de 100.0 segundos, e uma fila que antes era processada começa a crescer.
Esses valores são calculados, não medições. O modelo assume uma única thread executável e que o steal se distribui uniformemente ao longo do intervalo. Os serviços reais muitas vezes parecem piores do que a curva indica, porque uma fatia roubada ocorre no meio de um pedido, e o atraso é então pago novamente por tudo o que está à espera desse pedido. Para obter o seu próprio valor em vez de usar uma fórmula, faça benchmark da VPS durante uma hora tranquila e novamente durante uma hora movimentada, registando st nas duas janelas.
É roubo de CPU ou é outra coisa?
É fácil confundir steal com outros sintomas. Leia os contadores em conjunto, na mesma linha de vmstat.
stalto enquantoreuspermanecem baixos: o host não está a disponibilizar o core. Isso é steal.rmuito acima do número de vCPUs, comusalto estperto de zero: está a executar mais trabalho do que os seus próprios CPUs conseguem suportar. Comparercom o resultado denproc. Isto é oversubscription dos seus próprios recursos, não um problema causado por um vizinho.waalto comstperto de zero: as tarefas estão bloqueadas no armazenamento. É um problema diferente e requer uma correção diferente.- Load average alto enquanto
steusestão ambos baixos: o valor de load também conta tarefas não interrompíveis. Normalmente, isto indica um dispositivo bloqueado ou um mount de rede pendurado, e não um problema de CPU.
Os planos burstable merecem uma nota própria. Fornecem um saldo de créditos que aumenta quando está idle e diminui quando está ocupado. Quando o saldo termina, o provider limita-o a uma taxa base. Em algumas plataformas, esse throttle é reportado como steal. Noutras, é invisível a partir do sistema e simplesmente recebe menos ciclos por segundo. Leia a descrição do plano antes de concluir que a causa é um vizinho.
Por que um contentor não apresenta steal time
Steal é uma propriedade da máquina virtual, não de um contentor em execução dentro dela. Um contentor Docker no seu próprio VPS partilha o /proc do host, portanto um valor st lido dentro dele corresponde ao steal do VPS, que é o resultado pretendido. A virtualização baseada em contentores, vendida como VPS, comporta-se de forma diferente. Com lxcfs ativo, /proc/stat dentro do contentor é sintetizado a partir da contabilidade do cgroup, e o steal é zero por definição. Uma stack de monitorização que recolha dados apenas a partir do interior pode apresentar um zero constante e estável enquanto a máquina física subjacente está sem capacidade de CPU.
Dentro de um contentor, o contador com o mesmo significado é o throttling da quota de CPU. No cgroup v2:
cat /sys/fs/cgroup/cpu.statnr_throttled conta os períodos de aplicação em que o grupo atingiu a sua quota de CPU, e throttled_usec totaliza o tempo durante o qual ficou suspenso. Um nr_throttled crescente significa que o processo estava pronto para executar, mas não estava a executar. A experiência é a mesma que com steal, mas a causa é um limite definido por si. Verifique os seus próprios limites antes de responsabilizar o host, sobretudo se executa os seus serviços em Docker num VPS com limites de CPU no ficheiro compose. A virtualização em camadas acrescenta mais um ponto onde o tempo pode desaparecer, porque uma VM dentro do seu VPS acumula o steal do VPS e o seu próprio atraso de escalonamento. Tenha isto em conta se usa virtualização aninhada num VPS.
O que fazer com steal persistente
Nenhuma definição dentro do guest corrige o steal, porque o scheduler que toma essa decisão é executado fora do guest. Atualizar o kernel também não altera isso: o agendamento consciente da cache adicionado no Linux kernel 7.2 reorganiza as suas tarefas entre os cores que lhe foram efetivamente atribuídos e não consegue recuperar os ciclos que um vizinho já consumiu. Há quatro medidas concretas.
Recolha primeiro as evidências. Registe os timestamps em UTC, a duração de cada episódio, a frequência com que se repete e se mpstat mostra um vCPU afetado ou todos. Uma semana de amostras registadas vale mais do que uma captura de ecrã.
Abra um ticket com esses dados. Faça duas perguntas diretas: este node está oversubscribed durante estas janelas e a minha instância pode ser movida? Cole o output de vmstat e as horas exatas. Os providers atuam com base numa janela reproduzível, e um ticket que apenas diga que o servidor está lento recebe uma resposta a pedir essa janela. A quantidade deste trabalho que pode delegar é uma das diferenças práticas entre um VPS gerido e um VPS não gerido.
Peça uma migração. Mover um guest para um node menos carregado é um procedimento normal para um provider e costuma exigir apenas um reboot curto. Esta é a correção que não tem custo e resolve o caso comum, em que um node fica temporariamente com vários vizinhos pesados ao mesmo tempo.
Elimine a contention com uma opção paga. Um plano com vCPU dedicada reserva cores físicos para a sua instância, por isso o contador fica em zero e permanece assim. O custo mensal é maior, e esta é a resposta adequada para uma workload que não pode absorver essa variação. Se isso ainda não for suficiente, ou se também quiser reservar a largura de banda da memória, o passo seguinte é um servidor dedicado em vez de um VPS.
Enquanto aguarda por qualquer uma destas medidas, reduza o impacto do steal. Execute menos worker threads do que o número de vCPUs, porque threads que não conseguem obter um core apenas acrescentam context switches. Mova o trabalho batch para as horas em que o node está menos ocupado, conforme o seu próprio log agora demonstra. Depois, faça nova medição com o mesmo comando durante as mesmas horas, para poder dizer se a alteração funcionou em vez de fazer uma suposição.
FAQ
Qual é um valor normal de CPU steal time numa VPS?
Num plano partilhado, picos breves e um valor sustentado inferior a cerca de 5 por cento são normais, porque uma CPU partilhada significa que o host divide os cores físicos entre os guests. Valores sustentados de dois dígitos durante várias horas não são normais e justificam a abertura de um ticket. Num plano com vCPU dedicada, o valor esperado é 0.0, pelo que qualquer outro valor deve ser reportado como uma falha. Avalie o número em função da sua própria carga de trabalho: um job batch executado durante a noite tolera steal, mas uma API sensível à latência não.
Um plano maior resolve um valor elevado de steal time?
Não por si só. Ter mais vCPUs no mesmo nó partilhado significa ter mais CPUs virtuais a competir pelos mesmos cores físicos congestionados, e a percentagem pode permanecer exatamente igual. O que elimina o steal é uma alocação de CPU dedicada ou a migração para um nó menos carregado. Uma quota maior numa máquina ocupada continua a ser uma quota numa máquina ocupada.
Porque é que a minha VPS mostra 0 de steal time quando está claramente lenta?
Há duas razões comuns. O hypervisor pode não exportar o contador, o que é habitual em plataformas VMware e Hyper-V, pelo que o campo permanece a zero independentemente do que o host esteja a fazer. Execute systemd-detect-virt para ver em que plataforma está. Caso contrário, o bottleneck está noutro componente: verifique wa para esperas de armazenamento, compare r com nproc para identificar sobrecarga própria e consulte /sys/fs/cgroup/cpu.stat dentro dos containers para detetar throttling de quotas.
Posso reduzir o steal time a partir do meu servidor?
Não pode alterar o escalonamento do host a partir do guest. Só pode reduzir o impacto. Execute menos threads de trabalho do que o número de vCPUs disponíveis, para que haja menos trabalho na run queue à espera de um core que não está disponível. Transfira os jobs batch para as horas em que o nó está menos carregado. Coloque os resultados em cache, para que menos pedidos precisem de CPU. As alterações que eliminam efetivamente o steal, como a migração para outro nó ou para cores dedicados, dependem do provider.