Como uso o espaço de troca apenas para emergências?

41

Eu tenho um laptop Debian (Buster) com 8 GB de RAM e 16 GB de swap. Estou executando uma tarefa de execução muito longa. Isso significa que meu laptop foi deixado nos últimos seis dias enquanto o agitava.

Enquanto isso, periodicamente preciso usar meu laptop como laptop. Isso não deve ser um problema; a tarefa de longa execução é vinculada à E / S, trabalhando em um disco rígido USB e não requer muita RAM (<200 MB) ou CPU (<4%).

O problema é que, quando voltar ao meu laptop depois de algumas horas, ele ficará muito lento e poderá levar 30 minutos para voltar ao normal. Isso é tão ruim que os monitores de falha sinalizam seus respectivos aplicativos como congelados (especialmente as janelas do navegador) e as coisas começam a falhar incorretamente.

Olhando no monitor do sistema, dos 2,5 GB usados ​​em torno da metade são trocados para troca. Confirmei que esse é o problema removendo o espaço de troca ( swapoff /dev/sda8). Se eu o deixar sem espaço de troca, ele volta à vida quase instantaneamente, mesmo depois de 24 horas. Com a troca, é praticamente um tijolo nos primeiros cinco minutos, restando apenas seis horas. Confirmei que o uso da memória nunca excede 3 GB, mesmo enquanto estiver ausente.

Eu tentei reduzir o swappiness ( veja também: Wikipedia ) para valores de 10e 0, mas o problema ainda persiste. Parece que após um dia de inatividade, o kernel acredita que a GUI inteira não é mais necessária e a limpa da RAM (a troca para o disco). A longa tarefa é ler uma vasta árvore de arquivos e ler todos os arquivos. Portanto, pode ser que o kernel esteja confuso ao pensar que o cache ajudaria. Mas, com uma única varredura de um HD USB de 2 TB com ~ 1 bilhão de nomes de arquivo, uma GB de RAM extra não ajudará muito o desempenho. Este é um laptop barato com um disco rígido lento. Simplesmente não é possível carregar os dados de volta para a RAM com rapidez suficiente.

Como posso dizer ao Linux para usar apenas o espaço de troca em uma emergência? Eu não quero correr sem troca. Se algo inesperado acontecer, e o sistema operacional precisar de alguns GBs extras de repente, não quero que as tarefas sejam mortas e prefiro começar a usar o swap. Mas, no momento, se eu deixar a troca ativada, meu laptop não poderá ser usado quando eu precisar.

A definição precisa de "emergência" pode ser motivo de debate. Mas, para esclarecer o que quero dizer: uma emergência seria onde o sistema é deixado sem outra opção além de trocar ou eliminar processos.


O que é uma emergência? - Você realmente precisa perguntar? ... Espero que você nunca se encontre em um prédio em chamas!

Não é possível definir tudo o que possa constituir uma emergência nesta questão. Mas, por exemplo, pode ser uma emergência quando o kernel é tão pressionado por memória que começa a interromper os processos com o OOM Killer . Uma emergência NÃO é quando o kernel pensa que pode melhorar o desempenho usando swap.


Edição final: aceitei uma resposta que faz exatamente o que pedi no nível do sistema operacional. Os futuros leitores também devem tomar nota das respostas que oferecem soluções em nível de aplicativo.

