Caching in Go (Golang): Redis, In-Memory und andere Lösungen
Caching ist eine der wichtigsten Strategien zur Leistungssteigerung und Reduzierung der Datenbanklast in Go-Anwendungen. In diesem Artikel betrachten wir die wichtigsten Ansätze und Bibliotheken zur Implementierung von Caching: von einfachen In-Memory-Lösungen bis hin zu verteiltem Caching mit Redis. Sie erfahren, wann welches Werkzeug die richtige Wahl ist und wie Sie den Cache in Go-Projekten richtig organisieren.
1. Integrierte Möglichkeiten: map und sync.Map
Der einfachste Weg zum Caching in Go ist die Verwendung einer normalen map mit Mutex oder der threadsicheren sync.Map. Diese Ansätze eignen sich für kleinere Projekte oder Prototypen, bei denen keine komplexe Invalidierungsstrategie erforderlich ist.
Beispiel mit sync.Map:
package main
import ( "fmt" "sync")
type Cache struct { data sync.Map}
func (c *Cache) Set(key string, value interface{}) { c.data.Store(key, value)}
func (c *Cache) Get(key string) (interface{}, bool) { return c.data.Load(key)}
func main() { cache := &Cache{} cache.Set("user:1", "Alice") if val, ok := cache.Get("user:1"); ok { fmt.Println("Found:", val) }}Vorteile: Einfachheit, keine Abhängigkeiten.
Nachteile: Kein TTL, keine automatische Bereinigung, Speicher nicht begrenzt.
2. In-Memory-Cache mit TTL: freecache
Freecache ist eine schnelle In-Memory-Cache-Bibliothek mit Unterstützung für TTL (Time-to-Live). Sie verwendet eine segmentierte Architektur, um Sperren zu minimieren und Speicher effizient zu verwalten.
Installation:
go get github.com/coocood/freecacheAnwendungsbeispiel:
package main
import ( "fmt" "github.com/coocood/freecache")
func main() { // Cache mit 100 MB Größe erstellen cache := freecache.NewCache(100 * 1024 * 1024)
// Wert mit TTL von 10 Sekunden setzen cache.Set([]byte("mykey"), []byte("myvalue"), 10)
// Wert abrufen if val, err := cache.Get([]byte("mykey")); err == nil { fmt.Println("Value:", string(val)) } else { fmt.Println("Key not found or expired") }}Vorteile: Automatische Bereinigung per TTL, geringer CPU-Verbrauch, Unterstützung großer Datenmengen.
Nachteile: Nur für einen einzelnen Prozess (nicht verteilt).
3. BigCache – Alternative zu freecache
BigCache ist eine weitere beliebte In-Memory-Bibliothek, optimiert für die Speicherung einer großen Anzahl von Einträgen (Millionen) mit minimaler Zugriffszeit. Sie unterstützt ebenfalls TTL und die automatische Räumung alter Daten.
Beispiel:
package main
import ( "fmt" "github.com/allegro/bigcache/v3" "time")
func main() { config := bigcache.Config{ Shards: 1024, LifeWindow: 10 * time.Minute, CleanWindow: 5 * time.Minute, MaxEntriesInWindow: 1000 * 10 * 60, MaxEntrySize: 500, Verbose: true, }
cache, _ := bigcache.NewBigCache(config) cache.Set("mykey", []byte("bigcache value")) val, _ := cache.Get("mykey") fmt.Println(string(val))}Vorteile: Hohe Leistung bei vielen Schlüsseln, flexible Konfiguration.
Nachteile: Wie freecache – lokaler Cache.
4. Verteiltes Caching mit Redis und go-redis
Für verteilte Systeme, in denen mehrere Anwendungsinstanzen einen gemeinsamen Cache benötigen, wird Redis verwendet. Der beliebteste Client für Go ist go-redis (früher go-redis/redis).
Installation:
go get github.com/redis/go-redis/v9Beispiel für grundlegendes Caching:
Auch in der Bibliothek
CLI-Framework für C++: cppcli — Erstellung von Konsolenanwendungen
Elasticsearch-Client für Java: Vollständige Anleitung zur Arbeit mit dem Java Client
Redis-Client für Go (Golang) — go-redis und radix