Skip to content

Commit 95eaa42

Browse files
committed
Tune Badger cache config parameters to contain RAM usage.
1 parent 59f84c6 commit 95eaa42

File tree

1 file changed

+45
-11
lines changed

1 file changed

+45
-11
lines changed

internal/cache/cache.go

Lines changed: 45 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"time"
66

77
"github.com/dgraph-io/badger/v4"
8+
"github.com/dgraph-io/badger/v4/options"
89
)
910

1011
const (
@@ -27,8 +28,9 @@ type Config struct {
2728
type Cache struct {
2829
defaultTTL time.Duration
2930

30-
db *badger.DB
31-
lo *log.Logger
31+
db *badger.DB
32+
lo *log.Logger
33+
stopGC chan struct{}
3234
}
3335

3436
// New creates and returns a new Cache instance.
@@ -48,27 +50,35 @@ func New(cfg Config, lo *log.Logger) (*Cache, error) {
4850
if cfg.MaxMemory > 0 {
4951
maxBytes := cfg.MaxMemory << 20 // Convert MB to bytes
5052

51-
// Distribute memory to 50% block cache, 25% memtables, and 25% index cache.
53+
// Distribute memory to 50% memtables, and 50% index cache.
5254
// Opinionated!
53-
opts.BlockCacheSize = maxBytes / 2
54-
opts.IndexCacheSize = maxBytes / 4
55+
opts.Compression = options.None
56+
opts.BlockCacheSize = 0
57+
opts.IndexCacheSize = maxBytes / 2
5558

56-
// MemTableSize * NumMemtables should fit in remaining ~25%.
57-
// Use smaller memtables with fewer of them.
58-
opts.MemTableSize = maxBytes / 8
59-
opts.NumMemtables = 2
59+
// MemTableSize * NumMemtables should fit in remaining memory.
60+
opts.NumMemtables = 3
61+
opts.MemTableSize = (maxBytes / 2) / int64(opts.NumMemtables)
6062
}
6163

6264
db, err := badger.Open(opts)
6365
if err != nil {
6466
return nil, err
6567
}
6668

67-
return &Cache{
69+
c := &Cache{
6870
defaultTTL: cfg.TTL,
6971
db: db,
7072
lo: lo,
71-
}, nil
73+
}
74+
75+
// Start background GC for hybrid mode (in-memory mode doesn't need it).
76+
if cfg.Mode != CacheTypeMemory {
77+
c.stopGC = make(chan struct{})
78+
go c.runGC()
79+
}
80+
81+
return c, nil
7282
}
7383

7484
// Get retrieves a value by key. Doesn't return an error if key is not found.
@@ -120,5 +130,29 @@ func (c *Cache) Purge() error {
120130

121131
// Close closes the underlying Badger database.
122132
func (c *Cache) Close() error {
133+
if c.stopGC != nil {
134+
close(c.stopGC)
135+
}
123136
return c.db.Close()
124137
}
138+
139+
// runGC periodically runs Badger's value log garbage collection.
140+
func (c *Cache) runGC() {
141+
ticker := time.NewTicker(60 * time.Minute)
142+
defer ticker.Stop()
143+
144+
for {
145+
select {
146+
case <-ticker.C:
147+
// Run value log GC until nothing left to collect.
148+
// 0.5 threshold means GC runs if 50%+ of a vlog file is garbage.
149+
for {
150+
if err := c.db.RunValueLogGC(0.5); err != nil {
151+
break
152+
}
153+
}
154+
case <-c.stopGC:
155+
return
156+
}
157+
}
158+
}

0 commit comments

Comments
 (0)