Philip Couling
fonte
11
Defina "emergência" e diga algo sobre como isso é diferente de qualquer situação comum em que o swap seria usado.
Kusalananda
4
Eu queria saber se você queria, de alguma forma, definir um tipo especial de "evento de emergência" fora dos limites que permitiria ao kernel usar swap, mas essa troca, caso contrário, não seria usada. AFAIK paginando a memória é algo que é lento e só é feito "em emergências" de qualquer maneira, e a coisa "troca" é a única coisa que você pode usar para ajustar esse comportamento (mas eu não sou usuário do Linux).
Kusalananda
2
Não, isso não está correto. Não é feito apenas em emergências. No mínimo, pensei que minha pergunta deixasse claro que só usei 3 GB de 8 GB ... Isso dificilmente é uma emergência, mas o kernel está trocando de qualquer maneira. Eu sugiro que você leia sobre swappiness e tópicos circundantes. Há muita discussão sobre as várias razões para a troca. É plausível que eu esteja pedindo um conceito que não exista no kernel, mas minhas razões para solicitá-lo são razoavelmente bem justificadas ..
Philip Couling
4
Reconheço que o conselho sempre foi "nunca executado sem troca". Mas os tamanhos de memória aumentaram as velocidades de leitura / gravação do disco rígido (HDD e não SSD), o que significa que a troca é cada vez mais uma má idéia. Parece que alguns acreditam que a troca de 8 GB de RAM + 8 GB realizará uma troca de 16 GB de RAM + 0. Se isso realmente acontecer, algo está muito errado com o kernel do Linux.
Philip Couling
7
@ Phillip Couling: Não, o ponto é que a troca de 16 GB de RAM + 16 GB terá um desempenho superior a 16 GB e 0 de troca - especialmente quando o seu código precisar de 17 GB de memória :-)
jamesqf

Respostas:

11

Ter uma troca tão grande hoje em dia costuma ser uma má idéia. Quando o sistema operacional trocou apenas alguns GB de memória para troca, seu sistema já estava rastreado até a morte (como o que você viu)

É melhor usar zramcom uma pequena partição de troca de backup . Muitos sistemas operacionais, como ChromeOS, Android e várias distribuições Linux, habilitam o zram há anos, especialmente para sistemas com menos RAM. É muito mais rápido que trocar no disco rígido e você pode sentir claramente a capacidade de resposta do sistema nesse caso. Menos em um SSD, mas de acordo com os resultados de benchmark aqui , ainda parece mais rápido, mesmo com o algoritmo lzo padrão. Você pode mudar para lz4 para obter um desempenho ainda melhor com um pouco menos de taxa de compactação. Sua velocidade de decodificação é quase 5 vezes mais rápida que o lzo, com base no benchmark oficial

Há também zswapembora eu nunca tenha usado. Provavelmente vale a pena tentar e comparar qual é o melhor para seus casos de uso

Depois disso, outra sugestão é reduzir a prioridade desses processos vinculados à IO e possivelmente deixar um terminal em execução com prioridade mais alta para que você possa executar comandos imediatamente, mesmo quando o sistema estiver com uma carga alta

Leitura adicional

phuclv
fonte
Apenas para que eu entenda, você está dizendo que eu posso criar um zramdispositivo de bloco, usá-lo como swap, com uma prioridade mais baixa como a partição HDD?
Philip Couling
@PhilipCouling Se você estiver usando o HDD, sim, definitivamente você deve usar um zram ou soluções semelhantes. A prioridade da troca deve ser menor que o zram, para que o Linux tente usar o zram primeiro e depois considere a troca. Se você usa o Ubuntu, o pacote zram-config já cuida das configurações de prioridade para você
phuclv
3
Estou aceitando esta resposta porque parece fazer exatamente o que pedi. Se eu ainda tiver meu swap de 16 GB ativado com prioridade reduzida, o kernel o usará somente quando o zswap estiver esgotado. IE: "em caso de emergência". Note que no debian-buster é muito fácil de configurar, simplesmente instalando o zram-tools.
Philip Couling
25

Uma correção é garantir que o controlador de memória cgroup esteja ativado (acho que é por padrão mesmo nos kernels semi-recentes, caso contrário, você precisará adicionar cgroup_enable=memoryà linha de comando do kernel). Em seguida, você pode executar sua tarefa intensiva de E / S em um cgroup com um limite de memória, o que também limita a quantidade de cache que pode consumir.

