@@ -52,6 +52,7 @@ var Config = struct {
52
52
MaxIdleConnsPerHost int
53
53
54
54
ConcurrencyLimitPerServer int
55
+ ExpireDelaySec int32
55
56
}{
56
57
MaxProcs : 1 ,
57
58
IntervalSec : 60 ,
@@ -63,6 +64,8 @@ var Config = struct {
63
64
64
65
MaxIdleConnsPerHost : 100 ,
65
66
67
+ ExpireDelaySec : 10 * 60 , // 10 minutes
68
+
66
69
pathCache : pathCache {ec : expirecache .New (0 )},
67
70
}
68
71
@@ -81,8 +84,10 @@ var Metrics = struct {
81
84
82
85
Timeouts * expvar.Int
83
86
84
- CacheSize expvar.Func
85
- CacheItems expvar.Func
87
+ CacheSize expvar.Func
88
+ CacheItems expvar.Func
89
+ CacheMisses * expvar.Int
90
+ CacheHits * expvar.Int
86
91
}{
87
92
FindRequests : expvar .NewInt ("find_requests" ),
88
93
FindErrors : expvar .NewInt ("find_errors" ),
@@ -96,6 +101,9 @@ var Metrics = struct {
96
101
InfoErrors : expvar .NewInt ("info_errors" ),
97
102
98
103
Timeouts : expvar .NewInt ("timeouts" ),
104
+
105
+ CacheHits : expvar .NewInt ("cache_hits" ),
106
+ CacheMisses : expvar .NewInt ("cache_misses" ),
99
107
}
100
108
101
109
// BuildVersion is defined at build and reported at startup and as expvar
@@ -360,7 +368,10 @@ func findHandler(w http.ResponseWriter, req *http.Request) {
360
368
var backends []string
361
369
var ok bool
362
370
if backends , ok = Config .pathCache .get (tld ); ! ok || backends == nil || len (backends ) == 0 {
371
+ Metrics .CacheMisses .Add (1 )
363
372
backends = Config .Backends
373
+ } else {
374
+ Metrics .CacheHits .Add (1 )
364
375
}
365
376
366
377
responses := multiGet (backends , rewrite .RequestURI ())
@@ -375,9 +386,12 @@ func findHandler(w http.ResponseWriter, req *http.Request) {
375
386
metrics = append (metrics , m ... )
376
387
377
388
// update our cache of which servers have which metrics
389
+ allServers := make ([]string , 0 )
378
390
for k , v := range paths {
379
391
Config .pathCache .set (k , v )
392
+ allServers = append (allServers , v ... )
380
393
}
394
+ Config .pathCache .set (originalQuery , allServers )
381
395
}
382
396
383
397
encodeFindResponse (format , originalQuery , w , metrics )
@@ -467,7 +481,10 @@ func renderHandler(w http.ResponseWriter, req *http.Request) {
467
481
468
482
// lookup the server list for this metric, or use all the servers if it's unknown
469
483
if serverList , ok = Config .pathCache .get (target ); ! ok || serverList == nil || len (serverList ) == 0 {
484
+ Metrics .CacheMisses .Add (1 )
470
485
serverList = Config .Backends
486
+ } else {
487
+ Metrics .CacheHits .Add (1 )
471
488
}
472
489
473
490
responses = append (responses , multiGet (serverList , rewrite .RequestURI ())... )
@@ -477,7 +494,10 @@ func renderHandler(w http.ResponseWriter, req *http.Request) {
477
494
478
495
// lookup the server list for this metric, or use all the servers if it's unknown
479
496
if serverList , ok = Config .pathCache .get (target ); ! ok || serverList == nil || len (serverList ) == 0 {
497
+ Metrics .CacheMisses .Add (1 )
480
498
serverList = Config .Backends
499
+ } else {
500
+ Metrics .CacheHits .Add (1 )
481
501
}
482
502
483
503
responses = multiGet (serverList , rewrite .RequestURI ())
@@ -490,7 +510,7 @@ func renderHandler(w http.ResponseWriter, req *http.Request) {
490
510
return
491
511
}
492
512
493
- metrics := mergeResponses (req , responses )
513
+ servers , metrics := mergeResponses (req , responses )
494
514
if metrics == nil {
495
515
Metrics .RenderErrors .Add (1 )
496
516
err := fmt .Sprintf ("no decoded responses to merge for req: %s" , req .URL .RequestURI ())
@@ -499,6 +519,8 @@ func renderHandler(w http.ResponseWriter, req *http.Request) {
499
519
return
500
520
}
501
521
522
+ Config .pathCache .set (target , servers )
523
+
502
524
switch format {
503
525
case "protobuf3" :
504
526
w .Header ().Set ("Content-Type" , contentTypeProtobuf )
@@ -567,8 +589,9 @@ func createRenderResponse(metrics *pb3.MultiFetchResponse, missing interface{})
567
589
return response
568
590
}
569
591
570
- func mergeResponses (req * http.Request , responses []serverResponse ) * pb3.MultiFetchResponse {
592
+ func mergeResponses (req * http.Request , responses []serverResponse ) ([] string , * pb3.MultiFetchResponse ) {
571
593
594
+ servers := make ([]string , 0 , len (responses ))
572
595
metrics := make (map [string ][]pb3.FetchResponse )
573
596
574
597
for _ , r := range responses {
@@ -583,12 +606,13 @@ func mergeResponses(req *http.Request, responses []serverResponse) *pb3.MultiFet
583
606
for _ , m := range d .Metrics {
584
607
metrics [m .GetName ()] = append (metrics [m .GetName ()], * m )
585
608
}
609
+ servers = append (servers , r .server )
586
610
}
587
611
588
612
var multi pb3.MultiFetchResponse
589
613
590
614
if len (metrics ) == 0 {
591
- return nil
615
+ return servers , nil
592
616
}
593
617
594
618
for name , decoded := range metrics {
@@ -617,7 +641,7 @@ func mergeResponses(req *http.Request, responses []serverResponse) *pb3.MultiFet
617
641
multi .Metrics = append (multi .Metrics , & metric )
618
642
}
619
643
620
- return & multi
644
+ return servers , & multi
621
645
}
622
646
623
647
func mergeValues (req * http.Request , metric * pb3.FetchResponse , decoded []pb3.FetchResponse ) {
@@ -698,7 +722,10 @@ func infoHandler(w http.ResponseWriter, req *http.Request) {
698
722
699
723
// lookup the server list for this metric, or use all the servers if it's unknown
700
724
if serverList , ok = Config .pathCache .get (target ); ! ok || serverList == nil || len (serverList ) == 0 {
725
+ Metrics .CacheMisses .Add (1 )
701
726
serverList = Config .Backends
727
+ } else {
728
+ Metrics .CacheHits .Add (1 )
702
729
}
703
730
704
731
format := req .FormValue ("format" )
@@ -923,6 +950,8 @@ func main() {
923
950
924
951
graphite .Register (fmt .Sprintf ("carbon.zipper.%s.cache_size" , hostname ), Metrics .CacheSize )
925
952
graphite .Register (fmt .Sprintf ("carbon.zipper.%s.cache_items" , hostname ), Metrics .CacheItems )
953
+ graphite .Register (fmt .Sprintf ("carbon.zipper.%s.cache_hits" , hostname ), Metrics .CacheHits )
954
+ graphite .Register (fmt .Sprintf ("carbon.zipper.%s.cache_misses" , hostname ), Metrics .CacheMisses )
926
955
927
956
go mstats .Start (* interval )
928
957
@@ -1022,14 +1051,13 @@ type pathCache struct {
1022
1051
}
1023
1052
1024
1053
func (p * pathCache ) set (k string , v []string ) {
1025
- // expire cache entries after 10 minutes
1026
- const expireDelay = 60 * 10
1054
+ // expire cache entries after Config.ExpireCache minutes
1027
1055
var size uint64
1028
1056
for _ , vv := range v {
1029
1057
size += uint64 (len (vv ))
1030
1058
}
1031
1059
1032
- p .ec .Set (k , v , size , expireDelay )
1060
+ p .ec .Set (k , v , size , Config . ExpireDelaySec )
1033
1061
}
1034
1062
1035
1063
func (p * pathCache ) get (k string ) ([]string , bool ) {
0 commit comments