(2020) Se stai usando un kernel Linux 5.1 o superiore puoi usare io_uring
interfaccia per I/O simile a file e ottenere un eccellente funzionamento asincrono.
Rispetto al libaio
esistente Interfaccia /KAIO, io_uring
presenta i seguenti vantaggi:
- Mantiene il comportamento asincrono quando si esegue l'I/O bufferizzato (e non solo quando si esegue l'I/O diretto)
- Più facile da usare (soprattutto quando si usa il
liburing
libreria di supporto) - Opzionalmente può funzionare in modalità polling (ma avrai bisogno di privilegi più elevati per abilitare questa modalità)
- Riduzione dello spazio di contabilità per I/O
- Riduzione dell'overhead della CPU grazie a un minor numero di cambi di modalità syscall in spazio utente/kernel (un grosso problema di questi tempi a causa dell'impatto delle mitigazioni di spectre/meltdown)
- I descrittori di file e i buffer possono essere preregistrati per risparmiare tempo di mappatura/annullamento della mappatura
- Più veloce (può raggiungere un throughput aggregato più elevato, gli I/O hanno una latenza inferiore)
- "Modalità collegata" può esprimere dipendenze tra I/O (>=kernel 5.3)
- Può funzionare con I/O basato su socket (
recvmsg()
/sendmsg()
sono supportati da>=5.3, vedi i messaggi che menzionano la parola support nella cronologia git di io_uring.c) - Supporta il tentativo di cancellazione dell'I/O in coda (>=5.5)
- Può richiedere l'I/O sempre essere eseguito da un contesto asincrono piuttosto che dall'impostazione predefinita di ricorrere solo al puntare I/O a un contesto asincrono quando il percorso di invio inline attiva il blocco (>=5.6 kernel)
- Crescente supporto per l'esecuzione di operazioni asincrone oltre
read
/write
(ad es.fsync
(>=5.1),fallocate
(>=5.6),splice
(>=5.7) e oltre) - Maggiore slancio di sviluppo
- Non diventa bloccante ogni volta che le stelle non sono perfettamente allineate
Rispetto a POSIX AIO di glibc, io_uring
presenta i seguenti vantaggi:
- Molto più veloce ed efficiente (i vantaggi generali inferiori dall'alto si applicano ancora di più qui)
- L'interfaccia è supportata dal kernel e NON utilizza un pool di thread in spazio utente
- Quando si esegue l'I/O bufferizzato, vengono eseguite meno copie dei dati
- Nessuna lotta con i segnali
- L'AIO POSIX di Glibc non può avere più di un I/O attivo su un singolo descrittore di file mentre
io_uring
sicuramente sì!
Il documento Efficient IO con io_uring va molto più in dettaglio riguardo a io_uring
vantaggi e utilizzo di . Il documento Cosa c'è di nuovo con io_uring descrive le nuove funzionalità aggiunte a io_uring
tra i kernel 5.2 - 5.5, mentre l'articolo The rapid growth of io_uringLWN descrive quali funzionalità erano disponibili in ciascuno dei kernel 5.1 - 5.5 con uno sguardo in avanti a ciò che sarebbe stato in 5.6 (vedi anche l'elenco di articoli io_uring di LWN). C'è anche un IO più veloce attraverso la presentazione video (diapositive) delle ricette del kernel io_uring dalla fine del 2019 e la presentazione video (diapositive) delle ricette del kernel io_uring dalla metà del 2022 di io_uring
. autore Jens Axboe. Infine, il tutorial Lord of the io_uring fornisce un'introduzione a io_uring
utilizzo.
Il io_uring
la community può essere raggiunta tramite la mailing list io_uring e gli archivi della mailing list io_uring mostrano il traffico giornaliero all'inizio del 2021.
Re "supporta l'I/O parziale nel senso di recv()
rispetto a read()
":è stata inserita una patch nel kernel 5.3 che ritenterà automaticamente io_uring
letture brevi e un ulteriore commit sono stati inseriti nel kernel 5.4 che modifica il comportamento in modo che si occupi automaticamente solo delle letture brevi quando si lavora con file "normali" su richieste che non hanno impostato REQ_F_NOWAIT
flag (sembra che tu possa richiedere REQ_F_NOWAIT
tramite IOCB_NOWAIT
oppure aprendo il file con O_NONBLOCK
). Quindi puoi ottenere recv()
style- comportamento I/O "breve" da io_uring
anche.
Software/progetti che utilizzano io_uring
Sebbene l'interfaccia sia giovane (la sua prima incarnazione è arrivata a maggio 2019), alcuni software open source utilizzano io_uring
"allo stato brado":
- fio (anch'esso creato da Jens Axboe) ha un backend io_uring ioengine (infatti è stato introdotto in fio-3.13 da febbraio 2019!). La presentazione "Prestazioni di archiviazione migliorate utilizzando la presentazione SNIA della nuova interfaccia I/O del kernel Linux" (diapositive) di due ingegneri Intel afferma che sono stati in grado di ottenere il doppio degli IOPS su un carico di lavoro e meno della metà della latenza media a una profondità di coda di 1 su un altro carico di lavoro quando si confronta il
io_uring
ioengine allibaio
ioengine su un dispositivo Optane. - Il progetto SPDK ha aggiunto il supporto per l'utilizzo di io_uring (!) per l'accesso ai dispositivi a blocchi nella sua versione v19.04 (ma ovviamente questo non è il backend che normalmente utilizzeresti SPDK per scopi diversi dal benchmarking). Più recentemente, sembra che abbiano anche aggiunto il supporto per l'utilizzo con i socket nella v20.04...
- Ceph ha eseguito il commit di un backend io_uring a dicembre 2019 che faceva parte della versione 15.1.0. L'autore del commit ha pubblicato un commento su github che mostra che alcuni backend io_uring hanno alcuni vantaggi e svantaggi rispetto al backend libaio (in termini di IOPS, larghezza di banda e latenza) a seconda del carico di lavoro.
- RocksDB ha commesso un
io_uring
backend per MultiRead nel dicembre 2019 e faceva parte della sua versione 6.7.3. Jens dichiaraio_uring
ha contribuito a ridurre drasticamente la latenza. - libev ha rilasciato la 4.31 con un
io_uring
iniziale backend nel dicembre 2019. Mentre alcuni dei punti originali dell'autore sono stati affrontati nei kernel più recenti, al momento della stesura (metà 2021) l'autore di libev ha alcune parole scelte suio_uring
e sta adottando un approccio attendista prima di implementare ulteriori miglioramenti. - QEMU ha eseguito il commit di un backend io_uring nel gennaio 2020 e faceva parte del rilascio QEMU 5.0. Nella presentazione PDF "io_uring in QEMU:high-performance disk IO for Linux" Julia Suvorova mostra il
io_uring
back-end con prestazioni superiori athreads
eaio
backend su un carico di lavoro di 16K blocchi casuali. - Samba ha unito un
io_uring
Backend VFS nel febbraio 2020 e faceva parte della versione Samba 4.12. Nel "backend Linux io_uring VFS". Thread della mailing list di Samba, Stefan Metzmacher (l'autore del commit) dice ilio_uring
module è stato in grado di spingere circa il 19% in più di throughput (rispetto ad alcuni backend non specificati) in un test sintetico. Puoi anche leggere la presentazione PDF "Async VFS Future" di Stefan per alcune delle motivazioni alla base dei cambiamenti. - Il libunifex C++ sperimentale di Facebook lo usa (ma ti servirà anche un kernel 5.6+)
- La gente della ruggine ha scritto involucri per creare
io_uring
più accessibile alla ruggine pura. rio è una libreria di cui si è parlato un po' e l'autore afferma di aver ottenuto un throughput più elevato rispetto all'utilizzo di chiamate di sincronizzazione racchiuse in thread. L'autore ha tenuto una presentazione del suo database e della sua libreria al FOSDEM 2020 che includeva una sezione che esaltava le virtù diio_uring
. - La libreria di ruggine Glommio utilizza esclusivamente
io_uring
. L'autore (Glauber Costa) ha pubblicato un documento intitolato L'archiviazione moderna è molto veloce. Sono le API che sono pessime, dimostrando che con un'attenta messa a punto Glommio potrebbe ottenere prestazioni 2,5 volte superiori rispetto al normale (non-io_uring
) durante l'esecuzione di I/O sequenziali su un dispositivo Optane. - Gluster ha unito un io_uring posix xlator nell'ottobre 2020 e faceva parte della versione Gluster 9.0. L'autore del commit afferma che le prestazioni "non erano peggiori delle normali chiamate di sistema pwrite/pread".
Software che indaga utilizzando io_uring
- Lo sviluppatore di PostgreSQL Andres Freund è stato una delle forze trainanti dietro
io_uring
miglioramenti (ad esempio la soluzione alternativa per ridurre la contesa di inode del filesystem). C'è una presentazione "Asynchronous IO for PostgreSQL" (tieni presente che il video è interrotto fino al segno dei 5 minuti) (PDF) che motiva la necessità di modifiche a PostgreSQL e dimostra alcuni risultati sperimentali. Ha espresso la speranza di ottenere il suoio_uring
opzionale support in PostgreSQL 14 e sembra perfettamente consapevole di cosa funziona e cosa non funziona anche a livello di kernel. Nel dicembre 2020, Andres discute ulteriormente il suo PostgreSQLio_uring
lavoro nel thread della mailing list pgsql-hackers "Blocking I/O, async I/O and io_uring" e menziona il lavoro in corso può essere visto su https://github.com/anarazel/postgres/tree/aio . - Il progetto Netty ha un repository incubatore che lavora su
io_uring
support che richiede un kernel 5.9 - libuv ha una richiesta pull contro di esso aggiungendo
io_uring
support ma i suoi progressi nel progetto sono stati lenti - SwiftNIO ha aggiunto
io_uring
il supporto per gli eventi (ma non le chiamate di sistema) nell'aprile 2020 e il problema Linux:full io_uring I/O delinea i piani per integrarlo ulteriormente - Il progetto Tokio Rust ha sviluppato un proof of concept tokio-uring
Supporto distribuzione Linux per io_uring
- (Fine 2020) L'ultimo kernel di abilitazione HWE di Ubuntu 18.04 è il 5.4 quindi
io_uring
è possibile utilizzare chiamate di sistema. Questa distribuzione non preconfeziona illiburing
libreria helper ma puoi costruirla da solo. - Il kernel iniziale di Ubuntu 20.04 è 5.4 quindi
io_uring
è possibile utilizzare chiamate di sistema. Come sopra, la distribuzione non preconfezionaliburing
. - Il kernel iniziale di Fedora 32 è 5.6 e ha un pacchetto
liburing
quindiio_uring
è utilizzabile. - SLES 15 SP2 ha un kernel 5.3 quindi
io_uring
è possibile utilizzare chiamate di sistema. Questa distribuzione non preconfeziona illiburing
libreria helper ma puoi costruirla da solo. - (metà 2021) Il kernel predefinito di RHEL 8 non supporta
io_uring
(una versione precedente di questa risposta diceva erroneamente di sì). C'è un articolo della knowledge base di Add io_uring support Red Hat (il contenuto è protetto da un paywall per gli abbonati) che è "in corso". - (metà 2022) Il kernel predefinito di RHEL 9 non supporta
io_uring
. Il kernel è abbastanza nuovo (5.14) ma supportaio_uring
è esplicitamente disabilitato.
Si spera io_uring
introdurrà una migliore storia di I/O asincrona simile a un file per Linux.
(Per aggiungere una sottile patina di credibilità a questa risposta, ad un certo punto in passato Jens Axboe (manutentore del livello di blocco del kernel Linux e inventore di io_uring
) ha pensato che valesse la pena votare questa risposta :-)
La vera risposta, puntata indirettamente da Peter Teoh, si basa su io_setup() e io_submit(). Nello specifico, le funzioni "aio_" indicate da Peter fanno parte dell'emulazione a livello utente di glibc basata sui thread, che non è un'implementazione efficiente. La vera risposta è in:
io_submit(2)
io_setup(2)
io_cancel(2)
io_destroy(2)
io_getevents(2)
Si noti che la pagina man, datata 2012-08, afferma che questa implementazione non è ancora maturata al punto da poter sostituire l'emulazione dello spazio utente glibc:
http://man7.org/linux/man-pages/man7/aio.7.html
questa implementazione non è ancora maturata al punto in cui l'implementazione POSIXAIO può essere completamente reimplementata utilizzando le chiamate kernelsystem.
Quindi, secondo l'ultima documentazione del kernel che riesco a trovare, Linux non ha ancora un modello di I/O asincrono basato sul kernel maturo. E, se presumo che il modello documentato sia effettivamente maturo, non supporta ancora l'I/O parziale nel senso di recv() rispetto a read().