Se você estiver usando o systemd, poderá definir +MemoryAccounting=yese MemoryHigh/ MemoryMaxou MemoryLimit(depende de se estiver usando o cgroup v1 ou v2) na unidade ou uma fatia que o contenha. Se for uma fatia, você pode usar systemd-runpara executar o programa na fatia.

Exemplo completo de um dos meus sistemas para executar o Firefox com um limite de memória. Observe que isso usa o cgroups v2 e é configurado como meu usuário, não como root (uma das vantagens da v2 sobre a v1 é que delegar isso para não-root é seguro, então o systemd faz isso).

$ systemctl --user cat mozilla.slice 
# /home/anthony/.config/systemd/user/mozilla.slice
[Unit]
Description=Slice for Mozilla apps
Before=slices.target

[Slice]
MemoryAccounting=yes
MemoryHigh=5G
MemoryMax=6G

$ systemd-run --user --slice mozilla.slice --scope -- /usr/bin/firefox &
$ systemd-run --user --slice mozilla.slice --scope -- /usr/bin/thunderbird &

Descobri que para que o usuário funcionasse, precisava usar uma fatia. O sistema um funciona apenas colocando as opções no arquivo de serviço (ou usando systemctl set-propertyo serviço).

Aqui está um exemplo de serviço (usando o cgroup v1), observe as duas últimas linhas. Isso faz parte da instância do sistema (pid = 1).

[Unit]
Description=mount S3QL filesystem
Requires=network-online.target
After=network-online.target

[Install]
WantedBy=multi-user.target

[Service]
Type=forking
User=s3ql-user
Group=s3ql-user
LimitNOFILE=20000
ExecStartPre=+/bin/sh -c 'printf "S3QL_CACHE_SIZE=%%i\n" $(stat -c "%%a*%%S*.90/1024" -f /srv/s3ql-cache/ | bc) > /run/local-s3ql-env'
ExecStartPre=/usr/bin/fsck.s3ql  --cachedir /srv/s3ql-cache/fs1 --authfile /etc/s3ql-authinfo  --log none «REDACTED»
EnvironmentFile=-/run/local-s3ql-env
ExecStart=/usr/bin/mount.s3ql --keep-cache --cachedir /srv/s3ql-cache/fs1 --authfile /etc/s3ql-authinfo --cachesize ${S3QL_CACHE_SIZE} --threads 4
ExecStop=/usr/bin/umount.s3ql /mnt/S3QL/
TimeoutStopSec=2m
MemoryAccounting=yes
MemoryLimit=1G

A documentação está em systemd.resource-control(5).

derobert
fonte
11
Você não pode fazer algo comparável e portátil usando apenas ulimit?
Old Pro
11
@ OldPro não é realmente. Primeiro, não há um limite para o AFAIK no uso total de memória, incluindo o cache da página (que é o uso que está se tornando excessivo aqui). Segundo, o ulimit de memória é por processo, os cgroups funcionam mesmo que a tarefa de longa duração seja bifurcada.
derobert 10/02
Eu pensei que a razão pela qual a contabilidade de memória é ativada por padrão em sistemas mais recentes é devido a uma alteração na systemdversão 238 .
sourcejedi 11/02
11
@sourcejedi que é relativamente recente. Quando o controlador de memória foi introduzido pela primeira vez, apenas tê-lo disponível (nem mesmo em uso) tinha um custo de desempenho grande o suficiente para que algumas distribuições pelo menos o desativassem por padrão e você tivesse que passar o argumento da linha de comando do kernel para ativá-lo. Os problemas de desempenho foram corrigidos, e isso mudou e, mais recentemente, o systemd também o ativa por padrão.
derobert 11/02
14

Parece que após um dia de inatividade, o kernel acredita que a GUI inteira não é mais necessária e a limpa da RAM (a troca para o disco).

O kernel está acreditando no The Right Thing ™ . Por que ele manteria 1 memória não utilizada na RAM e a desperdiçaria essencialmente em vez de usá-la como cache ou algo assim?

