Como otimizar o desempenho do disco permanente

Como otimizar discos permanentes

Os discos permanentes poderão proporcionar o desempenho descrito no gráfico do tipo de disco se a VM impulsionar um uso suficiente para atingir os limites de desempenho. Após o dimensionamento dos volumes de disco permanente para atender às necessidades de desempenho, o app e o sistema operacional poderão precisar de algum ajuste.

Nas seções a seguir, descrevemos alguns elementos principais que podem ser ajustados para melhorar o desempenho e mostramos como aplicar alguns deles a tipos específicos de cargas de trabalho.

Limitar cargas pesadas de E/S a um período de 50 TB

As cargas pesadas de E/S atingem o desempenho máximo quando limitadas a um período de 50 TB. Os períodos em discos permanentes separados que somam até 50 TB podem ser considerados iguais a um período de 50 TB para fins de desempenho. Um período refere-se a um intervalo contíguo de endereços de blocos lógicos em um único disco.

Desativar a inicialização lenta e ativar comandos DISCARD

Os discos permanentes aceitam comandos DISCARD ou TRIM (em inglês), que permitem aos sistemas operacionais informar aos discos quando os blocos deixam de ser usados. A compatibilidade com DISCARD permite ao SO marcar blocos de disco como não sendo mais necessários sem incorrer no custo de zerar os blocos.

Na maioria dos sistemas operacionais Linux, DISCARD é ativado quando você monta um disco permanente na instância. As instâncias do Windows Server 2012 R2 ativam DISCARD por padrão quando você monta um disco permanente.

Ativar DISCARD pode melhorar o desempenho geral do ambiente de execução, além de acelerar o desempenho do disco quando ele é montado pela primeira vez. A formatação de um volume de disco inteiro pode ser demorada, portanto, a "formatação lenta" é uma prática comum. A desvantagem da formatação lenta é que o custo é frequentemente pago na primeira vez em que o volume é ativado. Ao desativar a inicialização lenta e ativar os comandos DISCARD, é possível formatar e montar rapidamente.

  • Desative a inicialização lenta e ative DISCARD durante a formatação, basta transferir os seguintes parâmetros para mkfs.ext4 (em inglês):

    -E lazy_itable_init=0,lazy_journal_init=0,discard
    

    O parâmetro lazy_journal_init=0 não funciona em instâncias com imagens do CentOS 6 ou do RHEL 6. Para essas instâncias, formate os discos permanentes sem esse parâmetro.

    -E lazy_itable_init=0,discard
    
  • Para ativar os comandos DISCARD na montagem, transmita a seguinte sinalização ao comando desse processo:

    -o discard
    

Os discos permanentes funcionam bem com a opção discard ativada. No entanto, também é possível executar fstrim periodicamente além de, ou em vez de, usar a opção discard. Se você não usar discard, execute fstrim antes de criar um snapshot do disco. O corte do sistema de arquivos permite criar imagens de snapshot menores, o que reduz o custo do armazenamento delas.

Profundidade da fila de E/S

Muitos aplicativos têm configurações que afetam a profundidade da fila de E/S. Profundidades de fila mais altas aumentam as IOPS, mas também podem aumentar a latência. Profundidades de fila menores diminuem a latência por E/S, mas podem resultar em IOPS máximas mais baixas.

Cache de leitura antecipada

Para melhorar o desempenho de E/S, os sistemas operacionais usam técnicas como readahead (em inglês), também chamada de "leitura antecipada", em que mais dados de um arquivo são lidos na memória do que o solicitado, porque provavelmente as leituras posteriores precisarão desses dados. O readahead maior aumenta a capacidade às custas da memória e IOPS. Já o readahead menor aumenta as IOPS às custas da capacidade.

Em sistemas Linux, é possível receber e definir o valor de readahead com o comando blockdev (em inglês):

$ sudo blockdev --getra /dev/[DEVICE_ID]
$ sudo blockdev --setra [VALUE] /dev/[DEVICE_ID]

O valor de readahead é <desired_readahead_bytes> / 512 bytes.

Por exemplo, no caso de um readahead de 8 MB, esse valor equivale a 8.388.608 bytes (8 * 1024 * 1024).

8388608 bytes / 512 bytes = 16384

Defina blockdev como 16384:

$ sudo blockdev --setra 16384 /dev/[DEVICE_ID]

CPUs gratuitas

No disco permanente, a leitura e a gravação requerem ciclos de CPU da VM. Para atingir níveis de IOPS mais altos e consistentes, as CPUs precisam estar livres para processar E/S.

Cargas de trabalho orientadas por IOPS

Bancos de dados SQL ou NoSQL têm padrões de uso de acesso aleatório aos dados. O Google recomenda os seguintes valores para cargas de trabalho orientadas a IOPS:

  • valores de profundidade da fila de E/S de 1 para cada 400 a 800 IOPS até o limite de 64 em grandes volumes;

  • Uma CPU livre para cada 2.000 IOPS de leitura aleatória e outra igual para cada 2.500 IOPS de gravação aleatória.

Os valores mais baixos de readahead geralmente são sugeridos em documentos de práticas recomendadas do MongoDB, do Apache Cassandra (ambos em inglês) e de outros aplicativos de banco de dados.

Cargas de trabalho orientadas à capacidade

Leituras sequenciais rápidas são excelentes para operações de streaming, como um job do Hadoop, e tamanhos de E/S maiores podem aumentar o desempenho do streaming. Para as cargas de trabalho orientadas pela capacidade, recomendamos tamanhos de E/S de 256 KB ou maiores.

Como otimizar o desempenho do disco permanente padrão

Para atingir os níveis máximos de capacidade para discos permanentes padrão de maneira consistente, siga estas práticas recomendadas:

  • Use fluxos de E/S sequenciais paralelos quando possível

    Use a E/S sequencial em discos permanentes padrão, já que o sistema foi projetado para otimizar o desempenho da E/S de acesso sequencial ao disco, semelhante a um disco rígido HDD real.

    A distribuição de E/S entre vários streams sequenciais melhora significativamente o desempenho. Para alcançar o melhor nível de consistência, use oito ou mais streams sequenciais.

  • Use o tamanho grande de E/S

    Os discos permanentes padrão fornecem uma capacidade muito alta no limite. Para garantir que os limites de IOPS e a latência não afetem o desempenho do aplicativo, use um tamanho mínimo de E/S de 256 KB ou um valor maior.

    Use tamanhos de faixa grandes para aplicativos distribuídos do sistema de arquivos. Uma carga de trabalho de E/S aleatória usando tamanhos de faixas grandes (por exemplo, 4 MB ou mais) consegue um ótimo desempenho em discos permanentes padrão devido a quão bem a carga de trabalho imita o acesso a vários discos sequenciais de stream.

  • Certifique-se de fornecer E/S com paralelismo suficiente

    Use a maior profundidade de fila possível para aproveitar o paralelismo do sistema operacional. Fazer isso é especialmente importante para discos permanentes padrão. Dessa forma, é possível alcançar a capacidade no limite sem restringir seu aplicativo por latência de E/S.

Como otimizar o desempenho do disco permanente SSD

No gráfico de desempenho por tipo de disco, veja a descrição do desempenho alcançável e esperado para discos permanentes de estado sólido. Para otimizar os apps e as instâncias de VM visando atingir essas velocidades, use as seguintes práticas recomendadas:

  • Verifique se o app está gerando E/S suficiente

    Se o app estiver gerando menos IOPS do que o limite descrito no gráfico anterior, esse nível de IOPS não será alcançado. Por exemplo, em um disco de 500 GB, o limite de IOPS esperado é de 15.000 IOPS. No entanto, se você gerar menos IOPS ou as operações de E/S forem maiores que 8 KB, não será possível alcançar 15.000 IOPS.

  • Certifique-se de fornecer E/S com paralelismo suficiente

    Use uma profundidade de fila alta o suficiente para aproveitar o paralelismo do SO. Se você fornecer 1.000 IOPS, mas fizer isso de maneira síncrona, com uma profundidade de fila de 1, você alcançará muito menos IOPS do que o limite descrito no gráfico. No mínimo, o app precisa ter uma profundidade de fila de pelo menos 1 para cada 400-800 IOPS.

  • Verifique se há processamento disponível suficiente na instância que está gerando a E/S

    Se a instância de VM tiver pouca CPU, o app não conseguirá gerenciar as IOPS descritas acima. Recomendamos que você tenha uma CPU disponível para cada 2.000–2.500 IOPS de tráfego esperado.

  • Verifique se o app está otimizado para uma localidade razoável de dados temporais em discos grandes

    Se o app acessar dados distribuídos em partes diferentes de um disco em um período curto (centenas de GB por vCPU), você não atingirá o número ideal de IOPS. Para conseguir um melhor desempenho, otimize para a localidade de dados temporais, ponderando fatores como fragmentação do disco e aleatoriedade das partes acessadas do disco.

  • Verifique se o programador de E/S no SO está configurado para atender às suas necessidades específicas

    Em sistemas com base em Linux, defina o programador de E/S como noop para alcançar o maior número de IOPS em dispositivos com SSD.

