metrics: add hit counter for ARC and bloom caches

License: MIT
Signed-off-by: 's avatarJakub Sztandera <kubuxu@protonmail.ch>
上级 a2bb6e8e
package blockstore package blockstore
import ( import (
"github.com/ipfs/go-ipfs/blocks"
key "gx/ipfs/Qmce4Y4zg3sYr7xKM5UueS67vhNni6EeWgCRnb7MbLJMew/go-key" key "gx/ipfs/Qmce4Y4zg3sYr7xKM5UueS67vhNni6EeWgCRnb7MbLJMew/go-key"
"github.com/ipfs/go-ipfs/blocks"
"gx/ipfs/QmRg1gKTHzc3CZXSKzem8aR4E3TubFhbgXwfVuWnSK5CC5/go-metrics-interface"
lru "gx/ipfs/QmVYxfoJQiZijTgPNHCHgHELvQpbsJNTg6Crmc3dQkj3yy/golang-lru" lru "gx/ipfs/QmVYxfoJQiZijTgPNHCHgHELvQpbsJNTg6Crmc3dQkj3yy/golang-lru"
context "gx/ipfs/QmZy2y8t9zQH2a1b8q2ZSLKp17ATuJoCNxxyMFG5qFExpt/go-net/context" context "gx/ipfs/QmZy2y8t9zQH2a1b8q2ZSLKp17ATuJoCNxxyMFG5qFExpt/go-net/context"
ds "gx/ipfs/QmbzuUusHqaLLoNTDEVLcSF6vZDHZDLPC7p4bztRvvkXxU/go-datastore" ds "gx/ipfs/QmbzuUusHqaLLoNTDEVLcSF6vZDHZDLPC7p4bztRvvkXxU/go-datastore"
...@@ -12,15 +14,21 @@ import ( ...@@ -12,15 +14,21 @@ import (
type arccache struct { type arccache struct {
arc *lru.ARCCache arc *lru.ARCCache
blockstore Blockstore blockstore Blockstore
hits metrics.Counter
total metrics.Counter
} }
func arcCached(bs Blockstore, lruSize int) (*arccache, error) { func newARCCachedBS(bs Blockstore, ctx context.Context, lruSize int) (*arccache, error) {
arc, err := lru.NewARC(lruSize) arc, err := lru.NewARC(lruSize)
if err != nil { if err != nil {
return nil, err return nil, err
} }
c := &arccache{arc: arc, blockstore: bs}
c.hits = metrics.NewCtx(ctx, "arc.hits_total", "Number of ARC cache hits").Counter()
c.total = metrics.NewCtx(ctx, "arc_total", "Total number of ARC cache requests").Counter()
return &arccache{arc: arc, blockstore: bs}, nil return c, nil
} }
func (b *arccache) DeleteBlock(k key.Key) error { func (b *arccache) DeleteBlock(k key.Key) error {
...@@ -42,6 +50,7 @@ func (b *arccache) DeleteBlock(k key.Key) error { ...@@ -42,6 +50,7 @@ func (b *arccache) DeleteBlock(k key.Key) error {
// if ok == false has is inconclusive // if ok == false has is inconclusive
// if ok == true then has respons to question: is it contained // if ok == true then has respons to question: is it contained
func (b *arccache) hasCached(k key.Key) (has bool, ok bool) { func (b *arccache) hasCached(k key.Key) (has bool, ok bool) {
b.total.Inc()
if k == "" { if k == "" {
// Return cache invalid so the call to blockstore happens // Return cache invalid so the call to blockstore happens
// in case of invalid key and correct error is created. // in case of invalid key and correct error is created.
...@@ -50,6 +59,7 @@ func (b *arccache) hasCached(k key.Key) (has bool, ok bool) { ...@@ -50,6 +59,7 @@ func (b *arccache) hasCached(k key.Key) (has bool, ok bool) {
h, ok := b.arc.Get(k) h, ok := b.arc.Get(k)
if ok { if ok {
b.hits.Inc()
return h.(bool), true return h.(bool), true
} }
return false, false return false, false
......
...@@ -140,7 +140,7 @@ func TestGetAndDeleteFalseShortCircuit(t *testing.T) { ...@@ -140,7 +140,7 @@ func TestGetAndDeleteFalseShortCircuit(t *testing.T) {
} }
func TestArcCreationFailure(t *testing.T) { func TestArcCreationFailure(t *testing.T) {
if arc, err := arcCached(nil, -1); arc != nil || err == nil { if arc, err := newARCCachedBS(nil, context.TODO(), -1); arc != nil || err == nil {
t.Fatal("expected error and no cache") t.Fatal("expected error and no cache")
} }
} }
......
...@@ -6,6 +6,7 @@ import ( ...@@ -6,6 +6,7 @@ import (
"github.com/ipfs/go-ipfs/blocks" "github.com/ipfs/go-ipfs/blocks"
key "gx/ipfs/Qmce4Y4zg3sYr7xKM5UueS67vhNni6EeWgCRnb7MbLJMew/go-key" key "gx/ipfs/Qmce4Y4zg3sYr7xKM5UueS67vhNni6EeWgCRnb7MbLJMew/go-key"
"gx/ipfs/QmVWBQQAz4Cd2XgW9KgQoqXXrU8KJoCb9WCrhWRFVBKvFe/go-metrics-interface"
bloom "gx/ipfs/QmWQ2SJisXwcCLsUXLwYCKSfyExXjFRW2WbBH5sqCUnwX5/bbloom" bloom "gx/ipfs/QmWQ2SJisXwcCLsUXLwYCKSfyExXjFRW2WbBH5sqCUnwX5/bbloom"
context "gx/ipfs/QmZy2y8t9zQH2a1b8q2ZSLKp17ATuJoCNxxyMFG5qFExpt/go-net/context" context "gx/ipfs/QmZy2y8t9zQH2a1b8q2ZSLKp17ATuJoCNxxyMFG5qFExpt/go-net/context"
) )
...@@ -18,6 +19,10 @@ func bloomCached(bs Blockstore, ctx context.Context, bloomSize, hashCount int) ( ...@@ -18,6 +19,10 @@ func bloomCached(bs Blockstore, ctx context.Context, bloomSize, hashCount int) (
return nil, err return nil, err
} }
bc := &bloomcache{blockstore: bs, bloom: bl} bc := &bloomcache{blockstore: bs, bloom: bl}
bc.hits = metrics.NewCtx(ctx, "bloom.hits_total",
"Number of cache hits in bloom cache").Counter()
bc.total = metrics.NewCtx(ctx, "bloom_total",
"Total number of requests to bloom cache").Counter()
bc.Invalidate() bc.Invalidate()
go bc.Rebuild(ctx) go bc.Rebuild(ctx)
...@@ -33,8 +38,8 @@ type bloomcache struct { ...@@ -33,8 +38,8 @@ type bloomcache struct {
blockstore Blockstore blockstore Blockstore
// Statistics // Statistics
hits uint64 hits metrics.Counter
misses uint64 total metrics.Counter
} }
func (b *bloomcache) Invalidate() { func (b *bloomcache) Invalidate() {
...@@ -84,6 +89,7 @@ func (b *bloomcache) DeleteBlock(k key.Key) error { ...@@ -84,6 +89,7 @@ func (b *bloomcache) DeleteBlock(k key.Key) error {
// if ok == false has is inconclusive // if ok == false has is inconclusive
// if ok == true then has respons to question: is it contained // if ok == true then has respons to question: is it contained
func (b *bloomcache) hasCached(k key.Key) (has bool, ok bool) { func (b *bloomcache) hasCached(k key.Key) (has bool, ok bool) {
b.total.Inc()
if k == "" { if k == "" {
// Return cache invalid so call to blockstore // Return cache invalid so call to blockstore
// in case of invalid key is forwarded deeper // in case of invalid key is forwarded deeper
...@@ -92,6 +98,7 @@ func (b *bloomcache) hasCached(k key.Key) (has bool, ok bool) { ...@@ -92,6 +98,7 @@ func (b *bloomcache) hasCached(k key.Key) (has bool, ok bool) {
if b.BloomActive() { if b.BloomActive() {
blr := b.bloom.HasTS([]byte(k)) blr := b.bloom.HasTS([]byte(k))
if blr == false { // not contained in bloom is only conclusive answer bloom gives if blr == false { // not contained in bloom is only conclusive answer bloom gives
b.hits.Inc()
return false, true return false, true
} }
} }
......
...@@ -3,6 +3,7 @@ package blockstore ...@@ -3,6 +3,7 @@ package blockstore
import ( import (
"errors" "errors"
"gx/ipfs/QmVWBQQAz4Cd2XgW9KgQoqXXrU8KJoCb9WCrhWRFVBKvFe/go-metrics-interface"
context "gx/ipfs/QmZy2y8t9zQH2a1b8q2ZSLKp17ATuJoCNxxyMFG5qFExpt/go-net/context" context "gx/ipfs/QmZy2y8t9zQH2a1b8q2ZSLKp17ATuJoCNxxyMFG5qFExpt/go-net/context"
) )
...@@ -33,11 +34,14 @@ func CachedBlockstore(bs GCBlockstore, ...@@ -33,11 +34,14 @@ func CachedBlockstore(bs GCBlockstore,
if opts.HasBloomFilterSize != 0 && opts.HasBloomFilterHashes == 0 { if opts.HasBloomFilterSize != 0 && opts.HasBloomFilterHashes == 0 {
return nil, errors.New("bloom filter hash count can't be 0 when there is size set") return nil, errors.New("bloom filter hash count can't be 0 when there is size set")
} }
ctx = metrics.CtxSubScope(ctx, "bs.cache")
if opts.HasBloomFilterSize != 0 { if opts.HasBloomFilterSize != 0 {
cbs, err = bloomCached(cbs, ctx, opts.HasBloomFilterSize, opts.HasBloomFilterHashes) cbs, err = bloomCached(cbs, ctx, opts.HasBloomFilterSize, opts.HasBloomFilterHashes)
} }
if opts.HasARCCacheSize > 0 { if opts.HasARCCacheSize > 0 {
cbs, err = arcCached(cbs, opts.HasARCCacheSize) cbs, err = newARCCachedBS(cbs, ctx, opts.HasARCCacheSize)
} }
return cbs, err return cbs, err
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论