@@ -111,6 +111,8 @@ const (
111111 regionLabelGCInterval = time .Hour
112112 // storageSizeCollectorInterval is the interval to run storage size collector.
113113 storageSizeCollectorInterval = time .Minute
114+ // dfsStatsCollectorInterval is the interval to run store stats collector.
115+ dfsStatsCollectorInterval = time .Minute
114116
115117 // minSnapshotDurationSec is the minimum duration that a store can tolerate.
116118 // It should enlarge the limiter if the snapshot's duration is less than this value.
@@ -403,7 +405,7 @@ func (c *RaftCluster) Start(s Server, bootstrap bool) (err error) {
403405 }
404406 }
405407 c .checkSchedulingService ()
406- c .wg .Add (11 )
408+ c .wg .Add (12 )
407409 go c .runServiceCheckJob ()
408410 go c .runMetricsCollectionJob ()
409411 go c .runNodeStateCheckJob ()
@@ -415,6 +417,7 @@ func (c *RaftCluster) Start(s Server, bootstrap bool) (err error) {
415417 go c .startGCTuner ()
416418 go c .startProgressGC ()
417419 go c .runStorageSizeCollector (s .GetMeteringWriter (), c .regionLabeler , s .GetKeyspaceManager ())
420+ go c .runDFSStatsCollector (s .GetMeteringWriter (), s .GetKeyspaceManager ())
418421
419422 c .running = true
420423 c .heartbeatRunner .Start (c .ctx )
@@ -2626,3 +2629,83 @@ func (c *RaftCluster) collectStorageSize(
26262629 zap .Int ("count" , len (storageSizeInfoList )))
26272630 return storageSizeInfoList
26282631}
2632+
2633+ // runDFSStatsCollector runs the DFS (Distributed File System) stats collector for the metering.
2634+ func (c * RaftCluster ) runDFSStatsCollector (
2635+ writer * metering.Writer ,
2636+ keyspaceManager * keyspace.Manager ,
2637+ ) {
2638+ defer logutil .LogPanic ()
2639+ defer c .wg .Done ()
2640+
2641+ if writer == nil {
2642+ log .Info ("no metering writer provided, the dfs stats collector will not be started" )
2643+ return
2644+ }
2645+ log .Info ("running the dfs stats collector" )
2646+ // Init and register the collector before starting the loop.
2647+ collector := newDfsStatsCollector ()
2648+ writer .RegisterCollector (collector )
2649+ // Start the ticker to collect the DFS stats data periodically.
2650+ ticker := time .NewTicker (dfsStatsCollectorInterval )
2651+ defer ticker .Stop ()
2652+
2653+ for {
2654+ select {
2655+ case <- c .ctx .Done ():
2656+ log .Info ("dfs stats collector has been stopped" )
2657+ return
2658+ case <- ticker .C :
2659+ keyspaceDFSStats := c .collectDfsStats (keyspaceManager )
2660+ collector .Collect (keyspaceDFSStats )
2661+ }
2662+ }
2663+ }
2664+
2665+ type keyspaceDFSStatsKey struct {
2666+ keyspaceName string
2667+ component string
2668+ }
2669+
2670+ type keyspaceDFSStatsMap map [keyspaceDFSStatsKey ]* core.DFSStats
2671+
2672+ func (c * RaftCluster ) collectDfsStats (keyspaceManager * keyspace.Manager ) keyspaceDFSStatsMap {
2673+ var (
2674+ keyspaceDFSStats = make (keyspaceDFSStatsMap , 0 )
2675+ keyspaceName string
2676+ err error
2677+ )
2678+ for _ , store := range c .GetStores () {
2679+ scopedDFSStats := store .TakeScopedDFSStats ()
2680+ if len (scopedDFSStats ) == 0 {
2681+ continue
2682+ }
2683+ // Merge into the keyspace DFS stats.
2684+ for scope , stats := range scopedDFSStats {
2685+ // Set the keyspace name to empty string for global scope.
2686+ if scope .GetIsGlobal () {
2687+ keyspaceName = ""
2688+ } else {
2689+ keyspaceName , err = keyspaceManager .GetKeyspaceNameByID (scope .GetKeyspaceId ())
2690+ if err != nil {
2691+ continue
2692+ }
2693+ }
2694+ key := keyspaceDFSStatsKey {
2695+ keyspaceName : keyspaceName ,
2696+ component : scope .GetComponent (),
2697+ }
2698+ dfsStats , ok := keyspaceDFSStats [key ]
2699+ if ok {
2700+ dfsStats .WrittenBytes += stats .WrittenBytes
2701+ dfsStats .WriteRequests += stats .WriteRequests
2702+ } else {
2703+ keyspaceDFSStats [key ] = & core.DFSStats {
2704+ WrittenBytes : stats .WrittenBytes ,
2705+ WriteRequests : stats .WriteRequests ,
2706+ }
2707+ }
2708+ }
2709+ }
2710+ return keyspaceDFSStats
2711+ }
0 commit comments