GNU/Linux >> Belajar Linux >  >> Linux

Apakah benar-benar tidak ada blok I/O asinkron di Linux?

(2020) Jika Anda menggunakan kernel Linux 5.1 atau lebih tinggi, Anda dapat menggunakan io_uring antarmuka untuk I/O seperti file dan dapatkan operasi asinkron yang sangat baik.

Dibandingkan dengan libaio yang ada /antarmuka KAIO, io_uring memiliki keunggulan sebagai berikut:

  • Mempertahankan perilaku asinkron saat melakukan buffered I/O (dan tidak hanya saat melakukan I/O langsung)
  • Lebih mudah digunakan (terutama saat menggunakan liburing pustaka pembantu)
  • Secara opsional dapat bekerja dengan cara polling (tetapi Anda memerlukan hak istimewa yang lebih tinggi untuk mengaktifkan mode ini)
  • Lebih sedikit overhead ruang pembukuan per I/O
  • Menurunkan overhead CPU karena lebih sedikit sakelar mode syscall userspace/kernel (masalah besar akhir-akhir ini karena dampak mitigasi momok/meltdown)
  • Deskriptor dan buffer file dapat didaftarkan sebelumnya untuk menghemat waktu pemetaan/pembukaan peta
  • Lebih cepat (dapat mencapai throughput agregat yang lebih tinggi, I/O memiliki latensi lebih rendah)
  • "Mode tertaut" dapat mengekspresikan ketergantungan antara I/O (>=5.3 kernel)
  • Dapat bekerja dengan I/O berbasis soket (recvmsg() /sendmsg() didukung dari>=5.3, lihat pesan yang menyebutkan kata dukungan di riwayat git io_uring.c)
  • Mendukung percobaan pembatalan antrian I/O (>=5.5)
  • Dapat meminta I/O itu selalu dilakukan dari konteks asinkron daripada default hanya jatuh kembali ke punting I/O ke konteks asinkron ketika jalur pengiriman inline memicu pemblokiran (>=5.6 kernel)
  • Meningkatnya dukungan untuk melakukan operasi asinkron di luar read /write (misalnya fsync (>=5.1), fallocate (>=5.6), splice (>=5.7) dan lainnya)
  • Momentum pengembangan yang lebih tinggi
  • Tidak menghalangi setiap kali bintang tidak sejajar dengan sempurna

Dibandingkan dengan POSIX AIO glibc, io_uring memiliki keunggulan sebagai berikut:

  • Banyak lebih cepat dan lebih efisien (manfaat biaya overhead yang lebih rendah dari yang di atas berlaku lebih banyak lagi di sini)
  • Antarmuka didukung kernel dan TIDAK menggunakan kumpulan utas ruang pengguna
  • Lebih sedikit salinan data yang dibuat saat melakukan buffer I/O
  • Tidak perlu bergulat dengan sinyal
  • POSIX AIO Glibc tidak dapat memiliki lebih dari satu I/O dalam penerbangan pada deskriptor file tunggal sedangkan io_uring pasti bisa!

IO Efisien dengan dokumen io_uring menjelaskan lebih detail tentang io_uring manfaat dan kegunaannya. Dokumen What's new with io_uring menjelaskan fitur-fitur baru yang ditambahkan ke io_uring antara kernel 5.2 - 5.5, sementara Pertumbuhan cepat artikel io_uringLWN menjelaskan fitur mana yang tersedia di masing-masing kernel 5.1 - 5.5 dengan pandangan ke depan tentang apa yang akan ada di 5.6 (lihat juga daftar artikel io_uring LWN). Ada juga IO Lebih Cepat melalui presentasi video Resep Kernel io_uring (slide) dari akhir 2019 dan Apa yang baru dengan presentasi video Resep Kernel io_uring (slide) dari pertengahan 2022 oleh io_uring penulis Jens Axboe. Terakhir, tutorial Lord of the io_uring memberikan pengantar untuk io_uring penggunaan.

io_uring komunitas dapat dihubungi melalui milis io_uring dan arsip milis io_uring menunjukkan lalu lintas harian pada awal tahun 2021.

Re "mendukung sebagian I/O dalam arti recv() vs read() ":tambalan masuk ke kernel 5.3 yang secara otomatis akan mencoba lagi io_uring pembacaan singkat dan komit lebih lanjut masuk ke kernel 5.4 yang mengubah perilaku agar hanya secara otomatis menangani pembacaan singkat saat bekerja dengan file "biasa" pada permintaan yang belum menetapkan REQ_F_NOWAIT bendera (sepertinya Anda dapat meminta REQ_F_NOWAIT melalui IOCB_NOWAIT atau dengan membuka file dengan O_NONBLOCK ). Dengan demikian Anda bisa mendapatkan recv() gaya- perilaku I/O "pendek" dari io_uring juga.

Perangkat lunak/proyek menggunakan io_uring

