Como o swapoff pode ser tão lento?

77

De alguma forma, aconteceu de trocar 14 GB de memória. Depois de matar o culpado, tenho toneladas de memória livre novamente, então pensei em trazer os dados importantes novamente. Portanto, com 5 GB dos 32 GB usados ​​e 14 GB de espaço de troca usado, executei swapoff -a.... e 4 horas depois, cerca de metade do trabalho foi concluído.

Isso significa menos que 1 MB / s, enquanto eu posso copiar facilmente 200 MB / s. Minha troca é criptografada, mas todas as partições normais também são e, com o aes-ni , não há carga perceptível na CPU (e o preenchimento do espaço de troca levou apenas alguns minutos). Vejo que não há nenhuma razão especial para otimizar swapoff, no entanto, me pergunto como isso poderia ficar tão lento?


Apenas adicionando mais alguns dados: Minha memória principal é de 32 GB e tenho espaço de troca de 32 GB em cada um dos 4 discos rígidos (certamente um exagero, mas quem se importa?). Todo o espaço de troca pode ser (descriptografado e) lido em menos de 5 minutos:

time -p sudo sh -c 'for i in /dev/mapper/cryptswap?; do md5sum $i & done; wait'
014a2b7ef300e11094134785e1d882af  /dev/mapper/cryptswap1
a6d8ef09203c1d8d459109ff93b6627c  /dev/mapper/cryptswap4
05aff81f8d276ddf07cf26619726a405  /dev/mapper/cryptswap3
e7f606449327b9a016e88d46049c0c9a  /dev/mapper/cryptswap2
real 264.27

Ler uma parte de uma partição não pode ser mais lento do que ler tudo. No entanto, ler cerca de 1/10 disso leva cerca de 100 vezes mais.

Observei que, durante as swapoffduas CPUs, a maioria estava ociosa (talvez 10% de um núcleo) e os discos ("medidos" pelos LEDs). Também vi que os espaços de troca foram desativados um após o outro.

maaartinus
fonte
1
Eu me pergunto, o mesmo fenômeno ocorre quando o sistema carrega as páginas trocadas de volta na RAM por si só? Por exemplo, se um sistema foi suspenso no disco e iniciado, tudo foi trocado e está sendo carregado de volta na RAM. Parece ser muito lento para mim também.
Petr Pudlák
Todos os dispositivos de troca são ativados com a mesma prioridade?
Nils
@Petr Pudlák: Suspender no disco é um pouco diferente, ele simplesmente grava o conteúdo da RAM em um espaço livre na área de troca, e isso (e des-suspender) é provavelmente muito mais rápido. Não posso tentar, pois não funciona com a troca criptografada.
maaartinus
@ Nils: Sim, a prioridade é a mesma, assim como o disco e seu particionamento.
Maaartinus 30/08/2012
Isso torna mais estranho. Nesse caso, a troca é distribuída em todos os discos - isso deve ser muito rápido. Será que iostat -d 5apresentam baixa IO nos discos durante swapoff, também?
Nils

Respostas:

53

Primeiro, vamos ver o que você pode esperar do seu disco rígido. Seu disco rígido pode executar 200 MB / s sequencialmente . Quando você considera os tempos de busca, pode ser muito mais lento. Para escolher um exemplo arbitrário, dê uma olhada nas especificações de um dos modernos discos de 3 TB da Seagate, o ST3000DM001 :

  • Taxa máxima de dados sustentados: 210 MB / s

  • Buscar leitura média: <8,5 ms

  • Bytes por setor: 4.096

Se você nunca precisar procurar e se a sua troca estiver próxima à borda do disco, poderá esperar até a taxa máxima = 210 MB / s

Mas se seus dados de troca estiverem totalmente fragmentados, na pior das hipóteses, você precisará procurar todos os setores que lê. Isso significa que você só consegue ler 4 KB a cada 8,5 ms ou 4 KB / 0,0085 = 470 KB / s

Portanto, logo de cara, não é inconcebível que você esteja de fato correndo contra as velocidades do disco rígido.


Dito isto, parece bobagem que swapoffseria tão lenta e teria que ler páginas fora de ordem, especialmente se elas fossem escritas rapidamente (o que implica em ordem). Mas pode ser assim que o kernel funciona. O relatório de bug do Ubuntu # 486666 discute o mesmo problema:

The swap is being removed at speed of 0.5 MB/s, while the
hard drive speed is 60 MB/s;
No other programs are using harddrive a lot, system is not under
high load etc.

Ubuntu 9.10 on quad core.

