Skip to content

Commit 7b5bd39

Browse files
ctillercopybara-github
authored andcommitted
[channelz] Shard indices (grpc#39306)
Previously channelz kept an index of all objects in a global std::map protected by a single mutex. Instead: split the index in two. The first is a list of all base nodes, queryable on demand, sharded by pointer. These base nodes are available, but un-numbered. The id allocation then occurs whenever channelz is actually queried. At that point unnumbered nodes can be iterated and numbered sequentially, keeping that essential invariant for channelz pagination. In doing so, most nodes never need to hit a singleton global resource at all: the most they do is take a sharded lock and do a list insert/removal pair. (it turns out this code is a major source of contention in gRPC) Closes grpc#39306 COPYBARA_INTEGRATE_REVIEW=grpc#39306 from ctiller:counting-on-it a7a04c3 PiperOrigin-RevId: 750342301
1 parent 1f22c5f commit 7b5bd39

22 files changed

+421
-152
lines changed

BUILD

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1251,6 +1251,7 @@ grpc_cc_library(
12511251
],
12521252
external_deps = [
12531253
"absl/base:core_headers",
1254+
"absl/container:btree",
12541255
"absl/log",
12551256
"absl/log:check",
12561257
"absl/status:statusor",
@@ -1273,6 +1274,7 @@ grpc_cc_library(
12731274
"//src/core:per_cpu",
12741275
"//src/core:ref_counted",
12751276
"//src/core:resolved_address",
1277+
"//src/core:shared_bit_gen",
12761278
"//src/core:slice",
12771279
"//src/core:sync",
12781280
"//src/core:time",

CMakeLists.txt

Lines changed: 11 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

bazel/experiments.bzl

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

build_autogenerated.yaml

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

gRPC-C++.podspec

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

gRPC-Core.podspec

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

grpc.gemspec

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.xml

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/core/channelz/channelz.cc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,9 @@ BaseNode::BaseNode(EntityType type, std::string name)
168168
ChannelzRegistry::Register(this);
169169
}
170170

171-
BaseNode::~BaseNode() { ChannelzRegistry::Unregister(uuid_); }
171+
BaseNode::~BaseNode() { ChannelzRegistry::Unregister(this); }
172+
173+
intptr_t BaseNode::UuidSlow() { return ChannelzRegistry::NumberNode(this); }
172174

173175
std::string BaseNode::RenderJsonString() {
174176
Json json = RenderJson();

src/core/channelz/channelz.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,11 @@ class BaseNode : public RefCounted<BaseNode> {
141141
std::string RenderJsonString();
142142

143143
EntityType type() const { return type_; }
144-
intptr_t uuid() const { return uuid_; }
144+
intptr_t uuid() {
145+
const intptr_t id = uuid_.load(std::memory_order_relaxed);
146+
if (id > 0) return id;
147+
return UuidSlow();
148+
}
145149
const std::string& name() const { return name_; }
146150

147151
void RunZTrace(absl::string_view name, Timestamp deadline,
@@ -155,16 +159,20 @@ class BaseNode : public RefCounted<BaseNode> {
155159
void PopulateJsonFromDataSources(Json::Object& json);
156160

157161
private:
162+
intptr_t UuidSlow();
163+
158164
// to allow the ChannelzRegistry to set uuid_ under its lock.
159165
friend class ChannelzRegistry;
160166
// allow data source to register/unregister itself
161167
friend class DataSource;
162168
const EntityType type_;
163-
intptr_t uuid_;
169+
std::atomic<intptr_t> uuid_;
164170
std::string name_;
165171
Mutex data_sources_mu_;
166172
absl::InlinedVector<DataSource*, 3> data_sources_
167173
ABSL_GUARDED_BY(data_sources_mu_);
174+
BaseNode* prev_;
175+
BaseNode* next_;
168176
};
169177

170178
class ZTrace {

0 commit comments

Comments
 (0)