No Alibaba Cloud Linux 3, a leitura de arquivos NFS por chamadas de sistema como read e copy_file_range pode ser significativamente mais lenta do que no Alibaba Cloud Linux 2 devido à redução do tamanho padrão da janela de read-ahead no kernel 5.10.
Descrição do problema
Sintoma
A leitura de arquivos NFS no Alibaba Cloud Linux 3 pode apresentar desempenho degradado:
Chamadas de sistema como
readecopy_file_rangedemoram muito mais que o normal para ler arquivos NFS grandes.-
O comando
ddlê dados mais lentamente de um ponto de montagem NFS no Alibaba Cloud Linux 3 em comparação ao Alibaba Cloud Linux 2:dd if=<nfs_mntpoint>/<testfile> of=/dev/null bs=1MNotaEsse comando lê o arquivo
testfiledo ponto de montagem NFS para/dev/null. A saída doddexibe os bytes lidos e o tempo decorrido, permitindo calcular a taxa de leitura.
Impacto
Instâncias ECS afetadas:
Imagem: aliyun_3_x64_20G_alibase_20210415.vhd e posteriores.
Kernel: 5.10.23-4.al8.x86_64 e posteriores.
Sistema de arquivos: leitura de arquivos em um sistema de arquivos NFS montado.
Causa
O parâmetro de kernel read_ahead_kb define o tamanho da janela de read-ahead para um dispositivo de bloco. O read-ahead pré-carrega dados previstos na memória para evitar E/S de disco em leituras subsequentes e reduzir a latência.
Antes do kernel 5,4, o read-ahead do NFS baseava-se no parâmetro de montagem
rsize(rsize= tamanho de cada solicitação de leitura NFS). O valor padrão deread_ahead_kbera 15 ×rsize. O Alibaba Cloud Linux 2 (kernel 4.19) usarsize= 1.024 KB por padrão, resultando em umread_ahead_kbde 15.360 KB.Um commit do kernel 5,4 alterou esse comportamento:
read_ahead_kbagora se baseia emVM_READAHEAD_PAGESem vez dersize. O Alibaba Cloud Linux 3 (kernel 5.10) temread_ahead_kb= 128 KB como padrão.
Essa janela de read-ahead significativamente menor reduz o desempenho de leitura no Alibaba Cloud Linux 3. Ajuste o valor para restaurar o desempenho.
Uma janela de read-ahead maior melhora o desempenho de leitura sequencial, mas pode desperdiçar memória em leituras aleatórias. Avalie sua carga de trabalho para determinar o valor ideal de read_ahead_kb.
Solução
Modifique read_ahead_kb usando um dos métodos a seguir.
Use echo (single file system)
-
Verifique o valor atual de read-ahead do dispositivo NFS.
cat /sys/class/bdi/$(mountpoint -d <nfs_mountpoint>)/read_ahead_kbSubstitua
<nfs_mountpoint>pelo caminho do seu ponto de montagem NFS. Executecat /proc/self/mountinfopara encontrá-lo. -
Defina o valor de read-ahead para o dispositivo de armazenamento NFS.
sudo sh -c 'echo <num> > /sys/class/bdi/<major>:<minor>/read_ahead_kb'Substitua:
<num>: tamanho da janela de read-ahead em KB.<major>:<minor>: números do dispositivo do sistema de arquivos NFS. Executesudo mountpoint -d <nfs_mountpoint>para obtê-los.
Exemplo:
sudo sh -c 'echo 15360 > /sys/class/bdi/0:422/read_ahead_kb'NotaPara múltiplas montagens NFS, execute este comando para cada dispositivo.
Use udev rules (multiple file systems)
Adicione uma regra udev para definir automaticamente o parâmetro de read-ahead em todas as montagens NFS atuais e futuras.
O udev é um subsistema Linux que automatiza o gerenciamento de dispositivos ao escutar eventos do kernel e acionar ações quando dispositivos são adicionados.
-
Crie ou edite o arquivo de regras udev em
/etc/udev/rules.d/:sudo vim /etc/udev/rules.d/99-nfs.rules -
Adicione a seguinte regra udev:
Isso defina
read_ahead_kbcomo 15.360 KB. Ajuste conforme necessário.SUBSYSTEM=="bdi", ACTION=="add", PROGRAM="/bin/awk -v bdi=$kernel 'BEGIN{ret=1} {if ($4 == bdi) {ret=0}} END{exit ret}' /proc/fs/nfsfs/volumes", ATTR{read_ahead_kb}="15360" Salve e feche o arquivo.
-
Recarregue as regras udev.
sudo udevadm control --reload -
Acione a regra para dispositivos existentes.
sudo udevadm trigger -c add -s bdi
Edite nfs.conf (nfs-utils 2.3.3-57.0.1.al8.1 or later)
Requer nfs-utils 2.3.3-57.0.1.al8.1 ou posterior. Defina read_ahead_kb em /etc/nfs.conf. Verifique a versão do nfs-utils com o comando: rpm -qa | grep nfs-utils.
-
Abra e edite o arquivo de configuração NFS.
sudo vim /etc/nfs.conf -
Defina os valores de read-ahead e salve o arquivo.
[nfsrahead] nfs=15000 nfs4=16000O parâmetro
nfsaplica-se ao NFSv3, enfs4ao NFSv4. Verifique sua versão com o comando:mount -v | grep nfs. -
Desmonte e remonte os pontos de montagem NFS existentes para aplicar as alterações.
sudo umount <nfs_mountpoint> sudo mount -t nfs -o vers=<NFS protocol version> <NFS server address> <nfs_mountpoint>