56
56
indexRulesFile string
57
57
IndexRules conf.IndexRules
58
58
Partitioned bool
59
+ findCacheSize = 1000
59
60
)
60
61
61
62
func ConfigSetup () {
@@ -65,6 +66,7 @@ func ConfigSetup() {
65
66
memoryIdx .BoolVar (& Partitioned , "partitioned" , false , "use separate indexes per partition" )
66
67
memoryIdx .IntVar (& TagQueryWorkers , "tag-query-workers" , 50 , "number of workers to spin up to evaluate tag queries" )
67
68
memoryIdx .IntVar (& matchCacheSize , "match-cache-size" , 1000 , "size of regular expression cache in tag query evaluation" )
69
+ memoryIdx .IntVar (& findCacheSize , "find-cache-size" , 1000 , "number of find expressions to cache" )
68
70
memoryIdx .StringVar (& indexRulesFile , "rules-file" , "/etc/metrictank/index-rules.conf" , "path to index-rules.conf file" )
69
71
memoryIdx .StringVar (& maxPruneLockTimeStr , "max-prune-lock-time" , "100ms" , "Maximum duration each second a prune job can lock the index." )
70
72
globalconf .Register ("memory-idx" , memoryIdx , flag .ExitOnError )
@@ -233,6 +235,8 @@ type UnpartitionedMemoryIdx struct {
233
235
// used by tag index
234
236
defByTagSet defByTagSet
235
237
tags map [uint32 ]TagIndex // by orgId
238
+
239
+ findCache * FindCache
236
240
}
237
241
238
242
func NewUnpartitionedMemoryIdx () * UnpartitionedMemoryIdx {
@@ -241,6 +245,7 @@ func NewUnpartitionedMemoryIdx() *UnpartitionedMemoryIdx {
241
245
defByTagSet : make (defByTagSet ),
242
246
tree : make (map [uint32 ]* Tree ),
243
247
tags : make (map [uint32 ]TagIndex ),
248
+ findCache : NewFindCache (findCacheSize ),
244
249
}
245
250
}
246
251
@@ -453,6 +458,11 @@ func (m *UnpartitionedMemoryIdx) add(def *schema.MetricDefinition) idx.Archive {
453
458
return * archive
454
459
}
455
460
461
+ // invalidate any findCache items that match this series name
462
+ defer func () {
463
+ go m .findCache .InvalidateFor (def .OrgId , path )
464
+ }()
465
+
456
466
//first check to see if a tree has been created for this OrgId
457
467
tree , ok := m .tree [def .OrgId ]
458
468
if ! ok || len (tree .Items ) == 0 {
@@ -943,18 +953,36 @@ func (m *UnpartitionedMemoryIdx) idsByTagQuery(orgId uint32, query TagQuery) IdS
943
953
944
954
func (m * UnpartitionedMemoryIdx ) Find (orgId uint32 , pattern string , from int64 ) ([]idx.Node , error ) {
945
955
pre := time .Now ()
956
+ var matchedNodes []* Node
957
+ var err error
946
958
m .RLock ()
947
959
defer m .RUnlock ()
948
- matchedNodes , err := m .find (orgId , pattern )
949
- if err != nil {
950
- return nil , err
960
+ tree , ok := m .tree [orgId ]
961
+ if ! ok {
962
+ log .Debugf ("memory-idx: orgId %d has no metrics indexed." , orgId )
963
+ } else {
964
+ matchedNodes , ok = m .findCache .Get (orgId , pattern )
965
+ if ! ok {
966
+ matchedNodes , err = find (tree , pattern )
967
+ if err != nil {
968
+ return nil , err
969
+ }
970
+ m .findCache .Add (orgId , pattern , matchedNodes )
971
+ }
951
972
}
952
973
if orgId != idx .OrgIdPublic && idx .OrgIdPublic > 0 {
953
- publicNodes , err := m .find (idx .OrgIdPublic , pattern )
954
- if err != nil {
955
- return nil , err
974
+ tree , ok = m .tree [idx .OrgIdPublic ]
975
+ if ok {
976
+ publicNodes , ok := m .findCache .Get (idx .OrgIdPublic , pattern )
977
+ if ! ok {
978
+ publicNodes , err = find (tree , pattern )
979
+ if err != nil {
980
+ return nil , err
981
+ }
982
+ m .findCache .Add (idx .OrgIdPublic , pattern , publicNodes )
983
+ }
984
+ matchedNodes = append (matchedNodes , publicNodes ... )
956
985
}
957
- matchedNodes = append (matchedNodes , publicNodes ... )
958
986
}
959
987
log .Debugf ("memory-idx: %d nodes matching pattern %s found" , len (matchedNodes ), pattern )
960
988
results := make ([]idx.Node , 0 )
@@ -997,14 +1025,8 @@ func (m *UnpartitionedMemoryIdx) Find(orgId uint32, pattern string, from int64)
997
1025
return results , nil
998
1026
}
999
1027
1000
- // find returns all Nodes matching the pattern for the given orgId
1001
- func (m * UnpartitionedMemoryIdx ) find (orgId uint32 , pattern string ) ([]* Node , error ) {
1002
- tree , ok := m .tree [orgId ]
1003
- if ! ok {
1004
- log .Debugf ("memory-idx: orgId %d has no metrics indexed." , orgId )
1005
- return nil , nil
1006
- }
1007
-
1028
+ // find returns all Nodes matching the pattern for the given tree
1029
+ func find (tree * Tree , pattern string ) ([]* Node , error ) {
1008
1030
var nodes []string
1009
1031
if strings .Index (pattern , ";" ) == - 1 {
1010
1032
nodes = strings .Split (pattern , "." )
@@ -1031,17 +1053,17 @@ func (m *UnpartitionedMemoryIdx) find(orgId uint32, pattern string) ([]*Node, er
1031
1053
if pos != 0 {
1032
1054
branch = strings .Join (nodes [:pos ], "." )
1033
1055
}
1034
- log .Debugf ("memory-idx: starting search at orgId %d, node %q" , orgId , branch )
1056
+ log .Debugf ("memory-idx: starting search at node %q" , branch )
1035
1057
startNode , ok := tree .Items [branch ]
1036
1058
1037
1059
if ! ok {
1038
- log .Debugf ("memory-idx: branch %q does not exist in the index for orgId %d " , branch , orgId )
1060
+ log .Debugf ("memory-idx: branch %q does not exist in the index" , branch )
1039
1061
return nil , nil
1040
1062
}
1041
1063
1042
1064
if startNode == nil {
1043
1065
corruptIndex .Inc ()
1044
- log .Errorf ("memory-idx: startNode is nil. org=%d, patt=%q,pos=%d,branch=%q" , orgId , pattern , pos , branch )
1066
+ log .Errorf ("memory-idx: startNode is nil. patt=%q,pos=%d,branch=%q" , pattern , pos , branch )
1045
1067
return nil , errors .NewInternal ("hit an empty path in the index" )
1046
1068
}
1047
1069
@@ -1072,7 +1094,7 @@ func (m *UnpartitionedMemoryIdx) find(orgId uint32, pattern string) ([]*Node, er
1072
1094
grandChild := tree .Items [newBranch ]
1073
1095
if grandChild == nil {
1074
1096
corruptIndex .Inc ()
1075
- log .Errorf ("memory-idx: grandChild is nil. org=%d, patt=%q,i=%d,pos=%d,p=%q,path=%q" , orgId , pattern , i , pos , p , newBranch )
1097
+ log .Errorf ("memory-idx: grandChild is nil. patt=%q,i=%d,pos=%d,p=%q,path=%q" , pattern , i , pos , p , newBranch )
1076
1098
return nil , errors .NewInternal ("hit an empty path in the index" )
1077
1099
}
1078
1100
@@ -1180,7 +1202,11 @@ func (m *UnpartitionedMemoryIdx) Delete(orgId uint32, pattern string) ([]idx.Arc
1180
1202
pre := time .Now ()
1181
1203
m .Lock ()
1182
1204
defer m .Unlock ()
1183
- found , err := m .find (orgId , pattern )
1205
+ tree , ok := m .tree [orgId ]
1206
+ if ! ok {
1207
+ return nil , nil
1208
+ }
1209
+ found , err := find (tree , pattern )
1184
1210
if err != nil {
1185
1211
return nil , err
1186
1212
}
@@ -1192,7 +1218,9 @@ func (m *UnpartitionedMemoryIdx) Delete(orgId uint32, pattern string) ([]idx.Arc
1192
1218
1193
1219
statMetricsActive .Set (len (m .defById ))
1194
1220
statDeleteDuration .Value (time .Since (pre ))
1195
-
1221
+ if len (deletedDefs ) > 0 {
1222
+ m .findCache .Purge (orgId )
1223
+ }
1196
1224
return deletedDefs , nil
1197
1225
}
1198
1226
@@ -1411,8 +1439,8 @@ ORGS:
1411
1439
m .Unlock ()
1412
1440
tl .Add (time .Since (lockStart ))
1413
1441
pruned = append (pruned , defs ... )
1414
-
1415
1442
}
1443
+ m .findCache .Purge (org )
1416
1444
}
1417
1445
1418
1446
statMetricsActive .Set (len (m .defById ))
0 commit comments