Swap partition is encrypted.
Top (atop) shows near 100% hard drive usage
  DSK | sdc | busy 88% | read 56 | write 0 | avio 9 ms |
but the device transfer is low (kdesysguard)
  0.4 MiB/s on /dev/sdc reads, and 0 on writes

Uma das respostas foi:

It takes a long time to sort out because it has to rearrange and flush the
memory, as well as go through multiple decrypt cycles, etc. This is quite
normal

O relatório de erro foi fechado sem solução.

O livro de Mel Gorman " Entendendo o Linux Virtual Memory Manager " está um pouco desatualizado, mas concorda que esta é uma operação lenta:

Previsivelmente, a função responsável por desativar uma área é chamada sys_swapoff(). Esta função está principalmente relacionada à atualização do swap_info_struct. A principal tarefa de paginação em cada página paginada-out é de responsabilidade do try_to_unuse()que é extremamente caro.

Há um pouco mais de discussão a partir de 2007 na lista de discussão do Linux-kernel com o assunto " acelerando a troca " - embora as velocidades que eles estão discutindo sejam um pouco mais altas do que você está vendo.


É uma pergunta interessante que provavelmente é geralmente ignorada, uma vez que swapoffraramente é usada. Eu acho que se você realmente queria segui-lo para baixo, o primeiro passo seria tentar assistir seus padrões de uso de disco com mais cuidado (talvez com atop, iostatou até mesmo mais poderosas ferramentas como perfou systemtap). As coisas a procurar podem ser procura excessiva, pequenas operações de E / S, reescrita e movimentação constantes de dados, etc.

Jim Paris
fonte
5
Excelente explicação. Deve-se notar que é possível contornar a maior parte da fragmentação e liberar a maioria das trocas rapidamente fazendo o dump do
Brandon DuPree
Não é apenas tempo de fragmentação / busca. Meu swap está no SSD e as leituras aleatórias são muito rápidas, mas o comando swapoff é muito mais lento do que deveria e minha carga do SSD fica em torno de 1% util. Eu estou suspeitando que há lista andando em algum lugar do kernel ou no swapoff (que usa ~ 90-100% da CPU). Obviamente, se todo o trabalho for realizado seqüencialmente e as buscas do disco forem lentas também, isso poderá aumentar significativamente.
Thomas Guyot-Sionnest
33

Estou enfrentando o mesmo problema com o meu laptop, que tem um SSD, portanto, os horários de busca não devem ser um problema.

Eu encontrei uma explicação alternativa . Aqui está um trecho

Do jeito que funciona agora, o swapoff olha para cada página de memória trocada na partição swap e tenta encontrar todos os programas que a utilizam. Se não conseguir encontrá-los imediatamente, examinará as tabelas de páginas de todos os programas em execução para encontrá-los. Na pior das hipóteses, ele verificará todas as tabelas de páginas para todas as páginas trocadas na partição. Isso mesmo - as mesmas tabelas de páginas são verificadas repetidamente.

Portanto, é um problema do kernel e não qualquer outra coisa.

Nick Craig-Wood
fonte
Não, não é um problema no kernel IMHO. É como swapoffé implementado. Quando o processo é trocado, não demora muito.
precisa saber é o seguinte
15
É um problema com a implementação do swapoff que está no kernel - daí um problema no kernel! Você pode ver se strace swapoffpraticamente tudo o que faz é chamar a swapoffchamada de sistema.
Nick Craig-Wood
1
Eu tenho um servidor com 48GB de RAM (32cores), tinha 6 GB de troca de bugs grátis foi usado 0,7GB. swappiness = 10, tentou torná-lo 0 e também tentou o swapoff para ver o que acontece. O swapoff leva idades, provavelmente 30 minutos, liberando o swap extremamente lento. Eu tenho SSD sob quase nenhuma carga e CPU é semelhante, espero que o processo de troca que leva um CPU 100%.
sorin
1
É um problema de como o swapoff é implementado (no kernel). Houve discussões sobre uma abordagem muito melhor há alguns anos no kernel-dev, mas eles dizem que é um caso de esquina e não querem o esforço para alterá-lo.
precisa saber é o seguinte
7
No servidor com 1 TB de RAM (sim, TB) e troca de 2 GB de swap (requisito bobo da SAP), levou 12 horas para liberar 5% desses 2 GB (com 1 núcleo de CPU em 100%).
precisa saber é o seguinte
22

Sim, o swapoffmecanismo é terrivelmente ineficiente. A solução alternativa é fácil: itere nos processos, em vez das páginas trocadas. Use este script python (eu não sou afiliado):

