Skip to content

[server] Support DescribeTabletServers API for safe scaling and upgrades - #3743

Open
morazow wants to merge 3 commits into
apache:mainfrom
morazow:describe-tablet-servers-3570
Open

[server] Support DescribeTabletServers API for safe scaling and upgrades#3743
morazow wants to merge 3 commits into
apache:mainfrom
morazow:describe-tablet-servers-3570

Conversation

@morazow

@morazow morazow commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Adds a read-only DescribeTabletServers RPC to the Coordinator, following the pattern of GetClusterHealth ([server] Support Cluster Health API for safe rolling upgrades #3399 / [server] Add Cluster Health API implementation #3400).
  • New Admin.describeTabletServers() (@PublicEvolving) returns, per tablet server, the same four counters getClusterHealth() reports cluster-wide, scoped to that server: numReplicas, inSyncReplicas, numLeaderReplicas, activeLeaderReplicas.
  • Counters are computed from in-memory CoordinatorContext state on the coordinator event thread (via AccessContextEvent); tablet servers forward the request to the coordinator over the internal listener.
  • Live and shutting-down servers are always reported (even with zero replicas), and dead servers still holding assigned replicas remain visible, so a scale-in gate cannot treat them as drained.
  • This backs the Kubernetes Operator FIP's serverGreen(serverId) rolling-upgrade gate, the scale-in safety gate (numReplicas == 0), and per-server tablet load reporting.

Fixes #3570

Test Plan

  • New unit test DescribeTabletServersTest (fluss-server) covering: empty cluster, full ISR, out-of-ISR replicas, inactive leaders, leaderless buckets, evacuated servers, dead-but-assigned servers, partitioned tables, and reconciliation of per-server sums with computeClusterHealth.
  • New ITCase FlussAdminITCase#testDescribeTabletServersDuringRollingUpgrade: healthy cluster is green and sums match cluster health; a stopped server stays reported, non-empty and non-green; after restart all servers become green again.
  • mvn spotless:check clean on fluss-rpc, fluss-server, fluss-client, fluss-flink-common.

🤖 AI-assisted changes - reviewed by human developer

@morazow
morazow force-pushed the describe-tablet-servers-3570 branch 2 times, most recently from 8df1402 to b3d64f5 Compare July 23, 2026 06:40
…upgrades

Add a read-only DescribeTabletServers RPC to the Coordinator, following
the pattern of GetClusterHealth (apache#3399). It returns, per tablet server,
the same four counters getClusterHealth() reports cluster-wide, scoped
to that server: numReplicas, inSyncReplicas, numLeaderReplicas and
activeLeaderReplicas.

This lets operational tooling (e.g. the Fluss Kubernetes Operator):
- gate scale-in on a server being empty (numReplicas == 0),
- gate rolling upgrades on a per-server green predicate
  (inSyncReplicas == numReplicas && activeLeaderReplicas == numLeaderReplicas),
- report per-server tablet load in cluster status.

The counters are computed from in-memory CoordinatorContext state on
the coordinator event thread via AccessContextEvent. Tablet servers
forward the request to the coordinator. Live and shutting-down servers
are always reported, even with zero replicas, and dead servers that
still hold assigned replicas remain visible so a scale-in gate cannot
treat them as drained.

Closes apache#3570
@morazow
morazow force-pushed the describe-tablet-servers-3570 branch from b3d64f5 to 2aad05f Compare July 23, 2026 12:20
@morazow
morazow marked this pull request as ready for review July 23, 2026 14:12

@affo affo left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Matches the expectations for unlocking a detailed description of the tablet server and assessing a server health on a per-server basis.

Thanks for this contribution!

@affo affo left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@morazow and the community.
I also noticed that there is no way as of now to list the tags of servers, I do wonder if would be the right place to do that in your opinion :)

@morazow

morazow commented Jul 31, 2026

Copy link
Copy Markdown
Contributor Author

@affo good idea! So you think it makes sense as follow up PR or fine to add here?

@affo

affo commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

@morazow I would directly include that in this PR, as semantically it would make sense as we "describe" tablet servers. But I would also like to have an additional feedback on this one as well 🤝

Expose the ServerTag (PERMANENT_OFFLINE / TEMPORARY_OFFLINE) of each
tablet server in the DescribeTabletServers response, since there was no
read API for tags set via addServerTag. A tagged server is reported
even when it is dead and hosts no replicas, so its tag stays visible.

@fresh-borzoni fresh-borzoni left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@morazow Thank you for the PR!
Reading this alongside #1410 and #4061, the split looks like:
#1410 DescribeCluster for topology + ServerTag, getClusterHealth for aggregates, this one for per-server counters
#4061 the cache both health APIs read from.

If it holds, two things follow here: the tag commit is redundant with #1410, and both PRs currently claim ApiKey 1065 so one needs renumbering.

I'd hold the API-shape questions until that settles rather than have you redo work.

let me know when it settles, so I can help with API-shape

assertThat(isServerGreen(server)).isTrue();
}

// The per-server counters must sum up to the cluster-wide health counters.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A leaderless bucket is counted by cluster health but by no server here, so these sums can differ while every server still looks green. The waitUntil above doesn't rule that out. testPerServerSumsReconcileWithClusterHealth already covers this.
Do we need it?

@affo

affo commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

@fresh-borzoni at issue #1389 we conducted quite a big discussion also on the performance of this call given that it runs in the coordinator loop itself.

This led me to shape in draft a PR for an health cache that can be used by both cluster health and per-tablet health: #4061.

The cache uses a new mechanism thought for the performance updates, a new CoalescingRefreshCache class that embeds the logic for no-read-lock, but write lock, and enhances the logic to allow for different dirty states to optimize heavy updates on the coordinator side.

The same mechanism can be re-used across caches as well.

What would you guys think (@fresh-borzoni , @morazow )?

In case that one seems like a good approach we can:

  • rebase this one and wire the cache mechanism
  • on the second thing for server tags, yeah we already agreed on that issue that that should stay in getServerNodes, my only point was not to perform a direct ZK blocking call but to re-use the cache.

I re-read your comment above and realized you are aware of #4061 🤝 😅 , I misread at the beginning.
If you may also give feedback to that one now that you have the whole context it would be amazing 🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[server] Support DescribeTabletServers API for safe scaling and rolling upgrades

3 participants