Skip to content
This repository has been archived by the owner on Aug 23, 2023. It is now read-only.

Commit

Permalink
Merge pull request #1285 from grafana/find-cache-optional
Browse files Browse the repository at this point in the history
make Find cache optional
  • Loading branch information
Dieterbe authored Apr 17, 2019
2 parents 4c92934 + b3728f0 commit 45405aa
Show file tree
Hide file tree
Showing 10 changed files with 66 additions and 37 deletions.
2 changes: 1 addition & 1 deletion docker/docker-chaos/metrictank.ini
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,7 @@ rules-file = /etc/metrictank/index-rules.conf
max-prune-lock-time = 100ms
# use separate indexes per partition. experimental feature. See #1251, #1252
partitioned = false
# number of find expressions to cache (per org)
# number of find expressions to cache (per org). 0 disables cache
find-cache-size = 1000
# size of queue for invalidating findCache entries
find-cache-invalidate-queue-size = 200
Expand Down
2 changes: 1 addition & 1 deletion docker/docker-cluster-query/metrictank.ini
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,7 @@ rules-file = /etc/metrictank/index-rules.conf
max-prune-lock-time = 100ms
# use separate indexes per partition. experimental feature. See #1251, #1252
partitioned = false
# number of find expressions to cache (per org)
# number of find expressions to cache (per org). 0 disables cache
find-cache-size = 1000
# size of queue for invalidating findCache entries
find-cache-invalidate-queue-size = 200
Expand Down
2 changes: 1 addition & 1 deletion docker/docker-cluster/metrictank.ini
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,7 @@ rules-file = /etc/metrictank/index-rules.conf
max-prune-lock-time = 100ms
# use separate indexes per partition. experimental feature. See #1251, #1252
partitioned = false
# number of find expressions to cache (per org)
# number of find expressions to cache (per org). 0 disables cache
find-cache-size = 1000
# size of queue for invalidating findCache entries
find-cache-invalidate-queue-size = 200
Expand Down
2 changes: 1 addition & 1 deletion docker/docker-dev-custom-cfg-kafka/metrictank.ini
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,7 @@ rules-file = /etc/metrictank/index-rules.conf
max-prune-lock-time = 100ms
# use separate indexes per partition. experimental feature. See #1251, #1252
partitioned = false
# number of find expressions to cache (per org)
# number of find expressions to cache (per org). 0 disables cache
find-cache-size = 1000
# size of queue for invalidating findCache entries
find-cache-invalidate-queue-size = 200
Expand Down
2 changes: 1 addition & 1 deletion docs/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -469,7 +469,7 @@ rules-file = /etc/metrictank/index-rules.conf
max-prune-lock-time = 100ms
# use separate indexes per partition. experimental feature. See #1251, #1252
partitioned = false
# number of find expressions to cache (per org)
# number of find expressions to cache (per org). 0 disables cache
find-cache-size = 1000
# size of queue for invalidating findCache entries
find-cache-invalidate-queue-size = 200
Expand Down
16 changes: 12 additions & 4 deletions idx/memory/find_cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -334,26 +334,34 @@ func (c *FindCache) processInvalidateQueue() {

// PurgeFindCache purges the findCaches for all orgIds
func (m *UnpartitionedMemoryIdx) PurgeFindCache() {
m.findCache.PurgeAll()
if m.findCache != nil {
m.findCache.PurgeAll()
}
}

// ForceInvalidationFindCache forces a full invalidation cycle of the find cache
func (m *UnpartitionedMemoryIdx) ForceInvalidationFindCache() {
m.findCache.forceInvalidation()
if m.findCache != nil {
m.findCache.forceInvalidation()
}
}

// PurgeFindCache purges the findCaches for all orgIds
// across all partitions
func (p *PartitionedMemoryIdx) PurgeFindCache() {
for _, m := range p.Partition {
m.findCache.PurgeAll()
if m.findCache != nil {
m.findCache.PurgeAll()
}
}
}

// ForceInvalidationFindCache forces a full invalidation cycle of the find cache
func (p *PartitionedMemoryIdx) ForceInvalidationFindCache() {
for _, m := range p.Partition {
m.findCache.forceInvalidation()
if m.findCache != nil {
m.findCache.forceInvalidation()
}
}
}

Expand Down
71 changes: 46 additions & 25 deletions idx/memory/memory.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ func ConfigSetup() {
memoryIdx.BoolVar(&Partitioned, "partitioned", false, "use separate indexes per partition. experimental feature")
memoryIdx.IntVar(&TagQueryWorkers, "tag-query-workers", 50, "number of workers to spin up to evaluate tag queries")
memoryIdx.IntVar(&matchCacheSize, "match-cache-size", 1000, "size of regular expression cache in tag query evaluation")
memoryIdx.IntVar(&findCacheSize, "find-cache-size", 1000, "number of find expressions to cache (per org)")
memoryIdx.IntVar(&findCacheSize, "find-cache-size", 1000, "number of find expressions to cache (per org). 0 disables cache")
memoryIdx.IntVar(&findCacheInvalidateQueueSize, "find-cache-invalidate-queue-size", 200, "size of queue for invalidating findCache entries")
memoryIdx.IntVar(&findCacheInvalidateMaxSize, "find-cache-invalidate-max-size", 100, "max amount of invalidations to queue up in one batch")
memoryIdx.DurationVar(&findCacheInvalidateMaxWait, "find-cache-invalidate-max-wait", 5*time.Second, "max duration to wait building up a batch to invalidate")
Expand Down Expand Up @@ -255,13 +255,16 @@ type UnpartitionedMemoryIdx struct {
}

func NewUnpartitionedMemoryIdx() *UnpartitionedMemoryIdx {
return &UnpartitionedMemoryIdx{
m := UnpartitionedMemoryIdx{
defById: make(map[schema.MKey]*idx.Archive),
defByTagSet: make(defByTagSet),
tree: make(map[uint32]*Tree),
tags: make(map[uint32]TagIndex),
findCache: NewFindCache(findCacheSize, findCacheInvalidateQueueSize, findCacheInvalidateMaxSize, findCacheInvalidateMaxWait, findCacheBackoffTime),
}
if findCacheSize > 0 {
m.findCache = NewFindCache(findCacheSize, findCacheInvalidateQueueSize, findCacheInvalidateMaxSize, findCacheInvalidateMaxWait, findCacheBackoffTime)
}
return &m
}

func (m *UnpartitionedMemoryIdx) Init() error {
Expand Down Expand Up @@ -477,9 +480,11 @@ func (m *UnpartitionedMemoryIdx) add(def *schema.MetricDefinition) idx.Archive {
return *archive
}

defer func() {
go m.findCache.InvalidateFor(def.OrgId, path)
}()
if m.findCache != nil {
defer func() {
go m.findCache.InvalidateFor(def.OrgId, path)
}()
}

//first check to see if a tree has been created for this OrgId
tree, ok := m.tree[def.OrgId]
Expand Down Expand Up @@ -969,6 +974,25 @@ func (m *UnpartitionedMemoryIdx) idsByTagQuery(orgId uint32, query TagQuery) IdS
return query.Run(tags, m.defById)
}

func (m *UnpartitionedMemoryIdx) findMaybeCached(tree *Tree, orgId uint32, pattern string) ([]*Node, error) {

if m.findCache == nil {
return find(tree, pattern)
}

matchedNodes, ok := m.findCache.Get(orgId, pattern)
if ok {
return matchedNodes, nil
}

matchedNodes, err := find(tree, pattern)
if err != nil {
return nil, err
}
m.findCache.Add(orgId, pattern, matchedNodes)
return matchedNodes, nil
}

func (m *UnpartitionedMemoryIdx) Find(orgId uint32, pattern string, from int64) ([]idx.Node, error) {
pre := time.Now()
var matchedNodes []*Node
Expand All @@ -979,25 +1003,17 @@ func (m *UnpartitionedMemoryIdx) Find(orgId uint32, pattern string, from int64)
if !ok {
log.Debugf("memory-idx: orgId %d has no metrics indexed.", orgId)
} else {
matchedNodes, ok = m.findCache.Get(orgId, pattern)
if !ok {
matchedNodes, err = find(tree, pattern)
if err != nil {
return nil, err
}
m.findCache.Add(orgId, pattern, matchedNodes)
matchedNodes, err = m.findMaybeCached(tree, orgId, pattern)
if err != nil {
return nil, err
}
}
if orgId != idx.OrgIdPublic && idx.OrgIdPublic > 0 {
tree, ok = m.tree[idx.OrgIdPublic]
if ok {
publicNodes, ok := m.findCache.Get(idx.OrgIdPublic, pattern)
if !ok {
publicNodes, err = find(tree, pattern)
if err != nil {
return nil, err
}
m.findCache.Add(idx.OrgIdPublic, pattern, publicNodes)
publicNodes, err := m.findMaybeCached(tree, idx.OrgIdPublic, pattern)
if err != nil {
return nil, err
}
matchedNodes = append(matchedNodes, publicNodes...)
}
Expand Down Expand Up @@ -1229,6 +1245,9 @@ func (m *UnpartitionedMemoryIdx) Delete(orgId uint32, pattern string) ([]idx.Arc
if len(deletedDefs) == 0 {
return
}
if m.findCache == nil {
return
}
// asynchronously invalidate any findCache entries
// that match any of the deleted series.
if len(deletedDefs) > findCacheInvalidateQueueSize {
Expand Down Expand Up @@ -1481,11 +1500,13 @@ ORGS:
tl.Add(time.Since(lockStart))
pruned = append(pruned, defs...)
}
if len(paths) > findCacheInvalidateQueueSize {
m.findCache.Purge(org)
} else {
for path := range paths {
m.findCache.InvalidateFor(org, path)
if m.findCache != nil {
if len(paths) > findCacheInvalidateQueueSize {
m.findCache.Purge(org)
} else {
for path := range paths {
m.findCache.InvalidateFor(org, path)
}
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion metrictank-sample.ini
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,7 @@ rules-file = /etc/metrictank/index-rules.conf
max-prune-lock-time = 100ms
# use separate indexes per partition. experimental feature. See #1251, #1252
partitioned = false
# number of find expressions to cache (per org)
# number of find expressions to cache (per org). 0 disables cache
find-cache-size = 1000
# size of queue for invalidating findCache entries
find-cache-invalidate-queue-size = 200
Expand Down
2 changes: 1 addition & 1 deletion scripts/config/metrictank-docker.ini
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,7 @@ rules-file = /etc/metrictank/index-rules.conf
max-prune-lock-time = 100ms
# use separate indexes per partition. experimental feature. See #1251, #1252
partitioned = false
# number of find expressions to cache (per org)
# number of find expressions to cache (per org). 0 disables cache
find-cache-size = 1000
# size of queue for invalidating findCache entries
find-cache-invalidate-queue-size = 200
Expand Down
2 changes: 1 addition & 1 deletion scripts/config/metrictank-package.ini
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,7 @@ rules-file = /etc/metrictank/index-rules.conf
max-prune-lock-time = 100ms
# use separate indexes per partition. experimental feature. See #1251, #1252
partitioned = false
# number of find expressions to cache (per org)
# number of find expressions to cache (per org). 0 disables cache
find-cache-size = 1000
# size of queue for invalidating findCache entries
find-cache-invalidate-queue-size = 200
Expand Down

0 comments on commit 45405aa

Please sign in to comment.