Skip to content

Commit c3d41ff

Browse files
committed
roachpb: add proto changes for NodeCapacity
This commit adds new proto changes to NodeCapacity to track CPU usage and capacity at the node level. These metrics will be populated in the store descriptor before it is gossiped. MMA will use them from gossiped store descriptors to construct store load messages and compute utilization ratios across multiple dimensions. Epic: none Release note: none
1 parent 2af2f2d commit c3d41ff

File tree

2 files changed

+95
-0
lines changed

2 files changed

+95
-0
lines changed

pkg/roachpb/metadata.proto

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,35 @@ message Percentiles {
284284
optional double pMax = 6 [(gogoproto.nullable) = false];
285285
}
286286

287+
// NodeCapacity tracks CPU usage and capacity metrics at the node level. This
288+
// information is populated in the store descriptor before it is gossiped across
289+
// the network. MMA uses these metrics from gossiped store descriptors to
290+
// construct store load messages and calculate utilization ratios across
291+
// different dimensions.
292+
// TODO(wenyihu6): This field is currently unused and not populated. Populate
293+
// this field correctly and use it in MMA.
294+
message NodeCapacity {
295+
// StoresCPURate is the total CPU usage across all stores on this node,
296+
// measured in nanoseconds per second. It is calculated by summing the CPU
297+
// time of all replicas on the node, as tracked in replica stats.
298+
optional int64 stores_cpu_rate = 1 [(gogoproto.nullable) = false, (gogoproto.customname) = "StoresCPURate"];
299+
300+
// NumStores is the count of stores on this node over which StoresCPURate is
301+
// aggregated.
302+
optional int32 num_stores = 2 [(gogoproto.nullable) = false];
303+
304+
// NodeCPURateUsage is the node's actual CPU usage in ns/sec, measured by the
305+
// runtime load monitor tracking user+system CPU time. This is typically
306+
// higher than StoresCPURate gaps in the fine-grained instrumentation used to
307+
// compute StoresCPURate.
308+
optional int64 node_cpu_rate_usage = 3 [(gogoproto.nullable) = false, (gogoproto.customname) = "NodeCPURateUsage"];
309+
310+
// NodeCPURateCapacity is the node's total CPU capacity in nanoseconds per
311+
// sec, calculated by the runtime load monitor based on number of logical CPU
312+
// processors available for use by the processor.
313+
optional int64 node_cpu_rate_capacity = 4 [(gogoproto.nullable) = false, (gogoproto.customname) = "NodeCPURateCapacity"];
314+
}
315+
287316
// StoreCapacity contains capacity information for a storage device.
288317
message StoreCapacity {
289318
option (gogoproto.goproto_stringer) = false;
@@ -412,6 +441,7 @@ message StoreDescriptor {
412441
optional NodeDescriptor node = 3 [(gogoproto.nullable) = false];
413442
optional StoreCapacity capacity = 4 [(gogoproto.nullable) = false];
414443
optional StoreProperties properties = 5 [(gogoproto.nullable) = false];
444+
optional NodeCapacity node_capacity = 6 [(gogoproto.nullable) = false];
415445
}
416446

417447
// Locality is an ordered set of key value Tiers that describe a node's

pkg/roachpb/metadata_test.go

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -850,3 +850,68 @@ func TestRangeDescriptorsByStartKey(t *testing.T) {
850850
}
851851
}
852852
}
853+
854+
// TestNodeCapacity tests the NodeCapacity struct.
855+
func TestNodeCapacity(t *testing.T) {
856+
t.Run("basic", func(t *testing.T) {
857+
actual := NodeCapacity{
858+
StoresCPURate: 1,
859+
NumStores: 1,
860+
NodeCPURateUsage: 800000000,
861+
NodeCPURateCapacity: 10,
862+
}
863+
require.Equal(t, int64(1), actual.StoresCPURate)
864+
require.Equal(t, int32(1), actual.NumStores)
865+
require.Equal(t, int64(800000000), actual.NodeCPURateUsage)
866+
require.Equal(t, int64(10), actual.NodeCPURateCapacity)
867+
})
868+
869+
t.Run("zero values", func(t *testing.T) {
870+
actual := NodeCapacity{}
871+
require.Equal(t, int64(0), actual.StoresCPURate)
872+
require.Equal(t, int32(0), actual.NumStores)
873+
require.Equal(t, int64(0), actual.NodeCPURateUsage)
874+
require.Equal(t, int64(0), actual.NodeCPURateCapacity)
875+
})
876+
877+
t.Run("equality", func(t *testing.T) {
878+
nc1 := NodeCapacity{
879+
StoresCPURate: 1000000000,
880+
NumStores: 3,
881+
NodeCPURateUsage: 800000000,
882+
NodeCPURateCapacity: 1000000000,
883+
}
884+
nc2 := nc1
885+
require.Equal(t, nc1, nc2)
886+
require.Equal(t, int64(1000000000), nc2.StoresCPURate)
887+
require.Equal(t, int32(3), nc2.NumStores)
888+
require.Equal(t, int64(800000000), nc2.NodeCPURateUsage)
889+
require.Equal(t, int64(1000000000), nc2.NodeCPURateCapacity)
890+
})
891+
892+
t.Run("wrap in store descriptor", func(t *testing.T) {
893+
nc := NodeCapacity{
894+
StoresCPURate: 1000000000,
895+
NumStores: 3,
896+
NodeCPURateUsage: 800000000,
897+
NodeCPURateCapacity: 1000000000,
898+
}
899+
900+
storeDesc := StoreDescriptor{
901+
StoreID: 1,
902+
Node: NodeDescriptor{
903+
NodeID: 1,
904+
},
905+
Capacity: StoreCapacity{
906+
Capacity: 1000000000,
907+
Available: 500000000,
908+
RangeCount: 100,
909+
},
910+
NodeCapacity: nc,
911+
}
912+
require.Equal(t, int64(1000000000), storeDesc.NodeCapacity.StoresCPURate)
913+
require.Equal(t, int32(3), storeDesc.NodeCapacity.NumStores)
914+
require.Equal(t, int64(800000000), storeDesc.NodeCapacity.NodeCPURateUsage)
915+
require.Equal(t, int64(1000000000), storeDesc.NodeCapacity.NodeCPURateCapacity)
916+
})
917+
}

0 commit comments

Comments
 (0)