- 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
Postgres, c’est vraiment le top du top.
Commentaires Hacker News
preadv2(..., RWF_NOWAIT). Cela peut être utile pour réduire la latence avecio_method = workerNOWAITdepuis le thread principal et de ne la déporter vers un thread de travail qu’en cas d’échecaio(4)de FreeBSD, et son fonctionnement serait intéressant étant donné qu’il n’a pas les inconvénients deaiosous Linux/glibcio_uring, avec une question sur le fait de savoir si beaucoup d’administrateurs Linux ou de distributions le désactiventVACUUM ANALYZEviapgcronpgbouncer