git clone https://github.com/wiedemannc/deswappify-auto

Observe que o modo de operação daemon é apenas para desktops / laptops que geralmente são hibernados. Eu não o executaria como um daemon em um sistema de servidor - apenas execute-o em primeiro plano, aguarde até que ele relate que ele cuidou de alguns processos, então pare e tente:

swapoff /dev/x

Como a maioria das páginas agora está presente tanto na troca quanto na memória, ela swapofftem muito pouco a fazer e deve ser agora incrivelmente rápida (vi centenas de MB / s).

Seção Histórico adiante

O script python mencionado acima é baseado no restante desta resposta, que por sua vez foi o aprimoramento dessa resposta mais antiga da autoria de jlong . Como o script é muito mais seguro, recomendo apenas tentar o resto da minha resposta como a última linha de defesa :

perl -we 'for(`ps -e -o pid,args`) { if(m/^ *(\d+) *(.{0,40})/) { $pid=$1; $desc=$2; if(open F, "/proc/$pid/smaps") { while(<F>) { if(m/^([0-9a-f]+)-([0-9a-f]+) /si){ $start_adr=$1; $end_adr=$2; }  elsif(m/^Swap:\s*(\d\d+) *kB/s){ print "SSIZE=$1_kB\t gdb --batch --pid $pid -ex \"dump memory /dev/null 0x$start_adr 0x$end_adr\"\t2>&1 >/dev/null |grep -v debug\t### $desc \n" }}}}}' | sort -Vr | head

Este é executado talvez 2 segundos e não fazem nada, apenas lista os 10 principais segmentos de memória (na verdade, ele imprime mais one-liners; sim, eu não amo one-liners, basta examinar os comandos, aceitar o risco, copiar e colar em seu shell; eles realmente lerão do swap).

...Paste the generated one-liners...
swapoff /your/swap    # much faster now

O one-liner principal é seguro (para mim), exceto que lê muito / proc.

Os subcomandos preparados para seu exame manual não são seguros . Cada comando trava um processo durante a leitura de um segmento de memória do swap. Portanto, é inseguro com processos que não toleram nenhuma pausa. As velocidades de transferência que eu vi eram da ordem de 1 gigabyte por minuto. (O script python mencionado acima removeu essa deficiência).

Outro perigo é colocar muita pressão de memória no sistema; portanto, verifique com as free -m

O que isso faz?

for(`ps -e -o pid,args`) {

  if(m/^ *(\d+) *(.{0,40})/) { 
    $pid=$1; 
    $desc=$2; 

    if(open F, "/proc/$pid/smaps") { 

      while(<F>) { 

        if(m/^([0-9a-f]+)-([0-9a-f]+) /si){ 
          $start_adr=$1; 
          $end_adr=$2; 
        } elsif( m/^Swap:\s*(\d\d+) *kB/s ){
          print "SSIZE=$1_kB\t gdb --batch --pid $pid -ex \"dump memory /dev/null 0x$start_adr 0x$end_adr\"\t2>&1 >/dev/null |grep -v debug\t### $desc \n" 
        }
      }
    }
  }
}

A saída desse script perl é uma série de gdbcomandos dump memory (range)que lembram páginas trocadas na memória.

A saída começa com o tamanho, por isso é fácil passá-lo | sort -Vr | headpara obter os 10 maiores segmentos por tamanho (SSIZE). Os -Vestandes para classificar-version-número adequado, mas funciona para o meu propósito. Eu não conseguia descobrir como fazer a classificação numérica funcionar.

kubanczyk
fonte
Você usaria tipo numérica aqui comsort -t = -k 2n
Stéphane Chazelas
9
Parece não haver necessidade de usar o gdb para espiar a memória do processo (pelo menos nos kernels recentes). Pode-se apenas abrir /proc/$pid/mem, procurar e ler diretamente. Aqui está o PoC baseado em grande parte no seu snippet: gist.github.com/WGH-/91260f6d65db88be2c847053c49be5ae Desta forma, o processo não é interrompido, pois o AFAIK não deve causar nenhum perigo.
WGH 20/10
10

Durante a troca, se um slot de troca em uso for detectado, o kernel primeiro troca na página. A função unuse_process () tenta localizar todas as entradas da tabela de páginas que correspondem à página recém-trocada e faz a atualização necessária nas tabelas de páginas. A pesquisa é exaustiva e consome muito tempo: ela visita todos os descritores de memória (de todo o sistema) e examina suas entradas da tabela de páginas uma a uma.

Por favor, consulte a página 724 de "Entendendo a 3a versão do Kernel Linux".

Leslie
fonte