Meskipun antarmuka masih muda (inkarnasi pertamanya tiba pada Mei 2019), beberapa perangkat lunak sumber terbuka menggunakan io_uring "di alam liar":

  • fio (yang juga ditulis oleh Jens Axboe) memiliki backend io_uring ioengine (sebenarnya diperkenalkan kembali pada fio-3.13 dari Februari 2019!). Presentasi "Peningkatan Kinerja Penyimpanan Menggunakan Antarmuka I/O Antarmuka Linux Kernel Baru SNIA" (slide) oleh dua insinyur Intel menyatakan bahwa mereka dapat memperoleh IOPS dua kali lipat pada satu beban kerja dan kurang dari setengah latensi rata-rata pada kedalaman antrean 1 pada beban kerja lain saat membandingkan io_uring ioengine ke libaio ioengine di perangkat Optane.
  • Proyek SPDK menambahkan dukungan untuk menggunakan io_uring (!) untuk memblokir akses perangkat dalam rilis v19.04 (tetapi jelas ini bukan backend yang biasanya Anda gunakan untuk SPDK selain pembandingan). Baru-baru ini, mereka juga tampaknya telah menambahkan dukungan untuk menggunakannya dengan soket di v20.04...
  • Ceph melakukan backend io_uring pada Desember 2019 yang merupakan bagian dari rilis 15.1.0. Pembuat komit memposting komentar github yang menunjukkan beberapa backend io_uring memiliki beberapa keuntungan dan kerugian versus backend libaio (dalam hal IOPS, bandwidth, dan latensi) bergantung pada beban kerja.
  • RocksDB melakukan io_uring backend untuk MultiRead pada Desember 2019 dan merupakan bagian dari rilis 6.7.3. Jens menyatakan io_uring membantu mengurangi latensi secara dramatis.
  • libev merilis 4.31 dengan io_uring awal backend pada Desember 2019. Sementara beberapa poin asli penulis dibahas di kernel yang lebih baru, pada saat penulisan (pertengahan 2021) penulis libev memiliki beberapa kata pilihan tentang io_uring kedewasaan dan mengambil pendekatan menunggu dan melihat sebelum menerapkan perbaikan lebih lanjut.
  • QEMU melakukan backend io_uring pada Jan 2020 dan merupakan bagian dari rilis QEMU 5.0. Dalam presentasi PDF "io_uring in QEMU:high-performance disk IO for Linux", Julia Suvorova menunjukkan io_uring backend mengungguli threads dan aio backend pada satu beban kerja blok 16 ribu acak.
  • Samba menggabungkan io_uring Backend VFS pada Februari 2020 dan merupakan bagian dari rilis Samba 4.12. Di "Linux io_uring VFS backend." Utas milis Samba, Stefan Metzmacher (penulis komit) mengatakan io_uring modul mampu mendorong sekitar 19% lebih banyak throughput (dibandingkan dengan beberapa backend yang tidak ditentukan) dalam pengujian sintetik. Anda juga dapat membaca presentasi PDF "Async VFS Future" oleh Stefan untuk beberapa motivasi di balik perubahan tersebut.
  • Libunifex eksperimental C++ Facebook menggunakannya (namun Anda juga membutuhkan kernel 5.6+)
  • Orang-orang karat telah menulis pembungkus untuk membuat io_uring lebih mudah diakses oleh karat murni. rio adalah salah satu perpustakaan yang sedikit dibicarakan dan penulis mengatakan mereka mencapai throughput yang lebih tinggi dibandingkan dengan menggunakan panggilan sinkronisasi yang dibungkus dengan utas. Penulis memberikan presentasi tentang database dan perpustakaannya di FOSDEM 2020 yang mencakup bagian yang memuji kebaikan io_uring .
  • Perpustakaan karat Glommio secara eksklusif menggunakan io_uring . Penulis (Glauber Costa) menerbitkan sebuah dokumen yang disebut Penyimpanan modern sangat cepat. Ini adalah API yang buruk menunjukkan bahwa dengan penyetelan yang hati-hati Glommio dapat memperoleh kinerja lebih dari 2,5 kali lipat dari biasanya (non-io_uring ) syscall saat melakukan I/O berurutan pada perangkat Optane.
  • Gluster menggabungkan io_uring posix xlator pada Oktober 2020 dan merupakan bagian dari rilis Gluster 9.0. Penulis komit menyebutkan kinerjanya "tidak lebih buruk daripada syscall pwrite/pread biasa".