Analisar as métricas de desempenho do disco permanente

Faça isso no Cloud Monitoring, a solução de monitoramento integrada do Google Cloud.

Várias dessas métricas são úteis para entender se e quando seus discos estão sendo limitados. O objetivo da limitação é facilitar a E/S de burst. Com a limitação, as E/Ss de burst podem ser espalhadas por um período de tempo para que os limites de desempenho do seu disco possam ser alcançados, mas não excedidos em um determinado instante.

Para saber mais, consulte Como analisar métricas de desempenho de disco permanente.

Comparativo do desempenho do disco permanente

Para comparar o desempenho do disco permanente, use FIO em vez de outras ferramentas de comparativo de disco, como dd. Por padrão, dd usa uma profundidade de fila de E/S muito baixa. Portanto, é difícil garantir que o comparativo de mercado esteja gerando um número suficiente de E/S e bytes para testar com precisão o desempenho do disco.

Além disso, os dispositivos especiais usados com dd geralmente são muito lentos e não refletem com precisão o desempenho do disco permanente. Em geral, evite usar dispositivos especiais como /dev/urandom, /dev/random e /dev/zero nos comparativos de mercado de desempenho do disco permanente.

Para medir IOPS e capacidade de um disco em uso em uma instância em execução, compare o sistema de arquivos com a configuração pretendida. Use essa opção para testar uma carga de trabalho realista sem perder o conteúdo do disco existente. Quando você compara o sistema de arquivos em um disco existente, há muitos fatores específicos para seu ambiente de desenvolvimento que podem afetar os resultados do comparativo de mercado, e talvez você não atinja os limites de desempenho do disco.

Para medir o desempenho bruto de um disco permanente, faça comparações diretas com o dispositivo em bloco. Use essa opção para comparar o desempenho do disco bruto com os limites de desempenho do disco.

Os comandos a seguir funcionam com sistemas operacionais Debian ou Ubuntu com o gerenciador de pacotes apt.

Comparativo de IOPS e capacidade de um disco em uma instância em execução

