-
Notifications
You must be signed in to change notification settings - Fork 640
feat: io_uring based file reader #5777
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
58db99a
Initial uring impl
westonpace b8867e2
Cleanup and address clippy warnings
westonpace 2660925
Handle io_uring short reads with retry and EOF detection
westonpace 45c5952
Fix SQ-full push failure silently dropping requests
westonpace fae9411
Remove unused pending_count field from ThreadLocalUring
westonpace e8a28b2
Return error instead of panicking on SQ full in current_thread submit
westonpace aa2c82f
Update Cargo.lock files
westonpace 2510c8e
Fix clippy CI failure: replace disallowed snafu::location!() macro
westonpace 67e3d3f
Update Cargo.lock files
westonpace 39e3f17
Simplify lockfile changes
westonpace 84939a1
Address PR review feedback
westonpace 55b745a
Fix compiler recursion depth overflow in IvfIndexBuilder::build()
westonpace abbdbad
Update Cargo.lock after rebase
westonpace File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,84 @@ | ||
| // SPDX-License-Identifier: Apache-2.0 | ||
| // SPDX-FileCopyrightText: Copyright The Lance Authors | ||
|
|
||
| //! io_uring-based I/O for disks with high IOPS capacity (e.g. NVMe) | ||
| //! | ||
| //! This module provides two implementations of the [`Reader`](crate::traits::Reader) trait | ||
| //! using Linux's io_uring interface for asynchronous I/O. | ||
| //! | ||
| //! One of these uses a pool of dedicated background threads which each own an io_uring instance. | ||
| //! Read requests are submitted to a background thread's pool. | ||
| //! | ||
| //! The other implementation uses a thread-local io_uring instance. This only works if the future | ||
| //! is polled by the same thread that submitted the request. This means that the runtime must be | ||
| //! a single-threaded runtime. | ||
| //! | ||
| //! # Configuration | ||
| //! | ||
| //! The io_uring reader is enabled by using the `file+uring://` URI scheme instead of `file://`. | ||
| //! Additional tuning parameters are controlled by environment variables: | ||
| //! | ||
| //! - `LANCE_URING_CURRENT_THREAD` - Use thread-local io_uring (default: false) | ||
| //! - `LANCE_URING_BLOCK_SIZE` - Block size in bytes (default: 4KB) | ||
| //! - `LANCE_URING_IO_PARALLELISM` - Max concurrent operations (default: 128) | ||
| //! - `LANCE_URING_QUEUE_DEPTH` - io_uring queue depth (default: 16K) | ||
| //! - `LANCE_URING_THREAD_COUNT` - Number of io_uring threads to use (default: 2) | ||
| //! - `LANCE_URING_SUBMIT_BATCH_SIZE` - Number of requests to batch before submitting (default: 128) | ||
| //! - `LANCE_URING_POLL_TIMEOUT_MS` - Thread poll timeout in milliseconds (default: 10) | ||
| //! | ||
| //! Note: the block size and io parallelism are not actually used by the io_uring implementation. These | ||
| //! variables just control what the filesystem reports up to Lance. | ||
| //! | ||
| //! # Platform Support | ||
| //! | ||
| //! This module is only available on Linux and requires kernel 5.1 or newer. | ||
| //! On other platforms, the code falls back to [`LocalObjectReader`](crate::local::LocalObjectReader). | ||
| //! | ||
| //! # Example | ||
| //! | ||
| //! ```no_run | ||
| //! # use lance_io::object_store::ObjectStore; | ||
| //! # async fn example() -> lance_core::Result<()> { | ||
| //! // Enable io_uring by using the file+uring:// scheme | ||
| //! let uri = "file+uring:///path/to/file.dat"; | ||
| //! let (store, path) = ObjectStore::from_uri(uri).await?; | ||
| //! let reader = store.open(&path).await?; | ||
| //! | ||
| //! // Reader will use io_uring | ||
| //! let data = reader.get_range(0..1024).await?; | ||
| //! # Ok(()) | ||
| //! # } | ||
| //! ``` | ||
|
|
||
| mod future; | ||
| mod reader; | ||
| mod requests; | ||
| mod thread; | ||
|
|
||
| // Thread-local io_uring implementation for current-thread runtimes | ||
| pub(crate) mod current_thread; | ||
| pub(crate) mod current_thread_future; | ||
|
|
||
| #[cfg(test)] | ||
| mod tests; | ||
|
|
||
| use std::sync::LazyLock; | ||
|
|
||
| pub(crate) use current_thread::UringCurrentThreadReader; | ||
| pub use reader::UringReader; | ||
|
|
||
| /// Default block size for io_uring reads (4KB) | ||
| pub const DEFAULT_URING_BLOCK_SIZE: usize = 4 * 1024; | ||
|
|
||
| /// Default I/O parallelism for io_uring (128 concurrent operations) | ||
| pub const DEFAULT_URING_IO_PARALLELISM: usize = 128; | ||
|
|
||
| /// Default io_uring queue depth (16K entries) | ||
| pub const DEFAULT_URING_QUEUE_DEPTH: usize = 16 * 1024; | ||
|
|
||
| /// Cached `LANCE_URING_BLOCK_SIZE` env var, read once at first access. | ||
| pub(crate) static URING_BLOCK_SIZE: LazyLock<Option<usize>> = LazyLock::new(|| { | ||
| std::env::var("LANCE_URING_BLOCK_SIZE") | ||
| .ok() | ||
| .and_then(|s| s.parse().ok()) | ||
| }); |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.