Penyelidikan perangkat lunak menggunakan io_uring

  • Pengembang PostgreSQL Andres Freund telah menjadi salah satu kekuatan pendorong di balik io_uring perbaikan (mis. solusi untuk mengurangi pertengkaran inode sistem file). Ada presentasi "Asynchronous IO for PostgreSQL" (perhatikan video rusak hingga tanda 5 menit) (PDF) yang memotivasi perlunya perubahan PostgreSQL dan mendemonstrasikan beberapa hasil eksperimen. Dia telah menyatakan harapan untuk mendapatkan io_uring opsionalnya dukungan ke PostgreSQL 14 dan tampaknya sangat menyadari apa yang berhasil dan tidak berfungsi bahkan sampai ke tingkat kernel. Pada bulan Desember 2020, Andres membahas lebih lanjut PostgreSQL io_uring miliknya bekerja di utas milis "Memblokir I/O, async I/O, dan io_uring" pgsql-hacker dan menyebutkan pekerjaan yang sedang berlangsung dapat dilihat di https://github.com/anarazel/postgres/tree/aio .
  • Proyek Netty memiliki repo inkubator yang bekerja pada io_uring dukungan yang membutuhkan kernel 5.9
  • libuv memiliki permintaan tarik untuk tidak menambahkan io_uring dukungan tetapi kemajuannya ke dalam proyek lambat
  • SwiftNIO menambahkan io_uring dukungan untuk eventing (tetapi bukan syscalls) pada bulan April 2020 dan Linux:masalah I/O io_uring penuh menguraikan rencana untuk mengintegrasikannya lebih lanjut
  • Proyek Tokio Rust telah mengembangkan bukti konsep tokio-uring

Dukungan distribusi Linux untuk io_uring

  • (Akhir 2020) Kernel pengaktifan HWE terbaru Ubuntu 18.04 adalah 5.4 jadi io_uring syscall dapat digunakan. Distro ini tidak mengemas liburing terlebih dahulu pustaka pembantu tetapi Anda dapat membuatnya sendiri.
  • Kernel awal Ubuntu 20.04 adalah 5.4 jadi io_uring syscall dapat digunakan. Seperti di atas, distro tidak melakukan pra-paket liburing .
  • Kernel awal Fedora 32 adalah 5.6 dan ia memiliki liburing terpaket jadi io_uring dapat digunakan.
  • SLES 15 SP2 memiliki kernel 5.3 jadi io_uring syscall dapat digunakan. Distro ini tidak mengemas liburing terlebih dahulu pustaka pembantu tetapi Anda dapat membuatnya sendiri.
  • (Pertengahan 2021) Kernel default RHEL 8 tidak mendukung io_uring (versi sebelumnya dari jawaban ini secara keliru mengatakan demikian). Ada artikel basis pengetahuan Add io_uring support Red Hat (konten berada di balik dinding pembayaran pelanggan) yang "sedang diproses".
  • (Pertengahan 2022) Kernel default RHEL 9 tidak mendukung io_uring . Kernel cukup baru (5.14) tetapi mendukung io_uring secara eksplisit dinonaktifkan.

Semoga io_uring akan mengantarkan cerita I/O seperti file asinkron yang lebih baik untuk Linux.

(Untuk menambahkan sedikit kredibilitas pada jawaban ini, di beberapa titik di masa lalu Jens Axboe (pemelihara lapisan blok kernel Linux dan penemu io_uring ) pikir jawaban ini mungkin layak untuk diunggulkan :-)


Jawaban sebenarnya, yang secara tidak langsung ditunjukkan oleh Peter Teoh, didasarkan pada io_setup() dan io_submit(). Secara khusus, fungsi "aio_" yang ditunjukkan oleh Peter adalah bagian dari emulasi tingkat pengguna glibc berdasarkan utas, yang bukan implementasi yang efisien. Jawaban sebenarnya ada di:

io_submit(2)
io_setup(2)
io_cancel(2)
io_destroy(2)
io_getevents(2)

Perhatikan bahwa halaman manual, tertanggal 2012-08, mengatakan bahwa implementasi ini belum matang hingga dapat menggantikan emulasi ruang pengguna glibc:

http://man7.org/linux/man-pages/man7/aio.7.html

implementasi ini belum matang ke titik di mana implementasi POSIXAIO dapat diimplementasikan ulang sepenuhnya menggunakan panggilan sistem kernel.

Jadi, menurut dokumentasi kernel terbaru yang dapat saya temukan, Linux belum memiliki model I/O asinkron berbasis kernel yang matang. Dan, jika saya berasumsi bahwa model yang terdokumentasi benar-benar matang, masih tidak mendukung I/O parsial dalam arti recv() vs read().


Linux
  1. Pelaporan I/O dari baris perintah Linux

  2. Linux – Bagaimana Cara Memantau Disk I/o Di Direktori Tertentu?

  3. Linux – Menentukan File Tertentu yang Bertanggung Jawab Untuk I/o Tinggi?

  1. N Setara Dengan Top Tapi Untuk Jaringan I/o?

  2. Bagaimana cara menghentikan proses 'tidak terputus' di Linux?

  3. Men-debug latensi I/O Linux

  1. Bagaimana Anda melakukan non-blocking console I/O di Linux di C?

  2. Linux dan port penyelesaian I/O?

  3. Penurunan kinerja I/O yang masif dan tidak dapat diprediksi di Linux