From 8a8da4e6792e19caf3a5995ec5963f37b22d07d8 Mon Sep 17 00:00:00 2001 From: Lucas Francisco Lopez Date: Wed, 8 Jan 2025 18:23:33 +0100 Subject: [PATCH 1/2] Add HardMaxCacheSize to local cache config --- pkg/zcache/config.go | 26 ++++++++++++++++++-------- pkg/zcache/readme.md | 32 ++++++++++++++++++++++++++++++-- 2 files changed, 48 insertions(+), 10 deletions(-) diff --git a/pkg/zcache/config.go b/pkg/zcache/config.go index ba66cf1..81f85c4 100644 --- a/pkg/zcache/config.go +++ b/pkg/zcache/config.go @@ -1,13 +1,16 @@ package zcache import ( + "time" + "github.com/allegro/bigcache/v3" "github.com/go-redis/redis/v8" "github.com/zondax/golem/pkg/logger" "github.com/zondax/golem/pkg/metrics" - "time" ) +const hardMaxCacheSizeDefault = 512 + type StatsMetrics struct { Enable bool UpdateInterval time.Duration @@ -40,11 +43,12 @@ type RemoteConfig struct { } type LocalConfig struct { - Prefix string - Logger *logger.Logger - MetricServer metrics.TaskMetrics - StatsMetrics StatsMetrics - CleanupProcess CleanupProcess + Prefix string + Logger *logger.Logger + MetricServer metrics.TaskMetrics + StatsMetrics StatsMetrics + CleanupProcess CleanupProcess + HardMaxCacheSizeInMB int } func (c *RemoteConfig) ToRedisConfig() *redis.Options { @@ -66,8 +70,14 @@ func (c *RemoteConfig) ToRedisConfig() *redis.Options { } func (c *LocalConfig) ToBigCacheConfig() bigcache.Config { - evictionTime := time.Duration(100*365*24) * time.Hour // 100 years - return bigcache.DefaultConfig(evictionTime) + config := bigcache.DefaultConfig(time.Duration(100*365*24) * time.Hour) + + if c.HardMaxCacheSizeInMB <= 0 { + c.HardMaxCacheSizeInMB = hardMaxCacheSizeDefault + } + config.HardMaxCacheSize = c.HardMaxCacheSizeInMB * 1024 * 1024 + + return config } type CombinedConfig struct { diff --git a/pkg/zcache/readme.md b/pkg/zcache/readme.md index 86d21c4..4ba7fda 100644 --- a/pkg/zcache/readme.md +++ b/pkg/zcache/readme.md @@ -65,10 +65,12 @@ It's important to note that MetricServer is a mandatory configuration field in L func main() { config := zcache.LocalConfig{ // CleanupInterval is optional; if omitted, a default value of 12 hours will be used - CleanupProcess: CleanupProcess{ + CleanupProcess: CleanupProcess{ Interval: 30 * time.Minute, }, - MetricServer: metricServer, + // HardMaxCacheSizeInMB is optional; if omitted, a default value of 512MB will be used + HardMaxCacheSizeInMB: 1024, // Set maximum cache size to 1GB + MetricServer: metricServer, } cache, err := zcache.NewLocalCache(&config) @@ -182,3 +184,29 @@ func TestSomeFunctionWithMutex(t *testing.T) { } ``` +## Best Practices + +### Memory Management +When using the local cache (BigCache), it's important to understand how memory is managed: + +1. **Memory Growth**: BigCache allocates memory in chunks and doesn't immediately release memory when items are deleted or overwritten +2. **Memory Limit**: The `HardMaxCacheSizeInMB` parameter (default: 512MB) is crucial to prevent unbounded memory growth +3. **Actual Memory Usage**: The total memory consumption will be slightly higher than `HardMaxCacheSizeInMB` due to: + - Shard overhead (approximately 2×(64+32)×n bits per entry) + - Internal map structures + - Go runtime overhead + + +### Memory Monitoring +Monitor cache memory usage through the provided metrics: +- `local_cache_cleanup_item_count` +- `local_cache_cleanup_deleted_item_count` +- `local_cache_cleanup_errors` +- `local_cache_cleanup_last_run` + +### Notes +- BigCache has a known memory leak issue (see [issue #369](https://github.com/allegro/bigcache/issues/369)). To mitigate this: + 1. Always set `HardMaxCacheSizeInMB` (default: 512MB) + 2. Monitor memory usage through provided metrics + 3. Consider using shorter cleanup intervals in high-traffic scenarios + 4. For critical production environments, consider using the Combined Cache with Redis as primary storage From d0fcbeb05969dab2e4cfbbc9b98c7ed817efeab6 Mon Sep 17 00:00:00 2001 From: Lucas Francisco Lopez Date: Wed, 8 Jan 2025 18:24:42 +0100 Subject: [PATCH 2/2] minor change --- pkg/zcache/config.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/zcache/config.go b/pkg/zcache/config.go index 81f85c4..8eb4935 100644 --- a/pkg/zcache/config.go +++ b/pkg/zcache/config.go @@ -75,7 +75,7 @@ func (c *LocalConfig) ToBigCacheConfig() bigcache.Config { if c.HardMaxCacheSizeInMB <= 0 { c.HardMaxCacheSizeInMB = hardMaxCacheSizeDefault } - config.HardMaxCacheSize = c.HardMaxCacheSizeInMB * 1024 * 1024 + config.HardMaxCacheSize = c.HardMaxCacheSizeInMB return config }