Eu não acho que o kernel do Linux esteja trocando páginas de forma gratuita ou antecipada; portanto, se o fizer, deve ser para armazenar outra coisa na RAM, melhorando assim o desempenho da sua tarefa de longa duração, ou pelo menos com esse objetivo.

Se você souber quando precisará reutilizar seu laptop com antecedência, poderá usar o atcomando (ou crontab) para agendar uma limpeza de troca ( swapoff -a;swapon -a).

Como a limpeza da troca pode ser um exagero e até acionar o killer do OOM se, por algum motivo, nem tudo couber na RAM, você pode simplesmente "desapertar" 2 tudo relacionado aos aplicativos em execução que você deseja reviver.

Uma maneira de fazer isso seria anexar um depurador como gdba cada um dos processos afetados e disparar uma geração de dump principal:

# gdb -p <pid>
...
generate-core-dump /dev/null
...
quit

Conforme você escreveu, seu aplicativo de execução demorada não está reutilizando os dados que lê após a passagem inicial; portanto, você está em um caso específico em que o cache de longo prazo não é útil. Ignorar o cache usando E / S direta, como sugerido por Will Crawford, deve ser uma boa solução alternativa.

Como alternativa, você pode apenas limpar regularmente o cache de arquivos ecoando 1ou 3no /proc/sys/vm/drop_cachespseudo-arquivo antes que o sistema operacional pense que é uma boa idéia trocar os aplicativos e o ambiente da GUI.

Consulte Como você esvazia os buffers e o cache em um sistema Linux? para detalhes.

1 Não utilizado no sentido: não é mais usado ativamente desde um período significativo de tempo, a memória ainda sendo relevante para seus proprietários.
2 Coloque novamente as páginas de RAM armazenadas na área de troca.

jlliagre
fonte
2
Obrigado pelo pensamento sobre possíveis causas. Eu adicionei um pouco à pergunta, pois ela pode ser relevante. Gostaria de saber se existe uma maneira de diminuir a prioridade do armazenamento em cache na própria memória do aplicativo.
Philip Couling
5
"Não acho que o kernel do Linux esteja trocando páginas de forma gratuita ou antecipada; portanto, se o fizer, deve ser para armazenar algo mais na RAM, melhorando assim o desempenho". - Acho que essa redação é um pouco ambígua. O kernel definitivamente escreverá páginas para trocar, sempre que houver chance (por exemplo, houver pouca E / S de disco). No entanto, não os removerá da RAM. Dessa forma, você tem o melhor dos dois mundos: se você precisar dessas páginas rapidamente novamente, elas já estarão na RAM e não haverá nada a fazer. Se surgir uma emergência (como diz o OP), você simplesmente precisa liberar essas páginas na RAM, porque
Jörg W Mittag
3
... eles já estão em troca. E é exatamente por isso que você não deseja usar o swap "apenas em emergências", porque durante uma emergência, o sistema já está sob estresse e a última coisa que você deseja é adicionar grandes quantidades de E / S de disco a isso.
Jörg W Mittag
2
A coisa que está causando a troca é provavelmente o longo processo: é acessar arquivos no disco. Esses arquivos na memória serão usados ​​mais recentemente que a memória da GUI.
jpmc26
3
@ JörgWMittag Você tem evidências de que o kernel do Linux é, quando o uso de E / S é baixo, escrevendo preventivamente páginas na área de troca "por precaução", ou seja, sem libertá-las da RAM?
jlliagre
10

O processo que você está executando é algo que você mesmo criou?

Nesse caso, pode valer a pena ajustar seu código para abrir os arquivos usando a O_DIRECTbandeira, que cita a página do manual -

Tente minimizar os efeitos de cache da E / S para e deste arquivo. Em geral, isso prejudicará o desempenho, mas é útil em situações especiais, como quando os aplicativos fazem seu próprio cache. A E / S de arquivo é feita diretamente para / dos buffers de espaço do usuário. O sinalizador O_DIRECT, por si só, faz um esforço para transferir dados de forma síncrona, mas não oferece as garantias do sinalizador O_SYNC de que dados e metadados necessários são transferidos. Para garantir E / S síncrona, o O_SYNC deve ser usado além do O_DIRECT. Veja as NOTAS abaixo para uma discussão mais aprofundada.

Will Crawford
fonte
11
Outro similar (mas provavelmente mais fácil, pois tenho certeza de que o O_DIRECT tem restrições de alinhamento e você reduzirá o desempenho se suas leituras não forem grandes) é uma maneira de dizer ao kernel que você não precisará desses dados novamente, liberando-o do cache de página. (no telefone ou forneceria links, desculpe)
derobert 10/02
11
@derobert Por um lado, o nocachecomando é um truque conveniente para fazer isso. (Ele usa LD_PRELOAD para seqüestrar algumas chamadas libc).
sourcejedi 11/02
6

Aqui está uma idéia que eu ainda não tentei (e me desculpe, não tenho tempo agora para experimentar isso).

Suponha que você crie uma pequena VM com apenas 512 MB de memória para o processo em segundo plano. Não tenho certeza se você deseja que isso troque, faça sua chamada e desative a troca no sistema host.

X Tian
fonte
3

Remova a troca ou diminua-a em cerca de 20% ( pode variar de acordo com os sistemas ), já que os sistemas operacionais não estão mais usando a troca da mesma maneira que usavam nos anos anteriores. Provavelmente responde a algumas de suas perguntas:

-> redhat.com oficial

algumas das informações da Red Hat abaixo,

No passado, alguns fornecedores de aplicativos recomendavam a troca de um tamanho igual à RAM, ou mesmo o dobro da RAM. Agora vamos imaginar o sistema acima mencionado com 2 GB de RAM e 2 GB de swap. Um banco de dados no sistema foi configurado por engano para um sistema com 5 GB de RAM. Depois que a memória física é usada, o swap é usado. Como o disco de troca é muito mais lento que a RAM, o desempenho diminui e ocorre a debulha. Nesse ponto, até mesmo os logins no sistema podem se tornar impossíveis. À medida que mais e mais memória é gravada, eventualmente a memória física e a troca são completamente esgotadas e o assassino do OOM entra em ação, matando um ou mais processos. No nosso caso, há bastante troca disponível, portanto o tempo de baixo desempenho é longo.

e

https://wiki.debian.org/Swap

parte do link Debian acima,

Informações e considerações relacionadas à quantidade de swap a ser usada:

"A quantidade recomendada de espaço de troca tradicionalmente é o dobro da quantidade de memória do sistema. Isso mudou ao longo do tempo para uma vez e meia a memória do sistema, ambas as respostas são linhas de base decentes, mas estão se tornando respostas cada vez menos úteis à pergunta com o passar do tempo. Existem muitas variáveis ​​sobre o seu sistema e o uso pretendido que determinarão a troca de sistema disponível que você deseja ter. "

Você pode tentar:

"Melhor maneira de desativar o swap no linux"


Nota pessoal:


Desde que eu tenho 6 GB de RAM e em todo o meu sistema operacional Linux recentemente. Eu nunca vi nenhuma indicação de uso do Swap. Eu determinei que devo desativá-lo por espaço (alguns gigabytes a mais) e porque, às vezes, diminui o meu sistema.

Tyþë-Ø
fonte
11
No passado, alguns fornecedores de aplicativos recomendavam a troca de um tamanho igual à RAM, ou mesmo o dobro da RAM. Sinto-me muito mais velho vendo isso, de alguma forma ... Embora eu ainda tenha um dos HDDs na barreira ~ 528MB e também 2,5GB, de alguma forma essa citação - bem, é algo de muito tempo atrás ... isso pode explicar por que vi problemas semelhantes há alguns anos. Acredito que usei o sysctl para corrigi-lo, mas não me lembro exatamente qual configuração, se foi nessa noite.
Pryftan