4 pontos por GN⁺ 2025-05-08 | 2 comentários | Compartilhar no WhatsApp
  • O Postgres 18, atualmente em beta1, introduz suporte a I/O assíncrono (Asynchronous I/O), melhorando bastante especialmente o desempenho de leitura em ambientes de nuvem
  • Com a nova configuração io_method, agora é possível escolher além do modo sync tradicional, os modos worker e io_uring
  • Segundo benchmarks na AWS, com io_uring o desempenho de leitura em disco melhora em até 3 vezes
  • Porém, com a assincronicidade, fica mais difícil interpretar os tempos de I/O na análise de consultas existente (EXPLAIN ANALYZE)
  • É necessário otimizar o desempenho com a nova view de monitoramento (pg_aios) e o parâmetro de tuning effective_io_concurrency

Introdução de I/O assíncrono no Postgres 18

  • Tradicionalmente, o Postgres usa um modelo de I/O bloqueante, esperando cada leitura de disco ser concluída
  • A alta latência em storages baseados em rede (como EBS) causa gargalos em ambientes de nuvem
  • O I/O assíncrono permite processar várias leituras de disco em paralelo, aumentando o uso de CPU e o throughput geral

Trabalho preparatório no Postgres 17: Read Stream API

  • No Postgres 17, a API read_stream foi introduzida para padronizar a abstração das operações de leitura
  • Porém, ela ainda depende do cache de páginas do SO e não é refletida diretamente no shared buffer do próprio Postgres
  • No Postgres 18, passa a ser possível fazer leituras assíncronas diretas, em vez de apenas hints ao kernel

Nova configuração: io_method

  • O Postgres 18 adiciona a configuração io_method ao postgresql.conf, oferecendo as 3 opções a seguir:

io_method = sync

  • Mesmo modo síncrono do Postgres atual
  • Usa um método de solicitação antecipada de leitura baseado em posix_fadvise()

io_method = worker (padrão)

  • Processos worker dedicados a I/O leem dados de forma assíncrona e os entregam ao shared buffer
  • O processo principal pode continuar executando sem interromper a operação de leitura
  • O número padrão de workers é 3, e pode ser ajustado com io_workers

io_method = io_uring

  • Interface de I/O de alto desempenho disponível no kernel Linux 5.1 ou superior
  • Executa leituras assíncronas diretamente por meio de um ring buffer compartilhado com o kernel, sem processos worker
  • Requer kernel, filesystem e configurações mais recentes

Benchmark de desempenho de I/O assíncrono (na AWS)

  • Ambiente de teste:
    • AWS c7i.8xlarge (32 vCPU, 64GB RAM)
    • EBS io2 de 100GB, 20.000 IOPS
    • Execução de SELECT COUNT(*) em uma tabela de 3,5GB

Comparação de desempenho com cold cache:

Versão/configuração Tempo de execução (ms)
Postgres 17 (sync) 15,831
Postgres 18 (sync) 15,071
Postgres 18 (worker) 10,052
Postgres 18 (io_uring) 5,723
  • io_uring entrega ganho de desempenho de 2,8x em relação a sync
  • É especialmente eficaz para reduzir a latência de disco na nuvem

Ajuste de effective_io_concurrency

  • No Postgres 18, esse parâmetro influencia o número interno de requisições assíncronas de read-ahead
  • O valor padrão foi elevado de 1 para 16, e multiplicado por io_combine_limit define o alcance máximo de leitura
  • Em ambientes de nuvem com alta latência, valores maiores podem ser vantajosos, mas é preciso benchmark por workload

Nova ferramenta de monitoramento: pg_aios

  • Em pg_stat_activity, durante operações assíncronas, isso aparece como evento AioIoCompletion, o que dificulta analisar a espera do backend
  • No caso de io_uring, como o kernel processa diretamente, o estado de I/O não fica visível no Postgres
  • Pela view pg_aios, é possível verificar detalhes das requisições assíncronas em andamento
    SELECT * FROM pg_aios;  
    
  • É possível verificar estados como SUBMITTED, COMPLETED_IO e informações sobre os blocos de destino

