Skip to content

Commit 3ba32e4

Browse files
authored
Merge branch 'main' into esql-inference-rerank-test-service-score-update
2 parents 6a57a30 + 9d99472 commit 3ba32e4

File tree

14 files changed

+245
-124
lines changed

14 files changed

+245
-124
lines changed

distribution/docker/src/docker/dockerfiles/cloud_ess_fips/Dockerfile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
# Extract Elasticsearch artifact
2626
################################################################################
2727
28-
FROM docker.elastic.co/wolfi/chainguard-base-fips:latest@sha256:aa593467857242c06357efd847cd72f5d84fbdd4633a65d64eb85bd7a797ecdd AS builder
28+
FROM docker.elastic.co/wolfi/chainguard-base-fips:latest@sha256:dda0bd723ffc0a113b1b61c43f748b01d61129dfc95bfaf7ad82cdd0d1f94212 AS builder
2929
3030
# Install required packages to extract the Elasticsearch distribution
3131
RUN <%= retry.loop(package_manager, "export DEBIAN_FRONTEND=noninteractive && ${package_manager} update && ${package_manager} update && ${package_manager} add --no-cache curl") %>
@@ -104,7 +104,7 @@ WORKDIR /usr/share/elasticsearch/config
104104
# Add entrypoint
105105
################################################################################
106106

107-
FROM docker.elastic.co/wolfi/chainguard-base-fips:latest@sha256:aa593467857242c06357efd847cd72f5d84fbdd4633a65d64eb85bd7a797ecdd
107+
FROM docker.elastic.co/wolfi/chainguard-base-fips:latest@sha256:dda0bd723ffc0a113b1b61c43f748b01d61129dfc95bfaf7ad82cdd0d1f94212
108108

