Skip to content

Commit 98cd8a9

Browse files
adelapenamichaelsembwever
authored andcommitted
CNDB-15432: CNDB-15155: Segregate SAI's query metrics per query type (#1969)
Add SAI query metrics per kind of query. There are metrics for: * Filtering only queries. * Top-k only queries, such as ANN, BM25 and generic ordering. * Hybrid queries, combining both top-k and filtering. * Single-partition queries. * Multi-partition queries. Each of these groups has the same records as the general query metrics. These new metrics can be enabled/disabled with the system properties: * cassandra.sai.metrics.query_kind.per_table.enabled * cassandra.sai.metrics.query_kind.per_query.enabled Rebase notes: * required to re-implement CASSANDRA-18940 * will be replaced (made redundant) by CASSANDRA-20923
1 parent 79b692d commit 98cd8a9

File tree

17 files changed

+591
-134
lines changed

17 files changed

+591
-134
lines changed

src/java/org/apache/cassandra/config/CassandraRelevantProperties.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -728,6 +728,20 @@ public enum CassandraRelevantProperties
728728
SAI_NUMERIC_VALUES_MONOTONIC_BLOCK_SIZE("dse.sai.numeric_values.monotonic_block_size", "16384"),
729729
/** Controls the number of rows read in a single batch when fetching rows for a partition key */
730730
SAI_PARTITION_ROW_BATCH_SIZE("cassandra.sai.partition_row_batch_size", "100"),
731+
732+
/**
733+
* Whether to enable SAI per-query metrics for different kinds of query, such as filter-only queries, top-k-only
734+
* queries, hybrid queries, single-partition queries, and multipartition queries. These metrics are histograms and
735+
* timers.
736+
*/
737+
SAI_QUERY_KIND_PER_QUERY_METRICS_ENABLED("cassandra.sai.metrics.query_kind.per_query.enabled", "false"),
738+
739+
/**
740+
* Whether to enable SAI per-table metrics for different kinds of query, such as filter-only queries, top-k-only
741+
* queries, hybrid queries, single-partition queries, and multipartition queries. These metrics are always counters.
742+
*/
743+
SAI_QUERY_KIND_PER_TABLE_METRICS_ENABLED("cassandra.sai.metrics.query_kind.per_table.enabled", "true"),
744+
731745
SAI_QUERY_OPT_LEVEL("cassandra.sai.query.optimization.level", "1"),
732746
SAI_REDUCE_TOPK_ACROSS_SSTABLES("cassandra.sai.reduce_topk_across_sstables", "true"),
733747
SAI_TEST_DISABLE_TIMEOUT("cassandra.sai.test.timeout_disabled", "false"),

src/java/org/apache/cassandra/db/MultiRangeReadCommand.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,12 @@ public ReadResponse createEmptyResponse()
150150
: MultiRangeReadResponse.createDataResponse(iterator, this);
151151
}
152152

153+
@Override
154+
public boolean isSinglePartition()
155+
{
156+
return dataRanges.size() == 1 && dataRanges.get(0).isSinglePartition();
157+
}
158+
153159
/**
154160
* @return all token ranges to be queried
155161
*/

src/java/org/apache/cassandra/db/PartitionRangeReadCommand.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,12 @@ public static PartitionRangeReadCommand allDataRead(TableMetadata metadata, long
188188
false);
189189
}
190190

191+
@Override
192+
public boolean isSinglePartition()
193+
{
194+
return dataRange.isSinglePartition();
195+
}
196+
191197
public ClusteringIndexFilter clusteringIndexFilter(DecoratedKey key)
192198
{
193199
return dataRange.clusteringIndexFilter(key);

src/java/org/apache/cassandra/db/ReadCommand.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,12 +295,25 @@ public Index.QueryPlan indexQueryPlan()
295295
return indexQueryPlan;
296296
}
297297

298+
/**
299+
* @return {@code true} if this command uses index-based filtering, {@code false} otherwise
300+
*/
301+
public boolean usesIndexFiltering()
302+
{
303+
return indexQueryPlan != null && indexQueryPlan.usesIndexFiltering();
304+
}
305+
298306
@Override
299307
public boolean isTopK()
300308
{
301309
return indexQueryPlan != null && indexQueryPlan.isTopK();
302310
}
303311

312+
/**
313+
* @return {@code true} if this command only queries a single partition, {@code false} otherwise.
314+
*/
315+
public abstract boolean isSinglePartition();
316+
304317
@VisibleForTesting
305318
public Index.Searcher indexSearcher()
306319
{

src/java/org/apache/cassandra/db/SinglePartitionReadCommand.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,12 @@ public SinglePartitionReadCommand forPaging(Clustering<?> lastReturned, DataLimi
473473
return cmd;
474474
}
475475

476+
@Override
477+
public boolean isSinglePartition()
478+
{
479+
return true;
480+
}
481+
476482
@Override
477483
public PartitionIterator execute(ConsistencyLevel consistency, ClientState state, Dispatcher.RequestTime requestTime) throws RequestExecutionException
478484
{

src/java/org/apache/cassandra/index/Index.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1186,6 +1186,14 @@ default boolean supportsMultiRangeReadCommand()
11861186
{
11871187
return false;
11881188
}
1189+
1190+
/**
1191+
* @return {@code true} if this plan uses index-based filtering, {@code false} otherwise
1192+
*/
1193+
default boolean usesIndexFiltering()
1194+
{
1195+
return true;
1196+
}
11891197
}
11901198

11911199
/*

src/java/org/apache/cassandra/index/sai/QueryContext.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ public class QueryContext
6666
private float annRerankFloor = 0.0f; // only called from single-threaded setup code
6767

6868
private final LongAdder shadowedPrimaryKeyCount = new LongAdder();
69+
private final LongAdder postFilteringReadLatency = new LongAdder();
6970

7071
// Determines the order of using indexes for filtering and sorting.
7172
// Null means the query execution order hasn't been decided yet.
@@ -146,6 +147,11 @@ public void addAnnGraphSearchLatency(long val)
146147
annGraphSearchLatency.add(val);
147148
}
148149

150+
public void addPostFilteringReadLatency(long val)
151+
{
152+
postFilteringReadLatency.add(val);
153+
}
154+
149155
public void setFilterSortOrder(FilterSortOrder filterSortOrder)
150156
{
151157
this.filterSortOrder = filterSortOrder;
@@ -247,6 +253,11 @@ public void updateAnnRerankFloor(float observedFloor)
247253
annRerankFloor = max(annRerankFloor, observedFloor);
248254
}
249255

256+
public long getPostFilteringReadLatency()
257+
{
258+
return postFilteringReadLatency.longValue();
259+
}
260+
250261
/**
251262
* Determines the order of filtering and sorting operations.
252263
* Currently used only by vector search.

0 commit comments

Comments
 (0)