Postgres surprod en prod avec io_uring ou kernel params

Posté par bernadette-launay le 04/08/2024
RÉSOLU

bernadette-launay

Membre depuis le 20/03/2019

rédacteur

salut le monde. on a un postgresql 15 qui tourne sur une VM bare metal debian. il gère un gros volume de transactions et parfois sous forte charge les temps de réponse s'envolent. on parle de reqs à 500ms au lieu de 10ms. le CPU est pas saturé le disque est un nvme pcie gen4. je me demande si c'est pas un truc kernel ou les io stack

# postgresql.conf extrait
shared_buffers = 16GB
work_mem = 256MB
wal_buffers = 16MB
min_wal_size = 1GB
max_wal_size = 4GB
checkpoint_timeout = 5min
max_worker_processes = 8
max_parallel_workers = 8
max_connections = 500
random_page_cost = 1.1
seq_page_cost = 1.0
data_checksums = on

j'ai déjà optimisé pas mal le postgresql.conf mais le souci persiste. on est en xfs sur le nvme. quelqu'un a déjà galéré avec ça et trouvé une solution côté kernel genre io_uring ou des sysctl à tuner ?

Commentaires

vbertrand

Membre depuis le 23/07/2019

secouriste

salut ! les 500ms sur du nvme ça sent pas bon du tout. t'as checké les iops de ton nvme pendant les pics ? genre avec fio ou iostat -x 1 ? la queue depth aussi est super importante

bernadette-launay

Membre depuis le 20/03/2019

rédacteur

iostat montre que le util est souvent à 100% mais les r/s et w/s sont pas si élevés que ça. le await par contre monte en flèche. queue depth je suis pas sûr d'où la voir facilement

vbertrand

Membre depuis le 23/07/2019

secouriste

le await qui monte c'est clair ça pue l'i/o bloquante. la queue depth tu peux la voir avec cat /sys/block/nvme0n1/device/queue_depth ou nvme smart-log /dev/nvme0n1. t'as quel scheduler I/O ? cat /sys/block/nvme0n1/queue/scheduler

bernadette-launay

Membre depuis le 20/03/2019

rédacteur

ok pour la queue depth je check. le scheduler est mq-deadline. c'est le défaut pour nvme je crois non ?

vbertrand

Membre depuis le 23/07/2019

secouriste

oui mq-deadline c'est le classique. mais pour du nvme ultra rapide et des grosses bases comme postgres, none (pas de scheduler) ou kyber sont parfois mieux. kyber est plus axé latence. t'as essayé io_uring pour postgres ? par défaut il utilise posix_fadvise et pwritev. io_uring pourrait vraiment réduire la latence

bernadette-launay

Membre depuis le 20/03/2019

rédacteur

io_uring pour postgres je sais que c'est expérimental sur 15. je voulais éviter pour la prod. mais si ça peut régler ça... y'a des flags à mettre au niveau kernel pour io_uring ou c'est juste la lib ?

vbertrand

Membre depuis le 23/07/2019

secouriste

non c'est pas juste la lib. le kernel doit être assez récent genre 5.10+ pour bien en profiter. et postgres faut le compiler avec l'option configure --with-liburing mais faut que la liburing soit dispo. c'est un peu risqué en prod si t'es pas sûr

bernadette-launay

Membre depuis le 20/03/2019

rédacteur

ouais je préfère éviter de recompiler. des sysctl qui pourraient aider alors ? genre des trucs sur le vfs cache ou le dirty ratio ?

vbertrand

Membre depuis le 23/07/2019

secouriste

pour les sysctl oui. regarde vm.dirty_ratio, vm.dirty_background_ratio, vm.swappiness. si swappiness est trop haut ça peut envoyer des pages vitales en swap même avec beaucoup de RAM. et vm.min_free_kbytes peut aider si ton système galère à allouer de la mémoire

bernadette-launay

Membre depuis le 20/03/2019

rédacteur

le swappiness est à 10. dirty_ratio 20, dirty_background_ratio 10. on a 64gb de ram et le kernel ne swap jamais. ça m'étonnerait que ça vienne de là. mais le min_free_kbytes je vais regarder

vbertrand

Membre depuis le 23/07/2019

secouriste

autre piste : NUMA. si ta VM a plusieurs sockets CPU, et que postgres n'est pas bindé sur un seul node NUMA, ça peut engendrer des latences mémoire. t'as vérifié avec numactl --hardware et pg_isready -d 'dbname' pour voir si le process est bien sur le bon node ?

bernadette-launay

Membre depuis le 20/03/2019

rédacteur

ha putain j'avais zappé le NUMA. notre serveur est bi-socket. je vais vérifier ça. si postgres est sur un node et la mémoire sur un autre ça expliquerait bien ces pics

vbertrand

Membre depuis le 23/07/2019

secouriste

exactement. utilise numactl --cpunodebind=0 --membind=0 postgres (ou le bon node) pour démarrer postgres. et vérifie que ton OS ne déplace pas les processus tout le temps. des fois juste ça ça change tout

bernadette-launay

Membre depuis le 20/03/2019

rédacteur

d'acc. je vais tester le numactl pour binder postgres et re-checker le scheduler i/o pour passer à none voir. le min_free_kbytes sera en dernier recours. thx pour les tips ça donne des pistes concrètes

bernadette-launay

Membre depuis le 20/03/2019

rédacteur

j'ai bindé postgres avec numactl et passé le scheduler I/O à none. les pics de latence ont quasi disparu ! on est revenu à 10ms même sous forte charge. merci énormément pour l'aide précieuse !

Laisser une réponse

Vous devez être connecté pour poster un message !

Rejoindre la communauté

Recevoir les derniers articles gratuitement en créant un compte !

S'inscrire