109109
RUN <%= retry.loop(package_manager,
110110
"export DEBIAN_FRONTEND=noninteractive && \n" +

distribution/docker/src/docker/dockerfiles/wolfi/Dockerfile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
# Extract Elasticsearch artifact
2626
################################################################################
2727
28-
FROM docker.elastic.co/wolfi/chainguard-base:latest@sha256:9060788fe55e611245d1b4a53ef705018a2703b4879a950a276fe113ef750cd6 AS builder
28+
FROM docker.elastic.co/wolfi/chainguard-base:latest@sha256:5bb6cf5a4bd9826b7bab8d10699dc2189fbd29b1fe2681b3e271b8994d17cf16 AS builder
2929
3030
# Install required packages to extract the Elasticsearch distribution
3131
RUN <%= retry.loop(package_manager, "export DEBIAN_FRONTEND=noninteractive && ${package_manager} update && ${package_manager} update && ${package_manager} add --no-cache curl") %>
@@ -80,7 +80,7 @@ RUN sed -i -e 's/ES_DISTRIBUTION_TYPE=tar/ES_DISTRIBUTION_TYPE=docker/' bin/elas
8080
# Add entrypoint
8181
################################################################################
8282

83-
FROM docker.elastic.co/wolfi/chainguard-base:latest@sha256:9060788fe55e611245d1b4a53ef705018a2703b4879a950a276fe113ef750cd6
83+
FROM docker.elastic.co/wolfi/chainguard-base:latest@sha256:5bb6cf5a4bd9826b7bab8d10699dc2189fbd29b1fe2681b3e271b8994d17cf16
8484

8585
RUN <%= retry.loop(package_manager,
8686
"export DEBIAN_FRONTEND=noninteractive && \n" +

docs/reference/elasticsearch/mapping-reference/bbq.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ applies_to:
77

88
# Better Binary Quantization (BBQ) [bbq]
99

10-
Better Binary Quantization (BBQ) is an advanced vector quantization method, designed for large-scale similarity search. BBQ is a form of lossy compression for [`dense_vector` fields](https://www.elastic.co/docs/reference/elasticsearch/mapping-reference/dense-vector) that enables efficient storage and retrieval of large numbers of vectors, while keeping results close to those from the original uncompressed vectors.
10+
Better Binary Quantization (BBQ) is an advanced vector quantization method, designed for large-scale similarity search. BBQ is a form of lossy compression for [`dense_vector` fields](elasticsearch://reference/elasticsearch/mapping-reference/dense-vector.md) that enables efficient storage and retrieval of large numbers of vectors, while keeping results close to those from the original uncompressed vectors.
1111

1212
BBQ offers significant improvements over scalar quantization by relying on optimized `bit` level computations to reduce memory usage and computational costs while maintaining high search relevance using pre-computed corrective factors. BBQ is designed to work in combination with [oversampling](#bbq-oversampling) and reranking, and is compatible with various [vector search algorithms](#bbq-vector-search-algorithms), such as [HNSW](#bbq-hnsw) and [brute force (flat)](#bbq-flat).
1313

@@ -23,7 +23,7 @@ BBQ currently supports two vector search algorithms, each suited to different sc
2323

2424
### `bbq_hnsw` [bbq-hnsw]
2525

26-
When you set a dense vector field’s `index_options` parameter to `type: bbq_hnsw`, {{es}} uses the HNSW algorithm for fast [kNN search](https://www.elastic.co/docs//solutions/search/vector/knn) on compressed vectors. With the default [oversampling](#bbq-oversampling) applied, it delivers better cost efficiency, lower latency, and improved relevance ranking, making it the best choice for large-scale similarity search.
26+
When you set a dense vector field’s `index_options` parameter to `type: bbq_hnsw`, {{es}} uses the HNSW algorithm for fast [kNN search](docs-content://solutions/search/vector/knn.md) on compressed vectors. With the default [oversampling](#bbq-oversampling) applied, it delivers better cost efficiency, lower latency, and improved relevance ranking, making it the best choice for large-scale similarity search.
2727

2828
:::{note}
2929
Starting in version 9.1, `bbq_hnsw` is the default indexing method for new `dense_vector` fields with greater than 384 dimensions, so you typically don’t need to specify it explicitly when creating an index.
@@ -140,7 +140,7 @@ stack: ga 9.2
140140
This feature requires an [Enterprise subscription](https://www.elastic.co/subscriptions).
141141
:::
142142

143-
When you set a dense vector field’s `index_options` parameter to `type: bbq_disk`, {{es}} uses the DiskBBQ algorithm, a disk-based alternative to HNSW for [kNN search](https://www.elastic.co/docs//solutions/search/vector/knn) on compressed vectors. DiskBBQ stores the vector data on disk instead of in memory, lowering RAM requirements and reducing the overall cost of vector storage and search.
143+
When you set a dense vector field’s `index_options` parameter to `type: bbq_disk`, {{es}} uses the DiskBBQ algorithm, a disk-based alternative to HNSW for [kNN search](docs-content://solutions/search/vector/knn.md) on compressed vectors. DiskBBQ stores the vector data on disk instead of in memory, lowering RAM requirements and reducing the overall cost of vector storage and search.
144144

145145
DiskBBQ groups similar vectors into small clusters using [hierarchical K-means](https://www.elastic.co/search-labs/blog/k-means-for-vector-indices). When processing a query, it finds the centroids closest to the query vector and only compares the vectors within those clusters. This targeted approach reduces the number of in-memory operations, making it ideal for large-scale or memory-constrained environments.
146146

@@ -260,12 +260,12 @@ GET bbq-index/_search
260260
By default, oversampling is set to 3×, meaning if you request k:10, {{es}} retrieves 30 candidates for re-ranking. You don’t need to configure this behavior; it’s applied automatically for BBQ searches.
261261

262262
:::{note}
263-
You can change oversampling from the default 3× to another value. Refer to [Oversampling and rescoring for quantized vectors](https://www.elastic.co/docs/solutions/search/vector/knn#dense-vector-knn-search-rescoring) for details.
263+
You can change oversampling from the default 3× to another value. Refer to [Oversampling and rescoring for quantized vectors](docs-content://solutions/search/vector/knn.md#dense-vector-knn-search-rescoring) for details.
264264
:::
265265

266266
## Learn more [bbq-learn-more]
267267

268268
- [Better Binary Quantization (BBQ) in Lucene and {{es}}](https://www.elastic.co/search-labs/blog/better-binary-quantization-lucene-elasticsearch) - Learn how BBQ works, its benefits, and how it reduces memory usage while preserving search accuracy.
269269
- [Introducing a new vector storage format: DiskBBQ](https://www.elastic.co/search-labs/blog/diskbbq-elasticsearch-introduction) - Learn how DiskBBQ improves vector search in low-memory environments and compares to HNSW in speed and cost-effectiveness.
270-
- [Dense vector field type](https://www.elastic.co/docs/reference/elasticsearch/mapping-reference/dense-vector) - Find code examples for using `bbq_hnsw` `index_type`.
271-
- [kNN search](https://www.elastic.co/docs/solutions/search/vector/knn) - Learn about the search algorithm that BBQ works with.
270+
- [Dense vector field type](elasticsearch://reference/elasticsearch/mapping-reference/dense-vector.md) - Find code examples for using `bbq_hnsw` `index_type`.
271+
- [kNN search](docs-content://solutions/search/vector/knn.md) - Learn about the search algorithm that BBQ works with.

muted-tests.yml

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -231,9 +231,6 @@ tests:
231231
- class: org.elasticsearch.search.basic.SearchWithRandomDisconnectsIT
232232
method: testSearchWithRandomDisconnects
233233
issue: https://github.com/elastic/elasticsearch/issues/138128
234-
- class: org.elasticsearch.xpack.esql.qa.single_node.GenerativeMetricsIT
235-
method: test
236-
issue: https://github.com/elastic/elasticsearch/issues/138311
237234
- class: org.elasticsearch.xpack.ml.integration.RegressionIT
238235
method: testTwoJobsWithSameRandomizeSeedUseSameTrainingSet
239236
issue: https://github.com/elastic/elasticsearch/issues/138319
@@ -300,18 +297,6 @@ tests:
300297
- class: org.elasticsearch.packaging.test.DockerTests
301298
method: test072RunEsAsDifferentUserAndGroup
302299
issue: https://github.com/elastic/elasticsearch/issues/140127
303-
- class: org.elasticsearch.compute.aggregation.blockhash.BlockHashTests
304-
method: testLongBytesRefHashWithMultiValuedFields
305-
issue: https://github.com/elastic/elasticsearch/issues/140546
306-
- class: org.elasticsearch.compute.aggregation.TimeSeriesFirstDocIdDeduplicationTests
307-
method: testSimpleToString
308-
issue: https://github.com/elastic/elasticsearch/issues/140547
309-
- class: org.elasticsearch.compute.operator.RowInTableLookupOperatorTests
310-
method: testSimpleToString
311-
issue: https://github.com/elastic/elasticsearch/issues/140548
312-
- class: org.elasticsearch.compute.aggregation.WindowGroupingAggregatorFunctionTests
313-
method: testSimpleToString
314-
issue: https://github.com/elastic/elasticsearch/issues/140549
315300
- class: org.elasticsearch.search.TelemetryMetrics.ShardSearchPhaseAPMMetricsTests
316301
method: testUniformCanMatchMetricAttributesWhenPlentyOfDocumentsInIndex
317302
issue: https://github.com/elastic/elasticsearch/issues/140603
@@ -342,12 +327,6 @@ tests:
342327
- class: org.elasticsearch.xpack.esql.qa.single_node.EsqlSpecIT
343328
method: test {csv-spec:string.Url_encode_component tests with table reads}
344329
issue: https://github.com/elastic/elasticsearch/issues/140621
345-
- class: org.elasticsearch.xpack.logsdb.RandomizedRollingUpgradeIT
346-
method: testIndexingStandardSource
347-
issue: https://github.com/elastic/elasticsearch/issues/140658
348-
- class: org.elasticsearch.xpack.logsdb.RandomizedRollingUpgradeIT
349-
method: testIndexingSyntheticSource
350-
issue: https://github.com/elastic/elasticsearch/issues/139482
351330
- class: org.elasticsearch.xpack.esql.heap_attack.HeapAttackSubqueryIT
352331
method: testManyRandomTextFieldsInSubqueryIntermediateResultsWithSortManyFields
353332
issue: https://github.com/elastic/elasticsearch/issues/140664

server/src/main/java/org/elasticsearch/cluster/routing/allocation/allocator/BalancedShardsAllocator.java

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,6 @@ public void allocate(RoutingAllocation allocation) {
169169
final Balancer balancer = new Balancer(
170170
writeLoadForecaster,
171171
allocation,
172-
balancerSettings.getThreshold(),
173172
balancingWeights,
174173
balancerSettings.completeEarlyOnShardAssignmentChange()
175174
);
@@ -248,7 +247,6 @@ public ShardAllocationDecision explainShardAllocation(final ShardRouting shard,
248247
Balancer balancer = new Balancer(
249248
writeLoadForecaster,
250249
allocation,
251-
balancerSettings.getThreshold(),
252250
balancingWeightsFactory.create(),
253251
balancerSettings.completeEarlyOnShardAssignmentChange()
254252
);
@@ -303,7 +301,6 @@ public static class Balancer {
303301
private final RoutingNodes routingNodes;
304302
private final Metadata metadata;
305303

306-
private final float threshold;
307304
private final float avgShardsPerNode;
308305
private final double avgWriteLoadPerNode;
309306
private final double avgDiskUsageInBytesPerNode;
@@ -315,15 +312,13 @@ public static class Balancer {
315312
private Balancer(
316313
WriteLoadForecaster writeLoadForecaster,
317314
RoutingAllocation allocation,
318-
float threshold,
319315
BalancingWeights balancingWeights,
320316
boolean completeEarlyOnShardAssignmentChange
321317
) {
322318
this.writeLoadForecaster = writeLoadForecaster;
323319
this.allocation = allocation;
324320
this.routingNodes = allocation.routingNodes();
325321
this.metadata = allocation.metadata();
326-
this.threshold = threshold;
327322
avgShardsPerNode = WeightFunction.avgShardPerNode(metadata, routingNodes);
328323
avgWriteLoadPerNode = WeightFunction.avgWriteLoadPerNode(writeLoadForecaster, metadata, routingNodes);
329324
avgDiskUsageInBytesPerNode = balancingWeights.diskUsageIgnored()
@@ -521,7 +516,7 @@ private MoveDecision explainRebalanceDecision(final ProjectIndex index, final Sh
521516
// then even though the node we are examining has a better weight and may make the cluster balance
522517
// more even, it doesn't make sense to execute the heavyweight operation of relocating a shard unless
523518
// the gains make it worth it, as defined by the threshold
524-
final float localThreshold = sorter.minWeightDelta() * threshold;
519+
final float localThreshold = sorter.minWeightDelta() * sorter.getThreshold();
525520
boolean deltaAboveThreshold = lessThan(currentDelta, localThreshold) == false;
526521
// calculate the delta of the weights of the two nodes if we were to add the shard to the
527522
// node in question and move it away from the node that currently holds it.
@@ -640,7 +635,7 @@ private boolean balanceByWeights(NodeSorter sorter) {
640635
sorter.reset(index, 0, relevantNodes);
641636
int lowIdx = 0;
642637
int highIdx = relevantNodes - 1;
643-
final float localThreshold = sorter.minWeightDelta() * threshold;
638+
final float localThreshold = sorter.minWeightDelta() * sorter.getThreshold();
644639
while (true) {
645640
final ModelNode minNode = modelNodes[lowIdx];
646641
final ModelNode maxNode = modelNodes[highIdx];
@@ -1774,14 +1769,16 @@ public static final class NodeSorter extends IntroSorter {
17741769
/** The nodes weights with respect to the current weight function / index */
17751770
final float[] weights;
17761771
private final WeightFunction function;
1777-
private ProjectIndex index;
17781772
private final Balancer balancer;
1773+
private final float threshold;
1774+
private ProjectIndex index;
17791775
private float pivotWeight;
17801776

1781-
public NodeSorter(ModelNode[] modelNodes, WeightFunction function, Balancer balancer) {
1777+
public NodeSorter(ModelNode[] modelNodes, WeightFunction function, Balancer balancer, float threshold) {
17821778
this.function = function;
17831779
this.balancer = balancer;
17841780
this.modelNodes = modelNodes;
1781+
this.threshold = threshold;
17851782
weights = new float[modelNodes.length];
17861783
}
17871784

@@ -1844,6 +1841,10 @@ public float delta() {
18441841
public WeightFunction getWeightFunction() {
18451842
return function;
18461843
}
1844+
1845+
public float getThreshold() {
1846+
return threshold;
1847+
}
18471848
}
18481849

18491850
// Visible for testing.

server/src/main/java/org/elasticsearch/cluster/routing/allocation/allocator/GlobalBalancingWeightsFactory.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,9 @@ public WeightFunction weightFunctionForNode(RoutingNode node) {
5656

5757
@Override
5858
public NodeSorters createNodeSorters(BalancedShardsAllocator.ModelNode[] modelNodes, BalancedShardsAllocator.Balancer balancer) {
59-
return new GlobalNodeSorters(new BalancedShardsAllocator.NodeSorter(modelNodes, weightFunction, balancer));
59+
return new GlobalNodeSorters(
60+
new BalancedShardsAllocator.NodeSorter(modelNodes, weightFunction, balancer, balancerSettings.getThreshold())
61+
);
6062
}
6163

6264
@Override

server/src/main/java/org/elasticsearch/index/codec/vectors/diskbbq/ES920DiskBBQVectorsReader.java

Lines changed: 1 addition & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -47,39 +47,7 @@ public class ES920DiskBBQVectorsReader extends IVFVectorsReader {
4747

4848
public CentroidIterator getPostingListPrefetchIterator(CentroidIterator centroidIterator, IndexInput postingListSlice)
4949
throws IOException {
50-
return new CentroidIterator() {
51-
CentroidOffsetAndLength nextOffsetAndLength = centroidIterator.hasNext()
52-
? centroidIterator.nextPostingListOffsetAndLength()
53-
: null;
54-
55-
{
56-
// prefetch the first one
57-
if (nextOffsetAndLength != null) {
58-
prefetch(nextOffsetAndLength);
59-
}
60-
}
61-
62-
void prefetch(CentroidOffsetAndLength offsetAndLength) throws IOException {
63-
postingListSlice.prefetch(offsetAndLength.offset(), offsetAndLength.length());
64-
}
65-
66-
@Override
67-
public boolean hasNext() {
68-
return nextOffsetAndLength != null;
69-
}
70-
71-
@Override
72-
public CentroidOffsetAndLength nextPostingListOffsetAndLength() throws IOException {
73-
CentroidOffsetAndLength offsetAndLength = nextOffsetAndLength;
74-
if (centroidIterator.hasNext()) {
75-
nextOffsetAndLength = centroidIterator.nextPostingListOffsetAndLength();
76-
prefetch(nextOffsetAndLength);
77-
} else {
78-
nextOffsetAndLength = null; // indicate we reached the end
79-
}
80-
return offsetAndLength;
81-
}
82-
};
50+
return new PrefetchingCentroidIterator(centroidIterator, postingListSlice);
8351
}
8452

8553
@Override

0 commit comments

Comments
 (0)