Caching in Go (Golang): Redis und andere Lösungen
Caching ist eines der Schlüsselwerkzeuge zur Leistungssteigerung von Go-Anwendungen. Es ermöglicht, die Antwortzeit zu verkürzen, die Last auf Datenbanken und externe APIs zu reduzieren. In diesem Artikel betrachten wir die wichtigsten Ansätze zum Caching in Go: die Verwendung von Redis als externem Speicher, integriertes In-Memory-Caching und Gruppen-Caching mit der Bibliothek groupcache.
1. Warum ist Caching in Go notwendig?
Go ist eine auf hohe Leistung ausgerichtete Sprache, aber selbst die schnellsten Abfragen an Datenbanken oder externe Dienste können zum Engpass werden. Caching hilft:
- Verzögerungen bei wiederholten Anfragen zu reduzieren.
- Die Last auf Datenbanken und externe APIs zu verringern.
- Den Serverdurchsatz zu erhöhen.
- Spitzenlasten abzufedern.
2. Redis – verteiltes Caching
Redis ist die beliebteste Lösung für einen externen Cache in Go. Es arbeitet als In-Memory-Speicher mit Unterstützung für TTL, Persistenz und komplexe Datenstrukturen.
Redis in Go einbinden
Für die Arbeit mit Redis in Go wird am häufigsten die Bibliothek go-redis verwendet. Installation:
go get github.com/redis/go-redis/v9Beispiel: Einfaches Caching mit TTL
package main
import ( "context" "fmt" "time" "github.com/redis/go-redis/v9")
var ctx = context.Background()
func main() { rdb := redis.NewClient(&redis.Options{ Addr: "localhost:6379", })
// Wert mit TTL von 10 Sekunden setzen err := rdb.Set(ctx, "user:42", `{"name":"Alice"}`, 10*time.Second).Err() if err != nil { panic(err) }
// Wert abrufen val, err := rdb.Get(ctx, "user:42").Result() if err != nil { fmt.Println("Cache-Fehlzugriff") } else { fmt.Println("Cache-Treffer:", val) }}Strategien zur Cache-Invalidierung in Redis
- TTL (Time To Live) – automatische Löschung nach Zeitablauf.
- Lazy-Invalidierung – Cache-Bereinigung bei Datenaktualisierung.
- Löschung nach Schlüssel – Aufruf von
DELfür einen bestimmten Schlüssel. - Cache-Aside-Muster – Die Anwendung verwaltet den Cache selbst: Zuerst Redis prüfen, bei Fehlzugriff aus der Datenbank laden und im Cache speichern.
3. In-Memory-Caching in Go
Für lokales Caching ohne externe Abhängigkeiten können integrierte Go-Strukturen oder spezialisierte Bibliotheken verwendet werden.
Einfacher In-Memory-Cache mit sync.Map
package main
import ( "fmt" "sync" "time")
type CacheItem struct { Value interface{} Expiration int64}
type Cache struct { items sync.Map}
func (c *Cache) Set(key string, value interface{}, ttl time.Duration) { c.items.Store(key, CacheItem{ Value: value, Expiration: time.Now().Add(ttl).UnixNano(), })}
func (c *Cache) Get(key string) (interface{}, bool) { item, found := c.items.Load(key) if !found { return nil, false } cacheItem := item.(CacheItem) if time.Now().UnixNano() > cacheItem.Expiration { c.items.Delete(key) return nil, false } return cacheItem.Value, true}
func main() { cache := &Cache{} cache.Set("key1", "value1", 5*time.Second) val, ok := cache.Get("key1") if ok { fmt.Println("Gefunden:", val) }}Bibliothek freecache
freecache – eine leistungsstarke In-Memory-Bibliothek mit TTL-Unterstützung und geringem Speicherverbrauch. Installation:
go get github.com/coocood/freecachecache := freecache.NewCache(100 * 1024 * 1024) // 100 MBcache.Set([]by Auch in der Bibliothek
Kysely TypeScript: Vollständiges Tutorial mit Codebeispielen
tsup für TypeScript: Komplettguide mit Beispielen
Reaktive Programmierung in Rust: Bibliotheken, Frameworks und praktische Beispiele
Arbeiten mit CSV in C++: Bibliotheken und Codebeispiele
EasyNetQ für C# (.NET): Vollständiges Tutorial mit Beispielen