Optimisation io_uring pour ingestion logs haute perf ca patine

Posté par rraynaud le 30/01/2026
RÉSOLU

rraynaud

Membre depuis le 24/01/2025

actif

salut le monde je bosse sur un agent de logs custom en C qui utilise `io_uring` pour pousser des blocs de donnees sur disk. l'idee c'est d'avoir zero copie et max de throughput. mais je vois pas les perfs que j'attendais. le cpu est toujours un peu haut pour l'io. je write des buffers de 4k dans des fichiers.

struct io_uring_sqe *sqe = io_uring_get_sqe(&ring);
io_uring_prep_writev(sqe, fd, &iov, 1, offset);
io_uring_sqe_set_data(sqe, some_data);
io_uring_submit(&ring);

des idees pour gratter de la perf ?

Commentaires

delorme-tristan

Membre depuis le 20/05/2019

actif secouriste

hello t'utilises quelle version du kernel ? io_uring est tres sensible a ca. et t'as pense a `IORING_SETUP_SQPOLL` ? ca evite les transitions kernel/userspace

rraynaud

Membre depuis le 24/01/2025

actif

kernel 5.15. `IORING_SETUP_SQPOLL` j'y ai pense mais je l'ai pas encore activé. je voulais d'abord voir le comportement sans.

thibaut66

Membre depuis le 24/04/2025

actif

`SQPOLL` c'est presque obligatoire pour la haute perf si tu veux eviter les syscalls systematiques. ton thread kernel fait le boulot a ta place. mais attention il doit etre suffisamment 'busy' pour justifier le polling constant.

rraynaud

Membre depuis le 24/01/2025

actif

mon thread d'io est clairement busy c'est un agent de logs on a du flux constant. je vais tenter avec `SQPOLL`.

delorme-tristan

Membre depuis le 20/05/2019

actif secouriste

tu utilises `O_DIRECT` ? pour du log c souvent pertinent ca bypass le page cache et evite le double buffering mais ca demande des buffers alignes et de taille multiple du bloc physique du disk

rraynaud

Membre depuis le 24/01/2025

actif

non pas `O_DIRECT` je pensais que le cache systeme serait benefique pour les petites writes. mais si le CPU est haut ca veut ptete dire des copies memoire.

thibaut66

Membre depuis le 24/04/2025

actif

pour les logs `O_DIRECT` avec des writes de blocs plus grands genre 64k ou 128k c'est souvent mieux. et des buffers alignes comme dit user1. utilise `posix_memalign`.

rraynaud

Membre depuis le 24/01/2025

actif

ok je note `O_DIRECT` et des writes plus grosses. le `posix_memalign` je l'ai deja pour les buffers d'ingestion.

delorme-tristan

Membre depuis le 20/05/2019

actif secouriste

pense aussi a `io_uring_prep_fsync` si tu as besoin de garanties de durabilite. et la capacite de batcher tes IOs. plutot que `io_uring_submit` apres chaque writev, tu peux en cumuler plusieurs et soumettre un coup.

rraynaud

Membre depuis le 24/01/2025

actif

oui je batch deja un peu je soumets toutes les X writes ou tous les Y ms. le `fsync` est important mais je le fais pas sur chaque bloc. c'est trop cher.

thibaut66

Membre depuis le 24/04/2025

actif

avec `io_uring` tu peux aussi utiliser les 'fixed buffers' via `io_uring_register_buffers`. ca evite au kernel de refaire des mappings memoire a chaque operation. encore un gain.

rraynaud

Membre depuis le 24/01/2025

actif

fixed buffers c'est une bonne idee. ca ressemble a `splice` ou `vmsplice` pour eviter les copies userspace-kernel-userspace. je vais regarder ca.

delorme-tristan

Membre depuis le 20/05/2019

actif secouriste

le nombre de SQEs et CQEs dans ta ring est important aussi. si trop petit tu peux avoir des waits. essaie d'avoir un ring size suffisant pour tes pics de charge.

rraynaud

Membre depuis le 24/01/2025

actif

oui la taille de la ring est 4096. je pense que c'est ok. pas vu de completion queue full.

thibaut66

Membre depuis le 24/04/2025

actif

dernier point: quelle est la profondeur de ta queue disk hardware ? nvme a une profondeur enorme. si ton `io_uring` n'envoie pas assez d'ops en parallele tu sous-utilises le hardware.

rraynaud

Membre depuis le 24/01/2025

actif

j'ai du nvme oui. la profondeur c'est pas un souci je crois que ca supporte genre 64k commandes. je dois envoyer plus d'ops en parallele. donc `SQPOLL`, `O_DIRECT`, `fixed_buffers` et des writes plus grosses. ca fait pas mal de pistes.

delorme-tristan

Membre depuis le 20/05/2019

actif secouriste

exactement. y'a de quoi faire. commence par `SQPOLL` c'est le plus simple a implementer et ca donne un bon boost.

rraynaud

Membre depuis le 24/01/2025

actif

d'acc je vais coder ca. merci a vous deux pour les infos precieuses. j'espere voir le CPU enfin se calmer.

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