Se você quiser medir as IOPS e a capacidade de uma carga de trabalho realista em um disco ativo em uma instância em execução sem perder o conteúdo do disco, compare-o com um novo diretório no sistema de arquivos atual.

  1. Conecte-se à instância.

  2. Instale as dependências:

    sudo apt update
    sudo apt install -y fio
    
  3. No terminal, liste os discos anexados à VM e encontre o disco que você quer testar. Se o disco permanente ainda não estiver formatado, formate e ative o disco.

    sudo lsblk
    
    NAME   MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
    sda      8:0    0   10G  0 disk
    └─sda1   8:1    0   10G  0 part /
    sdb      8:32   0  2.5T  0 disk /mnt/disks/mnt_dir
    

    Neste exemplo, testamos um disco permanente SSD de 2.500 GB com o código do dispositivo sdb.

  4. Crie um novo diretório, fiotest, no disco. Neste exemplo, o disco é ativado em /mnt/disks/mnt_dir:

    TEST_DIR=/mnt/disks/mnt_dir/fiotest
    sudo mkdir -p $TEST_DIR
    
  5. Teste a capacidade de gravação realizando gravações sequenciais com vários streams paralelos (8+), usando um tamanho de bloco de E/S de 1 MB e uma profundidade de E/S de pelo menos 64:

    sudo fio --name=write_throughput --directory=$TEST_DIR --numjobs=8 \
    --size=10G --time_based --runtime=60s --ramp_time=2s --ioengine=libaio \
    --direct=1 --verify=0 --bs=1M --iodepth=64 --rw=write \
    --group_reporting=1
    
  6. Teste as IOPS de gravação executando gravações sequenciais, usando um tamanho de bloco de E/S de 4 KB e uma profundidade de E/S de pelo menos 64:

    sudo fio --name=write_iops --directory=$TEST_DIR --size=10G \
    --time_based --runtime=60s --ramp_time=2s --ioengine=libaio --direct=1 \
    --verify=0 --bs=4K --iodepth=64 --rw=randwrite --group_reporting=1
    
  7. Teste a capacidade de leitura executando gravações sequenciais com vários streams paralelos (8+), usando um tamanho de bloco de E/S de 1 MB e uma profundidade de E/S de pelo menos 64:

    sudo fio --name=read_throughput --directory=$TEST_DIR --numjobs=8 \
    --size=10G --time_based --runtime=60s --ramp_time=2s --ioengine=libaio \
    --direct=1 --verify=0 --bs=1M --iodepth=64 --rw=read \
    --group_reporting=1
    
  8. Teste as IOPS de leitura usando um tamanho de bloco de E/S de 4 KB e uma profundidade de E/S de pelo menos 64:

    sudo fio --name=read_iops --directory=$TEST_DIR --size=10G \
    --time_based --runtime=60s --ramp_time=2s --ioengine=libaio --direct=1 \
    --verify=0 --bs=4K --iodepth=64 --rw=randread --group_reporting=1
    
  9. Limpar:

    sudo rm $TEST_DIR/write* $TEST_DIR/read*
    

Comparativo do desempenho do disco permanente bruto

Se você quiser medir o desempenho de discos permanentes sozinhos fora do ambiente de desenvolvimento, teste o desempenho de leitura e gravação de um dispositivo de bloco em um disco permanente descartável e VM.

Os comandos a seguir pressupõem um disco permanente SSD de 2.500 GB anexado à VM. Se o tamanho do dispositivo for diferente, modifique o valor do argumento --filesize. Esse tamanho de disco é necessário para alcançar os limites de capacidade da VM de 32 vCPUs. Para mais informações, consulte Desempenho do armazenamento em blocos.

  1. Conecte-se à instância.

  2. Instale as dependências:

    sudo apt update
    sudo apt install -y fio
    
  3. Preencha o disco com dados diferentes de zero. As leituras de disco permanente em blocos vazios têm um perfil de latência diferente dos que contêm dados. Recomendamos que você preencha o disco antes de executar qualquer comparação de latência de leitura.

    # Running this command causes data loss on the second device.
    # We strongly recommend using a throwaway VM and disk.
    sudo fio --name=fill_disk \
      --filename=/dev/sdb --filesize=2500G \
      --ioengine=libaio --direct=1 --verify=0 --randrepeat=0 \
      --bs=128K --iodepth=64 --rw=randwrite
    
  4. Teste a largura de banda de gravação usando gravações sequenciais com vários streams paralelos (mais de oito). Eles precisam ter 1 MB como tamanho de E/S e uma profundidade de E/S igual ou superior a 64.

    # Running this command causes data loss on the second device.
    # We strongly recommend using a throwaway VM and disk.
    sudo fio --name=write_bandwidth_test \
      --filename=/dev/sdb --filesize=2500G \
      --time_based --ramp_time=2s --runtime=1m \
      --ioengine=libaio --direct=1 --verify=0 --randrepeat=0 \
      --bs=1M --iodepth=64 --rw=write --numjobs=8 --offset_increment=100G
    
  5. Teste as IOPS de gravação. Para alcançar o limite de IOPS do DP, é importante manter uma fila profunda de E/S. Por exemplo, quando a latência de gravação for de 1 milissegundo, a VM poderá ter no máximo 1.000 IOPS para cada E/S em execução. Para alcançar 15.000 IOPS de gravação, a VM terá que manter pelo menos 15 E/S em execução. Se o disco e a VM conseguirem 30.000 IOPS de gravação, o número de E/Ss em execução precisará ser de pelo menos 30 E/S. Quando o tamanho da E/S for maior do que 4 KB, a VM poderá alcançar o limite de largura de banda antes de alcançar o de IOPS.

    # Running this command causes data loss on the second device.
    # We strongly recommend using a throwaway VM and disk.
    sudo fio --name=write_iops_test \
      --filename=/dev/sdb --filesize=2500G \
      --time_based --ramp_time=2s --runtime=1m \
      --ioengine=libaio --direct=1 --verify=0 --randrepeat=0 \
      --bs=4K --iodepth=256 --rw=randwrite
    
  6. Teste a latência de gravação. Durante o teste da latência de E/S, é importante que a VM não alcance o limite de largura de banda ou de IOPS. Caso contrário, a latência de E/S real do disco permanente não será refletida. Por exemplo, se o limite de IOPS for alcançado em uma profundidade de E/S de 30, e o comando fio tiver o dobro disso, o total de IOPS permanecerá igual, e a latência de E/S relatada dobrará.

    # Running this command causes data loss on the second device.
    # We strongly recommend using a throwaway VM and disk.
    sudo fio --name=write_latency_test \
      --filename=/dev/sdb --filesize=2500G \
      --time_based --ramp_time=2s --runtime=1m \
      --ioengine=libaio --direct=1 --verify=0 --randrepeat=0 \
      --bs=4K --iodepth=4 --rw=randwrite
    
  7. Teste a largura de banda de leitura realizando leituras sequenciais com vários streams paralelos (mais de oito), em que 1 MB é o tamanho de E/S, e com uma profundidade de E/S igual ou superior a 64.

    sudo fio --name=read_bandwidth_test \
      --filename=/dev/sdb --filesize=2500G \
      --time_based --ramp_time=2s --runtime=1m \
      --ioengine=libaio --direct=1 --verify=0 --randrepeat=0 \
      --bs=1M --iodepth=64 --rw=read --numjobs=8 --offset_increment=100G
    
  8. Teste as IOPS de leitura. Para alcançar o limite de IOPS do DP, é importante manter uma fila profunda de E/S. Por exemplo, se o tamanho de E/S for maior do que 4 KB, a VM poderá alcançar o limite de largura de banda antes de alcançar o de IOPS. Para alcançar o máximo de 100 mil IOPS de leitura, especifique --iodepth=256 para este teste.

    sudo fio --name=read_iops_test \
      --filename=/dev/sdb --filesize=2500G \
      --time_based --ramp_time=2s --runtime=1m \
      --ioengine=libaio --direct=1 --verify=0 --randrepeat=0 \
      --bs=4K --iodepth=256 --rw=randread
    
  9. Teste a latência de leitura. É importante preencher o disco com dados para receber uma medição de latência realista. É importante que a VM não atinja os limites de IOPS ou de capacidade durante este teste, porque após o disco permanente atingir o limite de saturação, ele retornará as E/Ss recebidas, o que se refletirá como um aumento artificial na latência de E/S.

    sudo fio --name=read_latency_test \
      --filename=/dev/sdb --filesize=2500G \
      --time_based --ramp_time=2s --runtime=1m \
      --ioengine=libaio --direct=1 --verify=0 --randrepeat=0 \
      --bs=4K --iodepth=4 --rw=randread
    
  10. Teste a largura de banda de leitura sequencial.

    sudo fio --name=read_bandwidth_test \
      --filename=/dev/sdb --filesize=2500G \
      --time_based --ramp_time=2s --runtime=1m \
      --ioengine=libaio --direct=1 --verify=0 --randrepeat=0 \
      --numjobs=4 --thread --offset_increment=500G \
      --bs=1M --iodepth=64 --rw=read
    
  11. Teste a largura de banda de gravação sequencial.

    sudo fio --name=write_bandwidth_test \
      --filename=/dev/sdb --filesize=2500G \
      --time_based --ramp_time=2s --runtime=1m \
      --ioengine=libaio --direct=1 --verify=0 --randrepeat=0 \
      --numjobs=4 --thread --offset_increment=500G \
      --bs=1M --iodepth=64 --rw=write
    

A seguir