É um buffer de buffer do NFS do Linux?

4

Em uma montagem NFS (opções padrão no RedHat 5.6 com antigo kernel 2.6.18), parece-me que grandes e múltiplas operações de gravação atrasam operações de leitura menores. Por exemplo, fazer um simples ls em um diretório leva segundos (ou minutos) se houver um cp ou dd em execução simultaneamente. O problema é um pouco mitigado porque o Linux armazena os metadados em cache por alguns segundos, mas quando há muitos dados para gravar, a montagem do NFS se torna inutilizável.

No começo, pensei que isso fosse apenas um problema do servidor NFS, mas executando algo assim:

for((i=0; i<60; i++)) do
  strace -f -t -o strace.$i.log time stat /mnt/nfs/data > out.$i.log 2>&1
  sleep 1
  if ((i == 30)); then
    dd if=/dev/zero of=/mnt/nfs/data bs=1M count=1000 &
  fi
done

wait

e um tcpdump em paralelo me diz o seguinte:

1) sempre que o dd começa, o próximo stat que faz um cache perder leva 15s

23261 16:41:24 munmap(0x2ad024d0e000, 4096) = 0
23261 16:41:24 lstat("/mnt/fermat_emctest/data", {st_mode=S_IFREG|0600, st_size=1048576000, ...}) = 0
23261 16:41:40 open("/proc/filesystems", O_RDONLY) = 3

2) o tcpdump mostra que enquanto o dd está em execução e WRITE chamadas são emitidas, nem um único GETATTR é enviado. Como o RPC é assíncrono, eu esperaria ver GETATTR chamadas multiplexadas com WRITE , mas esse não é o caso. Não é o GETATTR que é lento (demora um pouco quando é enviado), é o kernel que o enfileira após todo o WRITE s.

É por isso que o stat demora, porque aguarda o kernel enviar a chamada GETATTR .

Estou certo? Isso parece um problema bufferbloat , o kernel está deixando meu stat com fome porque a fila de operações do lado do cliente para esta montagem (servidor?) Está cheia.

Acho que isso está de alguma forma relacionado à minha outra pergunta Como conseguir múltiplas conexões NFS / TCP para o mesmo servidor? .

Existe uma maneira de ajustar a fila de ops do NFS do kernel?

    
por Benoît 24.04.2014 / 17:04

1 resposta

0

OK, aqui está minha resposta.

Relacionado ao link com o kernel 2.6.18 e 2.6.32 como enviado com o RedHat Não é hora de revalidar isso com novos kernels), em um cliente NFS (opções de montagem v3 / tcp / default), quando um está gravando em um arquivo, o kernel também precisa atualizar os timestamps deste arquivo. Enquanto o arquivo está sendo gravado, se outro processo desejar os metadados desse arquivo (como quando faz um stat neste arquivo ou ls -l em seu diretório pai), esse processo de leitura é atrasado pelo kernel até que a gravação seja terminou.

No nível do NFS, vejo que o kernel emitirá a chamada GETATTR somente depois de tudo (não tenho certeza disso, mas nos meus testes até 5GiB, o tempo stat pareceu corresponder ao dd time) o WRITE . Quanto maior a gravação, maior é a espera.

Com um servidor NFS lento ou um servidor com muita RAM, esse atraso pode ser de minutos. Quando o stat(2) é colocado em suspensão, pode-se monitorar /proc/meminfo para NFS_Unstable ou Writeback , o que mostra a quantidade de dados em vôo.

Não sei por que o kernel faz isso, mas pelo menos agora eu entendo o comportamento. Portanto, não há bufferbloat, mas algumas operações são serializadas.

    
por 26.04.2014 / 12:32

Tags