4 points par GN⁺ 2025-05-08 | 2 commentaires | Partager sur WhatsApp
  • Postgres 18, actuellement en bêta 1, introduit la prise en charge des E/S asynchrones (Asynchronous I/O), avec à la clé une nette amélioration des performances de lecture en environnement cloud
  • Le nouveau paramètre io_method permet de choisir, en plus de la méthode sync traditionnelle, les modes worker et io_uring
  • Selon des benchmarks réalisés sur AWS, l’usage de io_uring permet jusqu’à 3x plus de performances en lecture disque
  • En contrepartie, l’asynchronisme rend plus difficile l’interprétation des timings d’E/S dans l’analyse de requêtes existante (EXPLAIN ANALYZE)
  • Une nouvelle vue de supervision (pg_aios) et des paramètres de tuning comme effective_io_concurrency deviennent nécessaires pour optimiser les performances

Introduction des E/S asynchrones dans Postgres 18

  • Traditionnellement, Postgres utilise un modèle d’E/S bloquantes, en attendant la fin de chaque lecture disque
  • La forte latence des stockages réseau (comme EBS) crée ainsi des goulots d’étranglement en environnement cloud
  • Les E/S asynchrones permettent de traiter plusieurs lectures disque en parallèle, ce qui améliore l’utilisation CPU et le débit global

Le travail préparatoire de Postgres 17 : l’API Read Stream

  • Postgres 17 a introduit l’API read_stream, qui standardise l’abstraction des opérations de lecture
  • Elle repose toutefois encore sur le cache de pages de l’OS et ne s’intègre pas directement au shared buffer de Postgres
  • Avec Postgres 18, il devient possible d’effectuer des lectures asynchrones directes, et non plus de simples hints noyau

Nouveau paramètre : io_method

  • Postgres 18 ajoute le paramètre io_method dans postgresql.conf, avec trois options :

io_method = sync

  • La méthode synchrone classique, identique aux versions précédentes de Postgres
  • Utilise une approche de prélecture basée sur posix_fadvise()

io_method = worker (par défaut)

  • Des processus worker dédiés aux E/S lisent les données de façon asynchrone et les transmettent au shared buffer
  • Le processus principal peut continuer à s’exécuter sans interruption pendant les lectures
  • Le nombre de workers est de 3 par défaut et peut être ajusté via io_workers

io_method = io_uring

  • Interface d’E/S haute performance disponible à partir du noyau Linux 5.1
  • Permet des lectures asynchrones directes via un ring buffer partagé avec le noyau, sans processus worker
  • Nécessite un noyau récent, un système de fichiers compatible et une configuration adaptée

Benchmarks de performance des E/S asynchrones (sur AWS)

  • Environnement de test :
    • AWS c7i.8xlarge (32 vCPU, 64GB RAM)
    • 100GB io2 EBS, 20 000 IOPS
    • Exécution de SELECT COUNT(*) sur une table de 3.5GB

Comparaison des performances avec cache froid :

Version/configuration Temps d’exécution (ms)
Postgres 17 (sync) 15,831
Postgres 18 (sync) 15,071
Postgres 18 (worker) 10,052
Postgres 18 (io_uring) 5,723
  • io_uring offre un gain de performance de 2,8x par rapport à sync
  • Effet particulièrement marqué pour réduire la latence disque dans le cloud

Réglage de effective_io_concurrency

  • Dans Postgres 18, ce paramètre influence le nombre interne de requêtes de read-ahead asynchrones
  • Sa valeur par défaut a été relevée de 1 à 16, et, combinée à io_combine_limit, elle détermine la plage maximale de lecture
  • Dans les environnements cloud à forte latence, une valeur élevée peut être avantageuse, mais des benchmarks selon la charge réelle restent nécessaires

Nouvel outil de supervision : pg_aios

  • Dans pg_stat_activity, les opérations asynchrones apparaissent sous l’événement AioIoCompletion, ce qui complique l’analyse de l’attente des backends
  • Avec io_uring, l’état des E/S n’est pas visible directement dans Postgres, car le noyau les gère lui-même
  • La vue pg_aios permet de consulter les détails des requêtes asynchrones en cours
    SELECT * FROM pg_aios;  
    
  • Il est possible d’y voir des états comme SUBMITTED, COMPLETED_IO, ainsi que les informations sur les blocs ciblés

