From 6e282829b72b5db471d62d2eb551aa893b975dc8 Mon Sep 17 00:00:00 2001 From: Simon Cooper Date: Wed, 25 Jun 2025 14:50:18 +0100 Subject: [PATCH 1/5] Turn direct IO off by default --- .../codec/vectors/es818/ES818BinaryQuantizedVectorsFormat.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/main/java/org/elasticsearch/index/codec/vectors/es818/ES818BinaryQuantizedVectorsFormat.java b/server/src/main/java/org/elasticsearch/index/codec/vectors/es818/ES818BinaryQuantizedVectorsFormat.java index 5df81c35bbd40..80213a778abfe 100644 --- a/server/src/main/java/org/elasticsearch/index/codec/vectors/es818/ES818BinaryQuantizedVectorsFormat.java +++ b/server/src/main/java/org/elasticsearch/index/codec/vectors/es818/ES818BinaryQuantizedVectorsFormat.java @@ -87,7 +87,7 @@ */ public class ES818BinaryQuantizedVectorsFormat extends FlatVectorsFormat { - static final boolean USE_DIRECT_IO = Boolean.parseBoolean(System.getProperty("vector.rescoring.directio", "true")); + static final boolean USE_DIRECT_IO = Boolean.parseBoolean(System.getProperty("vector.rescoring.directio", "false")); public static final String BINARIZED_VECTOR_COMPONENT = "BVEC"; public static final String NAME = "ES818BinaryQuantizedVectorsFormat"; From 22adee070f51d7063b65e813e7a362c5be973a29 Mon Sep 17 00:00:00 2001 From: Simon Cooper Date: Wed, 25 Jun 2025 15:53:08 +0100 Subject: [PATCH 2/5] Add changelog note for the directio option --- docs/changelog/125921.yaml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 docs/changelog/125921.yaml diff --git a/docs/changelog/125921.yaml b/docs/changelog/125921.yaml new file mode 100644 index 0000000000000..cde942c33c7ab --- /dev/null +++ b/docs/changelog/125921.yaml @@ -0,0 +1,18 @@ +pr: 125921 +summary: Allow direct IO for BBQ rescoring +area: Vector Search +type: feature +highlight: + title: Allow direct IO for BBQ rescoring + body: |- + BBQ rescoring can be drastically affected by the amount of available RAM + for use in the page cache. When there is not enough RAM to fit the whole + vector data in memory, BBQ search latencies can be affected by as much as 5000x. + Specifying the `vector.rescoring.directio=true` Java option on all vector search + nodes changes rescoring to use direct IO, which eliminates these very high latencies + from searches in low-memory scenarios, at a cost of a reduction + in vector search performance for BBQ indices. + + This option is released in 9.1 as a tech preview whilst we analyse its effect + for a variety of use cases. +issues: [] From 4a5804c3bf2475ac2fd978871b961b4482253436 Mon Sep 17 00:00:00 2001 From: Simon Cooper Date: Wed, 25 Jun 2025 16:44:36 +0100 Subject: [PATCH 3/5] Add check on the flag for tests --- docs/changelog/125921.yaml | 8 ++++---- .../es818/ES818BinaryQuantizedVectorsFormatTests.java | 2 ++ .../es818/ES818HnswBinaryQuantizedVectorsFormatTests.java | 2 ++ 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/docs/changelog/125921.yaml b/docs/changelog/125921.yaml index cde942c33c7ab..9ca2828c4a7c3 100644 --- a/docs/changelog/125921.yaml +++ b/docs/changelog/125921.yaml @@ -5,12 +5,12 @@ type: feature highlight: title: Allow direct IO for BBQ rescoring body: |- - BBQ rescoring can be drastically affected by the amount of available RAM - for use in the page cache. When there is not enough RAM to fit the whole + BBQ rescoring performance can be drastically affected by the amount of available RAM + for use for the system page cache. When there is not enough RAM to fit all the vector data in memory, BBQ search latencies can be affected by as much as 5000x. Specifying the `vector.rescoring.directio=true` Java option on all vector search - nodes changes rescoring to use direct IO, which eliminates these very high latencies - from searches in low-memory scenarios, at a cost of a reduction + nodes modifies rescoring to use direct IO, which eliminates these very high latencies + from searches in low-memory scenarios, at a cost of a general reduction in vector search performance for BBQ indices. This option is released in 9.1 as a tech preview whilst we analyse its effect diff --git a/server/src/test/java/org/elasticsearch/index/codec/vectors/es818/ES818BinaryQuantizedVectorsFormatTests.java b/server/src/test/java/org/elasticsearch/index/codec/vectors/es818/ES818BinaryQuantizedVectorsFormatTests.java index 9a20b56d80ba4..3b187f2241cca 100644 --- a/server/src/test/java/org/elasticsearch/index/codec/vectors/es818/ES818BinaryQuantizedVectorsFormatTests.java +++ b/server/src/test/java/org/elasticsearch/index/codec/vectors/es818/ES818BinaryQuantizedVectorsFormatTests.java @@ -333,6 +333,8 @@ private Directory newFSDirectory() throws IOException { } static void checkDirectIOSupported() { + assumeTrue("Direct IO is not enabled", ES818BinaryQuantizedVectorsFormat.USE_DIRECT_IO); + Path path = createTempDir("directIOProbe"); try (Directory dir = open(path); IndexOutput out = dir.createOutput("out", IOContext.DEFAULT)) { out.writeString("test"); diff --git a/server/src/test/java/org/elasticsearch/index/codec/vectors/es818/ES818HnswBinaryQuantizedVectorsFormatTests.java b/server/src/test/java/org/elasticsearch/index/codec/vectors/es818/ES818HnswBinaryQuantizedVectorsFormatTests.java index 3a4a0d097ea1b..c71549a945a48 100644 --- a/server/src/test/java/org/elasticsearch/index/codec/vectors/es818/ES818HnswBinaryQuantizedVectorsFormatTests.java +++ b/server/src/test/java/org/elasticsearch/index/codec/vectors/es818/ES818HnswBinaryQuantizedVectorsFormatTests.java @@ -221,6 +221,8 @@ private Directory newFSDirectory() throws IOException { } static void checkDirectIOSupported() { + assumeTrue("Direct IO is not enabled", ES818BinaryQuantizedVectorsFormat.USE_DIRECT_IO); + Path path = createTempDir("directIOProbe"); try (Directory dir = open(path); IndexOutput out = dir.createOutput("out", IOContext.DEFAULT)) { out.writeString("test"); From b8f17f01426adf4666cd24be3bad12238d5df033 Mon Sep 17 00:00:00 2001 From: Simon Cooper Date: Thu, 26 Jun 2025 09:21:18 +0100 Subject: [PATCH 4/5] Also disable direct IO test --- .../java/org/elasticsearch/index/store/DirectIOIT.java | 5 ++++- .../vectors/es818/ES818BinaryQuantizedVectorsFormat.java | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/server/src/internalClusterTest/java/org/elasticsearch/index/store/DirectIOIT.java b/server/src/internalClusterTest/java/org/elasticsearch/index/store/DirectIOIT.java index c80eac73f4f6a..02e17e3395760 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/index/store/DirectIOIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/index/store/DirectIOIT.java @@ -17,6 +17,7 @@ import org.apache.lucene.store.IndexOutput; import org.apache.lucene.tests.util.LuceneTestCase; import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.index.codec.vectors.es818.ES818BinaryQuantizedVectorsFormat; import org.elasticsearch.plugins.Plugin; import org.elasticsearch.search.vectors.KnnSearchBuilder; import org.elasticsearch.search.vectors.VectorData; @@ -43,7 +44,9 @@ public class DirectIOIT extends ESIntegTestCase { @BeforeClass - public static void checkSupported() throws IOException { + public static void checkSupported() { + assumeTrue("Direct IO is not enabled", ES818BinaryQuantizedVectorsFormat.USE_DIRECT_IO); + Path path = createTempDir("directIOProbe"); try (Directory dir = open(path); IndexOutput out = dir.createOutput("out", IOContext.DEFAULT)) { out.writeString("test"); diff --git a/server/src/main/java/org/elasticsearch/index/codec/vectors/es818/ES818BinaryQuantizedVectorsFormat.java b/server/src/main/java/org/elasticsearch/index/codec/vectors/es818/ES818BinaryQuantizedVectorsFormat.java index 80213a778abfe..146164b55f00a 100644 --- a/server/src/main/java/org/elasticsearch/index/codec/vectors/es818/ES818BinaryQuantizedVectorsFormat.java +++ b/server/src/main/java/org/elasticsearch/index/codec/vectors/es818/ES818BinaryQuantizedVectorsFormat.java @@ -87,7 +87,7 @@ */ public class ES818BinaryQuantizedVectorsFormat extends FlatVectorsFormat { - static final boolean USE_DIRECT_IO = Boolean.parseBoolean(System.getProperty("vector.rescoring.directio", "false")); + public static final boolean USE_DIRECT_IO = Boolean.parseBoolean(System.getProperty("vector.rescoring.directio", "false")); public static final String BINARIZED_VECTOR_COMPONENT = "BVEC"; public static final String NAME = "ES818BinaryQuantizedVectorsFormat"; From ac493d8c5e97c53eb7cfea1857e34d3c263bee93 Mon Sep 17 00:00:00 2001 From: Simon Cooper Date: Thu, 26 Jun 2025 14:05:01 +0100 Subject: [PATCH 5/5] Tweak wording --- docs/changelog/125921.yaml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/changelog/125921.yaml b/docs/changelog/125921.yaml index 9ca2828c4a7c3..0446558b1bdd1 100644 --- a/docs/changelog/125921.yaml +++ b/docs/changelog/125921.yaml @@ -5,13 +5,13 @@ type: feature highlight: title: Allow direct IO for BBQ rescoring body: |- - BBQ rescoring performance can be drastically affected by the amount of available RAM - for use for the system page cache. When there is not enough RAM to fit all the - vector data in memory, BBQ search latencies can be affected by as much as 5000x. + BBQ rescoring performance can be drastically affected by the amount of available + off-heap RAM for use by the system page cache. When there is not enough off-heap RAM + to fit all the vector data in memory, BBQ search latencies can be affected by as much as 5000x. Specifying the `vector.rescoring.directio=true` Java option on all vector search nodes modifies rescoring to use direct IO, which eliminates these very high latencies - from searches in low-memory scenarios, at a cost of a general reduction - in vector search performance for BBQ indices. + from searches in low-memory scenarios, at a cost of a reduction + in vector search performance for BBQ indices when the vectors do all fit in memory. This option is released in 9.1 as a tech preview whilst we analyse its effect for a variety of use cases.