Seu VPS precisa de swap? Veja como dimensionar
Imagens cloud costumam vir sem swap. Saiba quando um VPS pequeno precisa de um ficheiro, quanto criar, o efeito de vm.swappiness e quando zram é melhor.
É necessário swap no seu VPS?
A maioria das imagens de cloud é disponibilizada sem swap. Num VPS pequeno, a resposta normalmente é sim: adicione um ficheiro de swap. O swap não faz um servidor com 1 GB comportar-se como um servidor com 2 GB. Dá ao kernel um local para colocar páginas anónimas pouco utilizadas. Isso mantém a cache de páginas útil e faz do OOM killer (out of memory killer, a rotina do kernel que escolhe um processo e o termina para libertar memória) um último recurso, em vez de uma primeira opção.
A versão curta é esta: num servidor que executa alguns serviços de longa duração, um ficheiro de swap pequeno compensa o espaço em disco que ocupa. Num servidor em que um processo tenta regularmente alocar mais memória do que a máquina tem disponível, o swap não o salvará. Também tornará a falha mais lenta e mais difícil de identificar. O restante deste guia explica como distinguir estes dois casos e aborda os dois custos que só aparecem num VPS.
Todos os comandos abaixo requerem root no seu próprio servidor. Execute-os nesse servidor, em vez de copiar a saída do servidor de outra pessoa.
O que a swap realmente faz e o que não faz
A memória do Linux tem dois tipos. As páginas apoiadas por ficheiros são cópias de dados que já existem no disco: os seus programas e todos os ficheiros que leu recentemente. Esse conjunto é a cache de páginas. As páginas anónimas são memória sem um ficheiro associado: a heap e a stack, além da maior parte do que uma base de dados aloca em tempo de execução.
Quando a memória fica escassa, o kernel tem de recuperar páginas. Uma página limpa apoiada por ficheiro é fácil de recuperar, porque a cópia no disco continua disponível e a página pode ser lida novamente mais tarde. Uma página anónima não é, porque a única cópia está na RAM. Sem swap, o kernel tem duas opções para a memória anónima: mantê-la ou terminar o processo que a possui.
Um servidor sem swap continua a paginar. Apenas pagina a memória errada. Sob pressão, o kernel reduz a cache de páginas e expulsa páginas de ficheiros de que vai precisar novamente, incluindo o texto executável dos programas em execução. Essas páginas regressam através de falhas de página maiores. Verá leituras do disco na coluna bi de vmstat e um contador pgmajfault crescente em /proc/vmstat, enquanto si e so permanecem a zero durante todo o período. O sistema está em thrashing e os contadores de swap não mostram nada.
A swap não adiciona capacidade. Se o conjunto de trabalho, ou seja, as páginas que estão efetivamente a ser acedidas, for maior do que a RAM, a swap transforma um encerramento por falta de memória num servidor muito lento. Por vezes, essa é a opção pretendida, porque é possível aceder e reparar um servidor lento, enquanto uma base de dados terminada não pode ser recuperada. Por vezes, é pior, porque um servidor lento continua a falhar as verificações de integridade enquanto mantém todas as ligações abertas. Decida o que pretende antes de a adicionar.
Por que as imagens de cloud são disponibilizadas sem swap?
É uma escolha deliberada. A mesma imagem precisa de arrancar em todos os planos que um fornecedor disponibiliza. Por isso, uma partição swap fixa desperdiçaria espaço em disco nos planos pequenos e seria desnecessária nos grandes. A velocidade do swap também depende do armazenamento subjacente à máquina virtual. A imagem não pode conhecer esse armazenamento antecipadamente. Além disso, quem cria as imagens optimiza o comportamento previsível. Um processo que termina imediatamente é mais fácil de diagnosticar em toda uma frota do que uma máquina que continua activa, mas responde a cada pedido com vários segundos de atraso.
Esses motivos aplicam-se a máquinas descartáveis. Um VPS que mantém é diferente. Nesse caso, repara a máquina em vez de a substituir. Por isso, alguns segundos de paging costumam ser preferíveis a um serviço terminado. Considere a ausência de swap como uma predefinição criada para o caso de uso de outra pessoa.
Ficheiro de swap ou partição de swap numa VPS?
Use um ficheiro. Uma partição implica redimensionar um sistema de ficheiros root ativo num disco que já veio particionado. Isso representa um risco real sem qualquer benefício. Um ficheiro é criado e removido com comandos comuns. Também pode alterar o tamanho mais tarde sem tocar na tabela de partições.
A velocidade não é o fator decisivo. Em swapon, o kernel lê o mapa de extensões do ficheiro uma vez e, depois, envia as operações de E/S diretamente para o dispositivo de blocos. O sistema de ficheiros não participa em cada operação de paginação para dentro e para fora. No mesmo disco, um ficheiro de swap e uma partição de swap têm o mesmo desempenho.
Há dois limites importantes. Não coloque swap num sistema de ficheiros de rede, como NFS (network file system). No btrfs, o ficheiro deve ter a funcionalidade copy on write desativada e a compressão desligada. Por isso, o btrfs inclui a sua própria ferramenta auxiliar para criar um ficheiro de swap.
Como adicionar um ficheiro de swap no Ubuntu ou Debian
Verifique o que já existe antes de alterar qualquer coisa.
swapon --show
free -h
findmnt -no FSTYPE /Uma saída vazia de swapon --show significa que não existe swap, o que é normal numa imagem cloud acabada de criar. findmnt mostra o tipo do sistema de ficheiros raiz, e isso determina como criar o ficheiro. Em ext4, que é o sistema usado pela maioria das imagens cloud, fallocate é seguro.
sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfilechmod vem antes de mkswap de propósito. Se o ignorar, mkswap informa-o disso: mkswap: /swapfile: insecure permissions 0644, fix with: chmod 0600 /swapfile. Um ficheiro de swap legível por todos expõe a cada utilizador do sistema a memória que outros processos paginaram para o disco. Um mkswap correto confirma depois o tamanho, com uma linha como Setting up swapspace version 1, size = 2 GiB (2147479552 bytes).
Em xfs ou btrfs, o último comando pode falhar com swapon: /swapfile: swapon failed: Invalid argument. No XFS, isso acontece porque fallocate deixa extents não escritos, por isso escreva os bytes diretamente.
sudo dd if=/dev/zero of=/swapfile bs=1M count=2048 status=progressNo btrfs, a causa é o copy-on-write, e o btrfs-progs atual define as flags corretas automaticamente.
sudo btrfs filesystem mkswapfile --size 2g /swapfileEm qualquer dos casos, termine com chmod 600, mkswap quando aplicável, e swapon. Depois, confirme o resultado.
swapon --show
free -hswapon --show deve listar /swapfile com o tipo file e o tamanho que solicitou, e free -h deve mostrar uma linha Swap com quase nada utilizado. Zero de swap utilizado numa configuração nova está correto. O kernel só move páginas para lá quando tem um motivo.
Faça com que a configuração sobreviva a um reboot e teste a entrada imediatamente.
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
sudo swapoff /swapfile
sudo swapon -a
swapon --showswapon -a lê /etc/fstab, por isso uma linha incorreta falha agora, à sua frente. Um erro de sintaxe que nunca testa é um erro que encontra durante um reboot não planeado, quando o sistema volta a arrancar sem o swap que julgava ter.
Para remover o swap mais tarde, execute sudo swapoff /swapfile, elimine a linha do fstab e execute sudo rm /swapfile. swapoff tem primeiro de ler para a RAM todas as páginas paginadas para o disco, por isso pode falhar com swapoff: /swapfile: swapoff failed: Cannot allocate memory num sistema ocupado. Libere alguma memória e tente novamente.
Qual deve ser o tamanho do ficheiro de swap?
O objetivo é manter páginas anónimas inativas. Por isso, o que importa é a quantidade de memória alocada que está realmente inativa, não a quantidade de RAM incluída no plano. A memória inativa não aumenta proporcionalmente ao tamanho do plano. Por isso, o multiplicador diminui à medida que os planos ficam maiores. Esta é a regra usada neste guia.
The data behind this chart
[
{
"label": "1 GB plan",
"swap_gb": 2,
"swap_x_ram": 2
},
{
"label": "2 GB plan",
"swap_gb": 2,
"swap_x_ram": 1
},
{
"label": "4 GB plan",
"swap_gb": 2,
"swap_x_ram": 0.5
},
{
"label": "8 GB plan",
"swap_gb": 4,
"swap_x_ram": 0.5
},
{
"label": "16 GB plan",
"swap_gb": 4,
"swap_x_ram": 0.25
}
]No plano mais pequeno, o ficheiro de swap tem 2 GB, o que corresponde a 2 vezes a RAM. Uma máquina com 1 GB tem pouca margem disponível, por isso um pico pode acionar o OOM killer. No topo da tabela, o ficheiro fica limitado a 4 GB, ou 0.25 vezes a RAM. Paginar essa quantidade de dados num armazenamento partilhado demora o suficiente para deixar o servidor efetivamente indisponível durante a operação. Reduza estes valores se o espaço em disco for limitado, porque o ficheiro ocupa espaço real em disco.
A razão clássica para definir o swap com um tamanho igual ou superior ao da RAM é a hibernação, que grava toda a imagem da memória no swap. Uma VPS não entra em hibernação, por isso essa regra não se aplica ao seu caso.
O que vm.swappiness realmente altera?
vm.swappiness não é uma percentagem da RAM nem um limite. É o custo relativo que o kernel atribui à recuperação de páginas anónimas em comparação com páginas de ficheiros. O valor predefinido é 60. Diminua-o para que o kernel prefira libertar a cache de páginas. Aumente-o para que prefira paginar a memória anónima para a swap.
Isto implica uma troca nos dois sentidos. Em vm.swappiness = 10, uma base de dados mantém mais das suas alocações na memória e paga esse custo ao voltar a ler os ficheiros que acabou de remover da cache. Num servidor cujo trabalho principal é servir ficheiros, essa é a direção errada, porque a cache de páginas é o que faz o trabalho útil.
Definir o valor como 0 não desativa a swap. Diz ao kernel para evitar recuperar páginas anónimas até estar quase sem memória, o que antecipa o OOM killer em vez de o adiar. Se não quiser swap, remova o ficheiro de swap.
sysctl vm.swappiness
printf 'vm.swappiness = 10\n' | sudo tee /etc/sysctl.d/99-swappiness.conf
sudo sysctl --system
sysctl vm.swappinessUm sysctl -w simples permanece ativo apenas até ao próximo reboot e depois deixa silenciosamente de ser aplicado. Por isso, escreva a configuração no ficheiro em /etc/sysctl.d/. Os kernels a partir da versão 5.8 aceitam valores de 0 a 200. Valores acima de 100 só fazem sentido quando a swap é aproximadamente tão rápida como a RAM, o que significa usar zram.
zram: swap que consome CPU em vez de disco
zram é um dispositivo de blocos comprimido que reside na RAM. Use-o como swap e uma página que iria para o disco é comprimida e permanece na memória. Não há E/S de disco nem consumo da quota de disco. O custo é tempo de CPU em cada operação de entrada e saída de páginas, além da RAM que armazena as páginas comprimidas e que deixa de estar disponível para as aplicações.
Os rácios de compressão entre 2:1 e 3:1 são os valores normalmente publicados para páginas anónimas, e o seu valor é apresentado por zramctl nas colunas DATA e COMPR. Faça medições em vez de planear com base no valor típico, porque algumas cargas de trabalho contêm dados que praticamente não comprimem.
sudo apt install zram-toolsDefina ALGO=zstd e PERCENT=25 em /etc/default/zramswap, reinicie o serviço e verifique o resultado.
sudo systemctl restart zramswap
zramctl
swapon --showPERCENT é uma percentagem da RAM total, por isso 25 num sistema com 4 GB reserva até 1 GB para páginas comprimidas. Comece com um valor baixo e aumente-o apenas se zramctl mostrar que o dispositivo está a ficar cheio. A definição PRIORITY no mesmo ficheiro determina qual swap o kernel preenche primeiro: o valor mais alto tem prioridade, e um ficheiro de swap de disco adicionado com swapon simples recebe uma prioridade negativa, por isso o zram é utilizado primeiro e o ficheiro absorve o excedente. swapon --show apresenta ambos na coluna PRIO. Nas distribuições que utilizam systemd-zram-generator em vez de zram-tools, as mesmas definições ficam em /etc/systemd/zram-generator.conf.
zram é adequado para um sistema com capacidade de CPU disponível e pouco espaço livre em disco. É a escolha errada quando a capacidade de CPU já é o recurso em falta, porque o trabalho de compressão compete com a aplicação pela mesma capacidade.
Duas armadilhas da swap que só afetam uma VPS
A primeira armadilha é o disco. Um ficheiro de swap de 2 GB ocupa 2 GB do disco do seu plano assim que o cria, porque o espaço tem de ser alocado antecipadamente. df -h / diminui imediatamente pelo valor total e só recupera quando eliminar o ficheiro. Num plano pequeno, isso representa uma parcela significativa, e um sistema de ficheiros root cheio causa muito mais problemas do que a swap alguma vez resolveu. O ficheiro também é contabilizado na saída de du, algo que vale a pena recordar quando procura espaço e df e du discordam sobre onde foi parar o espaço em disco.
A segunda armadilha é a latência. A E/S da sua swap usa o armazenamento que o host partilha com os outros clientes, e não consegue ver a carga deles a partir da sua instância. Só vê o efeito: uma página que normalmente é carregada rapidamente por vezes demora muito mais tempo, e o processo que espera por ela fica bloqueado até a página chegar. O raciocínio é o mesmo de CPU steal time num host partilhado, aplicado à fila de disco em vez da fila de execução. Meça a latência na sua própria máquina, porque qualquer valor de latência publicado descreve os vizinhos de outra pessoa.
Como saber se o swap está a prejudicar o servidor?
O swap utilizado não é um problema. O tráfego de swap é. Um servidor com várias centenas de megabytes no swap e sem atividade de paginação apenas moveu memória que não é acedida há horas. Esse é o resultado pretendido.
Observe as taxas em vez dos totais.
vmstat 1 5si e so são os kibibytes por segundo transferidos para dentro e para fora do swap. Num servidor saudável, mantêm-se em zero ou perto disso, independentemente do valor indicado na coluna swpd. Um valor so sustentado, com si a aumentar ao mesmo tempo, significa que as páginas estão a ser gravadas e imediatamente lidas de volta. Isto é thrashing.
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
2 3 1048572 38210 4096 61440 912 1180 2210 1290 1402 2890 9 7 12 72 0Esse exemplo mostra um servidor com problemas. O sinal mais claro não está nas colunas do swap. Está em wa, com o valor 72, o que significa que a CPU passou a maior parte do tempo à espera de I/O, e em b, com o valor 3, o que significa que três processos estão bloqueados.
O PSI (pressure stall information) responde à questão de forma mais direta.
cat /proc/pressure/memorysome avg10=8.42 avg60=5.11 avg300=2.03 total=1284729
full avg10=3.10 avg60=1.94 avg300=0.71 total=498210some avg10=8.42 significa que, durante os últimos 10 segundos, pelo menos uma tarefa esteve bloqueada à espera de memória durante 8.42 por cento do tempo. full contabiliza o tempo durante o qual todas as tarefas não inativas estiveram bloqueadas. Por isso, um valor full sustentado representa um impacto mensurável, e não apenas um sinal de aviso. Se o ficheiro não existir, o kernel tem o PSI desativado por predefinição e precisa de psi=1 na linha de comandos do kernel.
Para ver que processos mantêm páginas no swap:
sudo awk '/^Name:/{n=$2} /^VmSwap:/ && $2+0 > 0 {printf "%10d kB %s\n", $2, n}' /proc/[0-9]*/status | sort -rn | headE para saber se o OOM killer já foi acionado:
sudo journalctl -k --grep "Out of memory"Um registo desse tipo aparece como Out of memory: Killed process 2199 (mysqld) total-vm:1275860kB, anon-rss:129252kB, file-rss:0kB, shmem-rss:0kB, UID:114 pgtables:504kB oom_score_adj:0, e o log do serviço no mesmo segundo indica Main process exited, code=killed, status=9/KILL. Se já viu essas linhas num servidor sem swap, adicionar um ficheiro de swap é a tentativa seguinte mais simples e barata.
Quando o swap é a solução errada
O swap dá tempo quando a pressão de memória é temporária ou afeta páginas pouco utilizadas. Não resolve um processo que cresce até terminar, e torna essa falha mais difícil de monitorizar, porque a máquina passa minutos adicionais a fazer paginação em vez de falhar rapidamente e reiniciar.
Limite o processo. Um serviço systemd aceita MemoryMax= e MemorySwapMax= num ficheiro drop-in. É assim que pode limitar a memória e a CPU de um serviço com systemd sem alterar a aplicação. Os contentores têm os mesmos controlos num nível superior. Defini-los é a forma de impedir que um serviço do Compose consuma toda a memória do servidor. Ambos permitem identificar o processo terminado num log que pode consultar, em vez de deixar o kernel escolher a vítima com base numa pontuação.
Faça isto enquanto o servidor é novo e está com pouca carga. Criar o ficheiro de swap e definir um limite de memória demora alguns minutos. Esta tarefa faz parte do trabalho descrito em os primeiros dez minutos num VPS novo.
FAQ
Adicionar swap faz o meu VPS de 1 GB funcionar como um VPS de 2 GB?
Não. A swap é muito mais lenta do que a RAM, e o kernel só move para lá as páginas que considera inativas. O que ela oferece é margem para picos e um local para manter memória que foi alocada, mas nunca mais foi utilizada. Se a carga de trabalho lê e escreve ativamente mais memória do que a máquina tem, a swap transforma uma terminação por falta de memória em paginação constante. O servidor continua ativo, mas responde lentamente demais para ser útil. Nesse caso, adicione RAM ou limite o processo que está a crescer.
De quanta swap precisa um VPS de 1 GB ou 2 GB?
2 GB é suficiente para ambos, e não é necessário continuar a aumentar esse valor com a RAM. A swap armazena páginas anónimas inativas, e a quantidade de memória realmente inativa num servidor não cresce da mesma forma que a RAM total. A regra antiga de usar o dobro da RAM vem da hibernação, que grava toda a imagem da memória no disco. Um VPS nunca hiberna. Dimensionar acima de 4 GB geralmente só proporciona uma falha mais longa e lenta num armazenamento partilhado com outros convidados.
Definir vm.swappiness como 0 é a forma correta de impedir a utilização de swap?
Não. Além disso, essa definição não faz o que o nome sugere. vm.swappiness = 0 não desativa a swap. Ela instrui o kernel a evitar a recuperação de páginas anónimas até estar perto de ficar sem memória, o que torna uma terminação por OOM mais provável, e não menos. Também transfere toda a recuperação para a cache de páginas, por isso as leituras de ficheiros voltam ao disco com mais frequência. Se quiser eliminar completamente a swap, execute sudo swapoff -a e remova a linha correspondente do fstab. Se quiser reduzir a utilização de swap, experimente vm.swappiness = 10 e compare as colunas si e so em vmstat antes e depois.
Devo usar zram em vez de um ficheiro de swap?
Use zram quando tiver capacidade de CPU disponível e pouco espaço livre em disco. Use um ficheiro de swap quando a situação for inversa. A zram comprime as páginas e mantém-nas na RAM. Assim, elimina completamente a E/S de disco, mas tem um custo de CPU em cada operação de entrada e saída de páginas. O espaço que ocupa também é RAM que deixa de estar disponível para as aplicações. Num VPS com uma alocação de CPU reduzida, esse custo recai sobre o recurso que já é escasso. É normal executar ambas: atribua uma prioridade mais elevada à zram com PRIORITY em /etc/default/zramswap e mantenha um ficheiro de swap em disco por baixo dela para o excesso.
Porque é que o OOM killer foi executado quando free mostrou memória disponível?
free apresenta um momento específico, mas uma alocação ocorre instantaneamente. Um processo que peça um bloco grande mais depressa do que a recuperação consegue libertar memória pode ser terminado, mesmo que a média parecesse confortável. Leia o log do kernel com sudo journalctl -k --grep "Out of memory". Ele identifica o processo terminado e o respetivo tamanho residente nesse momento. Verifique também se a terminação foi causada por um limite de cgroup, em vez de falta de memória em toda a máquina. Um contentor ou uma unidade systemd com MemoryMax= definido é terminada ao atingir o seu próprio limite, enquanto o host ainda pode ter memória livre.