Point d’attention : changement d’interprétation des timings d’E/S

  • Les I/O Timings affichés jusque-là dans EXPLAIN ANALYZE ne restent fiables qu’en mode synchrone
  • Avec worker ou io_uring, le parallélisme et la répartition sur plusieurs workers faussent l’interprétation de ces timings
  • Pour évaluer l’effort réel d’E/S, il est recommandé de s’appuyer sur le nombre de buffers shared read et sur pg_aios

Conclusion

  • Postgres 18 apporte des gains concrets pour les workloads centrés sur la lecture
  • Les bénéfices sont particulièrement importants avec des disques cloud à forte latence
  • En parallèle, il faut réapprendre à interpréter les métriques, tuner les performances et appliquer les bons réglages
  • Postgres 19 pourrait à l’avenir apporter la prise en charge des écritures asynchrones

2 commentaires

 
jujumilk3 2025-05-09

Postgres, c’est vraiment le top du top.

 
GN⁺ 2025-05-08
Commentaires Hacker News
  • Sous Linux, il est possible d’effectuer des lectures asynchrones depuis le cache de pages avec preadv2(..., RWF_NOWAIT). Cela peut être utile pour réduire la latence avec io_method = worker
    • Il est proposé de tenter la lecture avec NOWAIT depuis le thread principal et de ne la déporter vers un thread de travail qu’en cas d’échec
  • Une question est posée sur le fait de savoir si cette nouvelle fonctionnalité d’E/S asynchrones est réservée à Linux
    • Windows dispose d’IOCP et de sa propre implémentation d’IORing, tandis que macOS prend en charge POSIX AIO
    • Il est souligné qu’on voit peu de mentions de l’implémentation d’IORing sous Windows
  • Beaucoup de travail a été réalisé sur aio(4) de FreeBSD, et son fonctionnement serait intéressant étant donné qu’il n’a pas les inconvénients de aio sous Linux/glibc
  • Une question est posée sur la similarité avec InnoDB de MySQL
  • Des inquiétudes sont exprimées au sujet des problèmes de sécurité d’io_uring, avec une question sur le fait de savoir si beaucoup d’administrateurs Linux ou de distributions le désactivent
  • Un avis indique vouloir utiliser cette fonctionnalité en production sur NVMe, avec l’espoir que les grands fournisseurs cloud la proposent au plus vite
    • Le gain de performance est très attractif
  • Partage d’expérience sur un déploiement de Postgres sur un serveur Hetzner EX-44
    • Le rapport performance/prix est excellent et offre une capacité de niveau entreprise à faible coût
    • La sécurité est renforcée avec TailScale, supprimant totalement l’exposition au réseau public
    • L’approche d’optimisation inclut une configuration adaptée à la charge via PGTune, une surveillance des performances en temps réel avec PgHero, ainsi que des tâches automatiques VACUUM ANALYZE via pgcron
    • Un utilitaire CLI personnalisé a été développé pour les sauvegardes compressées en ZSTD, afin de maintenir un taux de compression élevé et un débit important, avec prise en charge de l’upload automatique vers S3
    • Cette configuration est stable, performante et offre une large marge de croissance
  • Un commentaire amusé concerne les 20k IOPS des instances AWS
    • Les NVMe grand public offrent environ 1 million+ d’IOPS, et cela devrait encore augmenter avec les NVMe PCIe 5.0
    • Il est estimé que les limitations arbitraires du cloud provoquent de nombreux problèmes
    • Les E/S asynchrones sont très utiles, mais elles le seraient moins avec un NVMe à 1 million d’IOPS
    • Les coûts du cloud sont très élevés, avec un écart de performance important par rapport au matériel grand public bon marché
  • Une question est posée sur la comparaison des performances entre Postgres, MariaDB et Percona
    • On se demande dans quels cas chaque base de données excelle
  • Une question est posée sur la date de sortie d’une mise à jour permettant davantage de connexions simultanées
    • Avec l’espoir de pouvoir se passer de pgbouncer