Use direct I/O for merge-time reads of raw vectors - #155919
Conversation
|
Pinging @elastic/es-search-relevance (Team:Search Relevance) |
|
|
||
| `on_disk_rescore` {applies_to}`stack: preview 9.3` {applies_to}`serverless: unavailable` | ||
| : (Optional, boolean) Only applicable to quantized HNSW and `bbq_disk` index types. When `true`, vector rescoring will read the raw vector data directly from disk, and will not copy it in memory. This can improve performance when vector data is larger than the amount of available RAM. This setting only applies to newly-indexed vectors; after changing this setting, the vectors must be reindexed or force-merged to apply the new setting to the whole index. Defaults to `false`. | ||
| : (Optional, boolean) Only applicable to quantized HNSW and `bbq_disk` index types. When `true`, vector rescoring will read the raw vector data directly from disk, and will not copy it in memory. This can improve performance when vector data is larger than the amount of available RAM. For `bbq_hnsw` indices, segment merges also read the raw vector data directly from disk where the platform supports it, so that merging is less likely to evict more frequently accessed data from the filesystem cache. {applies_to}`stack: ga 9.6` This setting only applies to newly-indexed vectors; after changing this setting, the vectors must be reindexed or force-merged to apply the new setting to the whole index. Defaults to `false`. |
There was a problem hiding this comment.
The inline applies_to tag is floating between sentences, which makes its scope ambiguous. Moving the new sentence to its own paragraph at the end and prefixing it with the tag makes the scope clear.
For the new content, defer to #155919 (comment)
| : (Optional, boolean) Only applicable to quantized HNSW and `bbq_disk` index types. When `true`, vector rescoring will read the raw vector data directly from disk, and will not copy it in memory. This can improve performance when vector data is larger than the amount of available RAM. For `bbq_hnsw` indices, segment merges also read the raw vector data directly from disk where the platform supports it, so that merging is less likely to evict more frequently accessed data from the filesystem cache. {applies_to}`stack: ga 9.6` This setting only applies to newly-indexed vectors; after changing this setting, the vectors must be reindexed or force-merged to apply the new setting to the whole index. Defaults to `false`. | |
| : (Optional, boolean) Only applicable to quantized HNSW and `bbq_disk` index types. When `true`, vector rescoring will read the raw vector data directly from disk, and will not copy it in memory. This can improve performance when vector data is larger than the amount of available RAM. This setting only applies to newly-indexed vectors; after changing this setting, the vectors must be reindexed or force-merged to apply the new setting to the whole index. Defaults to `false`. | |
| {applies_to}`stack: ga 9.6` For `bbq_hnsw` indices, segment merges also read the raw vector data directly from disk where the platform supports it, so that merging is less likely to evict more frequently accessed data from the filesystem cache. |
@thecoop: should the parent on_disk_rescore tag also be updated from
{applies_to}`stack: preview 9.3`
to
{applies_to}`stack: preview 9.3, ga X.x`
?
Or is on_disk_rescore still a preview thing?
There was a problem hiding this comment.
I'm not sure we can say directIO is ga yet, there's still various aspects we need to check - in particular whether we use direct IO for merges generally. We're due to come back to this soon, so we can re-evaluate it then
|
Thanks for the deep dive here, the page cache analysis is really useful. I like the idea of I'd like to separate two things that are mixed together in this PR, a bug and a feature. The bug is that I think we should land that one first since it changes the baseline you're comparing Then the feature part. Merges bypassing the page cache when you configure it sounds great
|
|
sounds fair, once #153423 lands, i'll rebase and re-measure on top of it. and agreed the residency numbers are unaffected either way. on the 2.2x: i think my numbers and yours are both right but they're measuring different bottlenecks. mine ran memory-constrained — during a merge the sources, the new-segment writeback and an unrelated pre-warmed file want ~38 GB between them, against ~25 GB of usable page cache. the device wasn't the limit there — that NVMe does 3.4-3.9 GB/s under O_DIRECT. so the baseline wasn't bandwidth-bound, it was reclaim-bound: the merge faults its sources in repeatedly while the kernel reclaims underneath it. i would say direct I/O isn't faster than RAM, it's faster than faulting through a thrashing cache. your box sounds device-bound at ~450 MiB/s, about 8x slower than mine. at that point mmap-with-the-right-advice and direct I/O should both saturate the device and tie, which is exactly what you saw. SEQUENTIAL advice fixes readahead, but it doesn't stop the merge from filling the cache, so i'd expect it to close much less of the gap once memory is the constraint rather than bandwidth. that's my prediction at least. writes: yes, and it matters. even with direct-IO reads the merged output is still buffered-written — ~82% of the new decoupling merge from rescore: agree, and that's most of the way done already. after thecoop's round 1 the PR builds two direct-IO directories and picks between them on also relevant: the lucene half of the |
Open the merge-side reader with a direct-I/O context when direct I/O is enabled, created lazily on the first
getMergeInstance()call and reading through a merge-sized (256 KiB) buffer rather than the 8 KiB rescore buffer. This stops merges from re-populating the page cache with the raw vectors thaton_disk_rescoredeliberately keeps out of memory. Mechanism, history around #127406, and benchmarks are in the issue.Closes #155021