feat(info): report command statistics per namespace#3557
Conversation
Track command calls, latency, and histograms per namespace and report them in INFO (stats, commandstats) and LATENCY HISTOGRAM scoped to the caller's namespace; the admin/default namespace sees the aggregate across all of them. Closes apache#755 Assisted-by: Claude Code Signed-off-by: nhancdt <nhancu2602@gmail.com>
|
@PragmaTwice I'd love to hear your thought about this change. Especially, some stats still stay global in this PR for the sack of simplicity. |
|
@jihuayu Thanks for running the CI pipeline. The only failing test is: This seems unrelated to the PR change. (as it was reported as flaky test in #3515). Could you kindly re-run the pipeline again? |
There was a problem hiding this comment.
Pull request overview
This PR adds per-namespace command statistics so that INFO (Stats/CommandStats) and LATENCY HISTOGRAM report metrics scoped to the caller’s namespace, while the default/admin namespace view returns an aggregate across all namespaces.
Changes:
- Introduces a per-namespace
Statsmap inServer, with lazy creation and aggregation for the default/admin namespace view. - Records command call/latency stats into a connection-cached per-namespace
Statson the command execution hot path. - Adds a Go integration test validating namespace scoping, aggregation, and namespace deletion behavior.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/gocase/unit/info/info_test.go | Adds TestNamespaceStats to validate INFO/LATENCY stats scoping and aggregation semantics. |
| src/server/server.h | Extends Server APIs to accept namespace for Stats/CommandStats and adds per-namespace Stats storage/aggregation helpers. |
| src/server/server.cc | Implements per-namespace Stats creation, aggregation, and updates INFO sections to use namespace-aware sources. |
| src/server/redis_connection.h | Adds cached per-namespace Stats pointer on the connection object. |
| src/server/redis_connection.cc | Switches command stats recording to the connection’s cached per-namespace Stats. |
| src/commands/cmd_server.cc | Clears namespace stats on NAMESPACE DEL and makes LATENCY HISTOGRAM use namespace-aware histograms/aggregate. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
jihuayu
left a comment
There was a problem hiding this comment.
Hello @nhancdt2602.Thank you for your contribution. I think this PR still has a few issues.
- latency command is admin only. It will make the namespace user could not get it's latency.
kvrocks/src/commands/cmd_server.cc
Line 1827 in 634ed15
- Deleting a namespace does not disconnect existing connections. This causes the old connections’
ns_stats_references to diverge.
After authentication:
ns_stats_["ns1"] -> Stats A
Active connection -> Stats A
After deleting `ns1`:
ns_stats_ no longer contains ns1
Active connection -> Stats A // kept alive by shared_ptr
After the old connection executes `INFO`:
ns_stats_["ns1"] -> newly created Stats B
Active connection -> Stats A
- Deleting a namespace may cause an underflow here.
Lines 107 to 117 in 8c26549
|
@jihuayu Thanks for your reply. To fix points 2 and 3, can I keep the stats entry in the namespace map even after the namespace is deleted? This would be consistent with the current behavior of |
|
@jihuayu Regarding point 1, I’m still not sure I understand your concern. Are you suggesting that we should not expose latency and histogram metrics for namespace-scoped connections? |
|
@nhancdt2602 Sorry, I’m late.
I have no objection to that, since deleting a namespace is a low-frequency operation. What I meant is that this command should not be restricted to ADMIN users. Namespace users are not ADMIN users, so they would be unable to retrieve latency information. |
@jihuayu Regarding point 1, LATENCY command already is scoped to ADMIN before this PR. If I'm not mistaken, you want to relax it by removing admin flag in LATENCY command config in this PR? |
LATENCY is no longer restricted to admin: a namespace connection can read the latency histogram scoped to its own namespace, while the admin/default namespace sees the aggregate across all namespaces. Assisted-by: Claude Opus 4.8 Signed-off-by: nhancdt <nhancu2602@gmail.com>
Stop erasing a namespace's Stats when the namespace is deleted (matching the existing db_scan_infos_ behavior). A connection still scoped to the deleted namespace then keeps updating the same, still-aggregated Stats rather than an orphaned copy, and the summed ops/sec reading stays monotonic, avoiding an unsigned underflow in TrackInstantaneousMetric. Also drops a few redundant comments. Assisted-by: Claude Opus 4.8 Signed-off-by: nhancdt <nhancu2602@gmail.com>
|
@jihuayu I've addressed all three points from your review. Looking for your feedback when you I have time.
|
|
@jihuayu Could you re-run the flaky test in CI pipeline again. All other tests pass. |
|
|
@nhancdt2602 It seems only the calls/latency are related to the namespace, so I'm wondering if it's better to extend the existing functions in void IncrCalls(const string &ns, const string &cmd) {
stats->total_calls++;
if (ns != kDefaultNamespace) {
stats->ns_command_calls[ns]++;
}
}so that we don't need to intercepting the stats and namespace in serval places. cc @jihuayu @PragmaTwice |
Thanks @git-hulk for your review. I saw your point about moving the namespace resolution logic into stats fields/methods like I want to keep the overhead of adding namespace telemetry information as minimal as possible. By keeping the namespace stats pointer when a connection is established, we are free of lock when accessing the namespace stat entry. That said, if you and project members prefer consolidating into Stats, accepting a per-command lock. I'm happy to refactor that way; just let me know the preferred trade-off. I'd love to hear your opinion about this ^^ |
@nhancdt2602 I'm not sure how much performance would be impacted. Consolidating into one stats would be more consistent from my personal perspective since only a few metrics are related to the namespace. |
|
@git-hulk I can relate your preference. From my side, I lean toward keeping the stat object scoped to namespace level and move the stat entry resolution to caller layer. However, I'm happy to apply your suggestion if it's the direction of the project. Shall I consolidate them or wait for others opinion ^^ |
We can wait for a while to see if other maintainers have any comments. |
@nhancdt2602 Do you mean the lock in this piece of code? |
@jihuayu Exactly. Or do you have any better ideas? |



Summary
This change tracks command calls, latency, and histograms per namespace. A namespaced connection sees its own numbers in INFO (Stats, CommandStats) and LATENCY HISTOGRAM; the admin/default namespace sees the aggregate across all namespaces.
Behavior:
INFO commandstats-> returns stats scoped by ns1 onlyINFO commandstats-> returns stats aggregated from all namespacesCloses #755.
Changes
ns_stats_field in the Server class (guarded by a shared_mutex), created lazily viaGetOrCreateNamespaceStats.GetStatsInfo,GetCommandsStatsInfo,LATENCY HISTOGRAMresolve their source by caller namespace, orAggregateNamespaceStats()for the admin/default view.Implementation notes
Test
unit/namespacemoduleunit/infomoduleAI disclosure