Atenção: mudança na interpretação das informações de tempo de I/O

  • Os I/O Timings mostrados em EXPLAIN ANALYZE só continuam confiáveis no modo síncrono
  • Ao usar worker ou io_uring com assincronicidade, a interpretação das informações de tempo fica distorcida por processamento paralelo e distribuição entre workers
  • Para avaliar o esforço real de I/O, recomenda-se usar a contagem de buffers shared read e o pg_aios

Conclusão

  • O Postgres 18 traz ganhos reais de desempenho para workloads focadas em leitura
  • Especialmente ao usar discos de alta latência em ambientes de nuvem, o benefício pode ser grande
  • Ao mesmo tempo, será necessário reaprender a interpretar métricas, fazer tuning de desempenho e aplicar as configurações corretamente
  • No futuro, o Postgres 19 também deve trazer suporte a escrita assíncrona

2 comentários

 
jujumilk3 2025-05-09

O Postgres é realmente o melhor, incrível.

 
GN⁺ 2025-05-08
Comentários do Hacker News
  • No Linux, é possível usar preadv2(..., RWF_NOWAIT) para realizar leituras assíncronas a partir do cache de páginas. Isso pode ser útil para reduzir a latência em io_method = worker
    • Foi sugerida uma abordagem em que a thread principal tenta ler com NOWAIT e só faz offload para uma thread de trabalho em caso de falha
  • Houve uma pergunta sobre se esse novo recurso de I/O assíncrono é exclusivo do Linux
    • O Windows tem IOCP e sua própria implementação de IORing, e o macOS oferece suporte a POSIX AIO
    • Foi apontado que não se fala muito sobre a implementação de IORing do Windows
  • Muito trabalho foi feito no aio(4) do FreeBSD, e seria interessante ver como ele funciona, já que não sofre das desvantagens do aio do Linux/glibc
  • Houve uma pergunta sobre semelhanças com o InnoDB do MySQL
  • Há preocupações com os problemas de segurança do io_uring, e foi levantada a questão de se muitos administradores ou distribuições Linux estão desativando esse recurso
  • Houve um comentário dizendo que gostariam de colocar esse recurso em produção com NVMe, e esperam que os principais provedores de nuvem o disponibilizem o quanto antes
    • O ganho de desempenho é muito atraente
  • Foi compartilhada uma experiência de implantação do Postgres em um servidor Hetzner EX-44
    • A relação custo-benefício é excelente, oferecendo capacidade em nível corporativo a baixo custo
    • A segurança foi reforçada com TailScale, eliminando completamente a exposição à rede pública
    • A abordagem de otimização inclui configuração específica para a carga de trabalho com PGTune, monitoramento de desempenho em tempo real com PgHero e tarefas automáticas de VACUUM ANALYZE com pgcron
    • Foi desenvolvido um utilitário CLI personalizado para backups com compressão ZSTD, mantendo alta taxa de compressão e alto throughput, com suporte a upload automático para S3
    • Essa configuração é estável, tem ótimo desempenho e oferece ampla margem para crescimento
  • Houve um comentário bem-humorado sobre os 20k IOPS das instâncias da AWS
    • NVMe de consumo entrega cerca de ~1 milhão+ de IOPS, e isso deve aumentar ainda mais com NVMe PCIe 5.0
    • Há a opinião de que os limites arbitrários da nuvem causam muitos problemas
    • I/O assíncrono é muito útil, mas pode ser menos importante em NVMe com 1 milhão de IOPS
    • Os custos da nuvem são muito altos, e a diferença de desempenho em relação a hardware de consumo barato é grande
  • Houve uma pergunta sobre comparação de desempenho entre Postgres, MariaDB e Percona
    • A pessoa quer saber em quais casos cada banco de dados se destaca
  • Houve uma pergunta sobre quando será lançado um update que permita mais conexões simultâneas
    • Há esperança de que seja possível parar de usar pgbouncer