feat: add DruidNode deploymentGroup field to support R/B deployments#19413
feat: add DruidNode deploymentGroup field to support R/B deployments#19413jtuglu1 wants to merge 2 commits into
Conversation
95da3b9 to
b016aa3
Compare
…Druid deployments
b016aa3 to
7d9c627
Compare
FrankChen021
left a comment
There was a problem hiding this comment.
| Severity | Findings |
|---|---|
| P0 | 0 |
| P1 | 0 |
| P2 | 1 |
| P3 | 0 |
| Total | 1 |
This is an automated review by Codex GPT-5
FrankChen021
left a comment
There was a problem hiding this comment.
| Severity | Findings |
|---|---|
| P0 | 0 |
| P1 | 0 |
| P2 | 2 |
| P3 | 0 |
| Total | 2 |
This is an automated review by Codex GPT-5
30b4c6d to
95204a9
Compare
FrankChen021
left a comment
There was a problem hiding this comment.
| Severity | Findings |
|---|---|
| P0 | 0 |
| P1 | 0 |
| P2 | 1 |
| P3 | 0 |
| Total | 1 |
| Severity | Findings |
|---|---|
| P0 | 0 |
| P1 | 0 |
| P2 | 1 |
| P3 | 0 |
| Total | 1 |
Reviewed 33 of 33 changed files.
This is an automated review by Codex GPT-5.5
95204a9 to
059de00
Compare
FrankChen021
left a comment
There was a problem hiding this comment.
| Severity | Findings |
|---|---|
| P0 | 0 |
| P1 | 1 |
| P2 | 1 |
| P3 | 0 |
| Total | 2 |
Reviewed 35 of 35 changed files.
This is an automated review by Codex GPT-5.5
| } | ||
|
|
||
| final Set<String> watched = segmentWatcherConfig.getWatchedDeploymentGroups(); | ||
| if (watched != null && !watched.contains(server.getDeploymentGroup())) { |
There was a problem hiding this comment.
[P1] Propagate deploymentGroup through inventory DruidServer construction
This filter depends on DruidServerMetadata.getDeploymentGroup(), but the normal discovery inventory path still builds DruidServer instances through DruidServer constructors that do not pass DruidNode.getDeploymentGroup() into DruidServerMetadata. In a real cluster, Historicals therefore arrive here with a null deploymentGroup, so setting druid.broker.segment.watchedDeploymentGroups filters out all Historicals; the same lost metadata also prevents coordinator resources from seeing active deployment groups. Please preserve the DruidNode deploymentGroup when constructing inventory DruidServer metadata.
| (remainingSegmentsToMove + remainingGroups - 1) / remainingGroups; | ||
| if (groupMaxSegmentsToMove > 0) { | ||
| new TierSegmentBalancer(tier, groupServers, groupMaxSegmentsToMove, params).run(); | ||
| remainingSegmentsToMove -= groupMaxSegmentsToMove; |
There was a problem hiding this comment.
[P2] Do not consume unused balance budget
The per-group loop subtracts groupMaxSegmentsToMove even when TierSegmentBalancer moves zero segments. With maxSegmentsToMove lower than the number of groups, a first group that is already balanced can consume the whole budget every coordinator run, leaving later skewed groups with groupMaxSegmentsToMove == 0 indefinitely. This still honors the numeric cap, but can permanently prevent balancing in later deployment groups; base the budget on actual moves or rotate/fairly allocate across runs.
Description
Druid Deployment Overview
Currently, deployment in Druid is geared towards "rolling" deployments, which, while potentially cheaper/faster are not the safest deployment mechanisms due to the lack of isolation during new cluster bring-up.
A red/black (a.k.a blue/green) deployment is better suited for cases where you want to bring another Druid cluster up in isolation of the existing one (but in same ZK/K8s discoverability namespace) in order to perform safety/performance checks before cutting over to the new deployment. The Overlord already supports a similar concept of worker "versioning" where it will only schedule peons on MMs/Indexers that are running the version it itself is configured with (or higher), allowing the cluster to eventually drain the ASGs with older Druid versions.
However, this functionality gets us part of the way to supporting what's effectively a zero-downtime (both query + ingest) deployment. To achieve a fully isolated (with the exception of master nodes: {coordinator, overlord}) deployment environment where we can mirror queries, observe state, etc. we also need to support version-based routing of queries.
Requirements
To do this, we need two things:
Users cannot be impacted by data loading/unavailability issues when a node is rolled. This is especially pertinent in cases where there is no replica for a segment in a given tier, meaning rolling an instance requires either cloning() the historical first or taking downtime. This applies for both historical and realtime segments: we should be avoiding any/all data availability/freshness problems during deployment.
681cbde provided support for tier aliases (so duplicate historical tier deployments can be brought up transparently to the user/operator).
Since Druid queries are generally read-only, isolating the new cluster from user traffic until it is deemed "healthy" is critical to ensure no regressions are deployed. This is also particularly helpful in performing performance/load tests. This PR provides the query routing support to allow user queries to route to strictly
oldnodes (router/broker/historical/peon), and any traffic sent tonewnodes to route tonewrouter/broker/historical/peon.NB: we allow queries from both versions to hit old/new peons to allow for convenient roll-back and easier data availability properties when forcing task group hand-off. This behavior can be toggled via
druid.broker.segment.strictRealtimeDeploymentGroupFilter, where setting it totruewould imply realtime servers with non-matching versions would be excluded from query planning.Deployment Steps
The combination of these 2 changes support the following deployment process:
newDruid ASGs: router, broker, historical, coordinator, overlord, MM, etc.newDruid version coordinatornewrouter/broker will be able to query only historicals of their same version; peons are by default queryable by all versions).newrouter/broker/historicals.This deployment method combines the traditional red/black deployment with Druid's rolling deployment, providing zero ingest downtime as well as zero query downtime for users (both in terms of availability and data freshness). It also provides ample time to experiment/canary changes without impacting user traffic.
Release note
This PR has: