kfaraz commented on code in PR #19537:
URL: https://github.com/apache/druid/pull/19537#discussion_r3680574017


##########
server/src/main/java/org/apache/druid/client/selector/ServerSelector.java:
##########
@@ -190,16 +192,123 @@ public List<DruidServerMetadata> 
getAllServers(CloneQueryMode cloneQueryMode)
   }
 
   @Nullable
-  public <T> QueryableDruidServer pick(@Nullable Query<T> query, 
CloneQueryMode cloneQueryMode)
+  public <T> QueryableDruidServer pick(@Nullable final Query<T> query, final 
CloneQueryMode cloneQueryMode)
+  {
+    return pick(query, cloneQueryMode, getQueryableHistoricalTiers(query));
+  }
+
+  @Nullable
+  public <T> QueryableDruidServer pick(
+      @Nullable final Query<T> query,
+      final CloneQueryMode cloneQueryMode,
+      @Nullable final Set<String> queryableHistoricalTiers
+  )
   {
     synchronized (this) {
-      if (!historicalServers.isEmpty()) {
-        return historicalTierStrategy.pick(query, 
filter.getQueryableServers(historicalServers, cloneQueryMode), segment.get());
+      if (queryableHistoricalTiers != null && 
queryableHistoricalTiers.isEmpty()) {
+        return null;
+      }
+      if (!historicalServers.isEmpty() || queryableHistoricalTiers != null) {
+        final Int2ObjectRBTreeMap<Set<QueryableDruidServer>> 
queryableHistoricalServers =
+            getQueryableHistoricalServers(
+                filter.getQueryableServers(historicalServers, cloneQueryMode),
+                queryableHistoricalTiers
+            );
+        return historicalTierStrategy.pick(query, queryableHistoricalServers, 
segment.get());
       }
       return realtimeTierStrategy.pick(query, realtimeServers, segment.get());
     }
   }
 
+  public <T> boolean hasQueryableServer(@Nullable final Query<T> query, final 
CloneQueryMode cloneQueryMode)
+  {
+    return hasQueryableServer(getQueryableHistoricalTiers(query), 
cloneQueryMode);
+  }
+
+  public boolean hasQueryableServer(

Review Comment:
   Please add a short javadoc.



##########
server/src/main/java/org/apache/druid/client/selector/ServerSelector.java:
##########
@@ -190,16 +192,123 @@ public List<DruidServerMetadata> 
getAllServers(CloneQueryMode cloneQueryMode)
   }
 
   @Nullable
-  public <T> QueryableDruidServer pick(@Nullable Query<T> query, 
CloneQueryMode cloneQueryMode)
+  public <T> QueryableDruidServer pick(@Nullable final Query<T> query, final 
CloneQueryMode cloneQueryMode)
+  {
+    return pick(query, cloneQueryMode, getQueryableHistoricalTiers(query));
+  }
+
+  @Nullable
+  public <T> QueryableDruidServer pick(
+      @Nullable final Query<T> query,
+      final CloneQueryMode cloneQueryMode,
+      @Nullable final Set<String> queryableHistoricalTiers
+  )
   {
     synchronized (this) {
-      if (!historicalServers.isEmpty()) {
-        return historicalTierStrategy.pick(query, 
filter.getQueryableServers(historicalServers, cloneQueryMode), segment.get());
+      if (queryableHistoricalTiers != null && 
queryableHistoricalTiers.isEmpty()) {

Review Comment:
   This check can be done before the `synchronized` block.



##########
server/src/main/java/org/apache/druid/client/selector/ServerSelector.java:
##########
@@ -190,16 +192,123 @@ public List<DruidServerMetadata> 
getAllServers(CloneQueryMode cloneQueryMode)
   }
 
   @Nullable
-  public <T> QueryableDruidServer pick(@Nullable Query<T> query, 
CloneQueryMode cloneQueryMode)
+  public <T> QueryableDruidServer pick(@Nullable final Query<T> query, final 
CloneQueryMode cloneQueryMode)
+  {
+    return pick(query, cloneQueryMode, getQueryableHistoricalTiers(query));
+  }
+
+  @Nullable
+  public <T> QueryableDruidServer pick(
+      @Nullable final Query<T> query,
+      final CloneQueryMode cloneQueryMode,
+      @Nullable final Set<String> queryableHistoricalTiers
+  )
   {
     synchronized (this) {
-      if (!historicalServers.isEmpty()) {
-        return historicalTierStrategy.pick(query, 
filter.getQueryableServers(historicalServers, cloneQueryMode), segment.get());
+      if (queryableHistoricalTiers != null && 
queryableHistoricalTiers.isEmpty()) {
+        return null;
+      }
+      if (!historicalServers.isEmpty() || queryableHistoricalTiers != null) {
+        final Int2ObjectRBTreeMap<Set<QueryableDruidServer>> 
queryableHistoricalServers =
+            getQueryableHistoricalServers(
+                filter.getQueryableServers(historicalServers, cloneQueryMode),
+                queryableHistoricalTiers

Review Comment:
   It would probably make more sense to pass the list of queryable tiers into 
the `filter.getQueryableServers` since the function seems very closely related.
   This would allow us to keep the server filtration logic in a single place, 
and will also provide an easy way for tier alias expansion in 
`BrokerViewOfCoordinatorConfig`, which is an impl of the `HistoricalFilter`.



##########
docs/querying/query-context-reference.md:
##########
@@ -68,9 +68,10 @@ Unless otherwise noted, the following parameters apply to 
all query types, and t
 |`useFilterCNF`|`false`| If true, Druid will attempt to convert the query 
filter to Conjunctive Normal Form (CNF). During query processing, columns can 
be pre-filtered by intersecting the bitmap indexes of all values that match the 
eligible filters, often greatly reducing the raw number of rows which need to 
be scanned. But this effect only happens for the top level filter, or 
individual clauses of a top level 'and' filter. As such, filters in CNF 
potentially have a higher chance to utilize a large amount of bitmap indexes on 
string columns during pre-filtering. However, this setting should be used with 
great caution, as it can sometimes have a negative effect on performance, and 
in some cases, the act of computing CNF of a filter can be expensive. We 
recommend hand tuning your filters to produce an optimal form if possible, or 
at least verifying through experimentation that using this parameter actually 
improves your query performance with no ill-effects.|
 |`secondaryPartitionPruning`|`true`|Enable secondary partition pruning on the 
Broker. The Broker will always prune unnecessary segments from the input scan 
based on a filter on time intervals, but if the data is further partitioned 
with hash or range partitioning, this option will enable additional pruning 
based on a filter on secondary partition dimensions.|
 |`debug`| `false` | Flag indicating whether to enable debugging outputs for 
the query. When set to false, no additional logs will be produced (logs 
produced will be entirely dependent on your logging level). When set to true, 
the following addition logs will be produced:<br />- Log the stack trace of the 
exception (if any) produced by the query |
-|`setProcessingThreadNames`|`false`| Flag indicating whether processing thread 
names will be set to `processing_<queryId>` while processing a query. Thread 
renaming aids in interpreting thread dumps, but has measurable thread renaming 
overhead when segment scans are very quick. |
+|`setProcessingThreadNames`|`true`| Whether processing thread names will be 
set to `queryType_dataSource_intervals` while processing a query. This aids in 
interpreting thread dumps, and is on by default. Query overhead can be reduced 
slightly by setting this to `false`. This has a tiny effect in most scenarios, 
but can be meaningful in high-QPS, low-per-segment-processing-time scenarios. |
 |`sqlPlannerBloat`|`1000`|Calcite parameter which controls whether to merge 
two Project operators when inlining expressions causes complexity to increase. 
Implemented as a workaround to exception `There are not enough rules to produce 
a node with desired properties: convention=DRUID, sort=[]` thrown after 
rejecting the merge of two projects.|
 |`cloneQueryMode`|`excludeClones`| Indicates whether clone Historicals should 
be queried by brokers. Clone servers are created by the `cloneServers` 
Coordinator dynamic configuration. Possible values are `excludeClones`, 
`includeClones` and `preferClones`. `excludeClones` means that clone 
Historicals are not queried by the broker. `preferClones` indicates that when 
given a choice between the clone Historical and the original Historical which 
is being cloned, the broker chooses the clones. Historicals which are not 
involved in the cloning process will still be queried. `includeClones` means 
that broker queries any Historical without regarding clone status. This 
parameter only affects native queries. MSQ does not query Historicals directly.|
+|`queryableHistoricalTiers`|`null`|Set of Historical tier names that may be 
queried. When set, the Broker only queries Historical servers whose 
`druid.server.tier` is in this set. Segments without a replica on one of the 
listed tiers are skipped.|

Review Comment:
   Does this also need to mention that tier aliases may be used instead of 
actual tier names?



##########
server/src/main/java/org/apache/druid/client/selector/ServerSelector.java:
##########
@@ -190,16 +192,123 @@ public List<DruidServerMetadata> 
getAllServers(CloneQueryMode cloneQueryMode)
   }
 
   @Nullable
-  public <T> QueryableDruidServer pick(@Nullable Query<T> query, 
CloneQueryMode cloneQueryMode)
+  public <T> QueryableDruidServer pick(@Nullable final Query<T> query, final 
CloneQueryMode cloneQueryMode)
+  {
+    return pick(query, cloneQueryMode, getQueryableHistoricalTiers(query));
+  }
+
+  @Nullable
+  public <T> QueryableDruidServer pick(
+      @Nullable final Query<T> query,
+      final CloneQueryMode cloneQueryMode,
+      @Nullable final Set<String> queryableHistoricalTiers
+  )
   {
     synchronized (this) {
-      if (!historicalServers.isEmpty()) {
-        return historicalTierStrategy.pick(query, 
filter.getQueryableServers(historicalServers, cloneQueryMode), segment.get());
+      if (queryableHistoricalTiers != null && 
queryableHistoricalTiers.isEmpty()) {
+        return null;
+      }
+      if (!historicalServers.isEmpty() || queryableHistoricalTiers != null) {
+        final Int2ObjectRBTreeMap<Set<QueryableDruidServer>> 
queryableHistoricalServers =
+            getQueryableHistoricalServers(
+                filter.getQueryableServers(historicalServers, cloneQueryMode),
+                queryableHistoricalTiers
+            );
+        return historicalTierStrategy.pick(query, queryableHistoricalServers, 
segment.get());
       }
       return realtimeTierStrategy.pick(query, realtimeServers, segment.get());
     }
   }
 
+  public <T> boolean hasQueryableServer(@Nullable final Query<T> query, final 
CloneQueryMode cloneQueryMode)
+  {
+    return hasQueryableServer(getQueryableHistoricalTiers(query), 
cloneQueryMode);
+  }
+
+  public boolean hasQueryableServer(
+      @Nullable final Set<String> queryableHistoricalTiers,
+      final CloneQueryMode cloneQueryMode
+  )
+  {
+    synchronized (this) {
+      if (queryableHistoricalTiers != null) {

Review Comment:
   This check can happen outside the `synchronized` block.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to