Schneller, gleichzeitiger, räumender In-Memory-Cache, der geschrieben wurde, um eine große Anzahl von Einträgen ohne Auswirkungen auf die Leistung zu erhalten. BigCache hält Einträge auf Heap, lässt aber GC für sie aus. Um dies zu erreichen, finden in den meisten Anwendungsfällen Vorgänge in Bytescheiben statt.
Erfordert Go 1.12 oder neuer.
import (
"fmt"
"context"
"github.com/allegro/bigcache/v3"
)
cache , _ := bigcache . New ( context . Background (), bigcache . DefaultConfig ( 10 * time . Minute ))
cache . Set ( "my-unique-key" , [] byte ( "value" ))
entry , _ := cache . Get ( "my-unique-key" )
fmt . Println ( string ( entry ))Wenn die Cache -Last im Voraus vorhergesagt werden kann, ist es besser, benutzerdefinierte Initialisierung zu verwenden, da auf diese Weise zusätzliche Speicherzuweisung vermieden werden kann.
import (
"log"
"github.com/allegro/bigcache/v3"
)
config := bigcache. Config {
// number of shards (must be a power of 2)
Shards : 1024 ,
// time after which entry can be evicted
LifeWindow : 10 * time . Minute ,
// Interval between removing expired entries (clean up).
// If set to <= 0 then no action is performed.
// Setting to < 1 second is counterproductive — bigcache has a one second resolution.
CleanWindow : 5 * time . Minute ,
// rps * lifeWindow, used only in initial memory allocation
MaxEntriesInWindow : 1000 * 10 * 60 ,
// max entry size in bytes, used only in initial memory allocation
MaxEntrySize : 500 ,
// prints information about additional memory allocation
Verbose : true ,
// cache will not allocate more memory than this limit, value in MB
// if value is reached then the oldest entries can be overridden for the new ones
// 0 value means no size limit
HardMaxCacheSize : 8192 ,
// callback fired when the oldest entry is removed because of its expiration time or no space left
// for the new entry, or because delete was called. A bitmask representing the reason will be returned.
// Default value is nil which means no callback and it prevents from unwrapping the oldest entry.
OnRemove : nil ,
// OnRemoveWithReason is a callback fired when the oldest entry is removed because of its expiration time or no space left
// for the new entry, or because delete was called. A constant representing the reason will be passed through.
// Default value is nil which means no callback and it prevents from unwrapping the oldest entry.
// Ignored if OnRemove is specified.
OnRemoveWithReason : nil ,
}
cache , initErr := bigcache . New ( context . Background (), config )
if initErr != nil {
log . Fatal ( initErr )
}
cache . Set ( "my-unique-key" , [] byte ( "value" ))
if entry , err := cache . Get ( "my-unique-key" ); err == nil {
fmt . Println ( string ( entry ))
}LifeWindow & CleanWindow LifeWindow ist eine Zeit. Nach dieser Zeit kann ein Eintrag als tot bezeichnet werden, aber nicht gelöscht werden.
CleanWindow ist eine Zeit. Nach dieser Zeit werden alle toten Einträge gelöscht, aber nicht die Einträge, die noch Leben haben.
Drei Caches wurden verglichen: Bigcache, Freecache und Karte. Benchmark-Tests wurden mit einem i7-6700k CPU @ 4,00 GHz mit 32 GB RAM auf Ubuntu 18,04 LTs (5.2.12-050212-Generik) durchgeführt.
Benchmarks -Quellcode finden Sie hier
go version
go version go1.13 linux/amd64
go test -bench=. -benchmem -benchtime=4s ./... -timeout 30m
goos: linux
goarch: amd64
pkg: github.com/allegro/bigcache/v3/caches_bench
BenchmarkMapSet-8 12999889 376 ns/op 199 B/op 3 allocs/op
BenchmarkConcurrentMapSet-8 4355726 1275 ns/op 337 B/op 8 allocs/op
BenchmarkFreeCacheSet-8 11068976 703 ns/op 328 B/op 2 allocs/op
BenchmarkBigCacheSet-8 10183717 478 ns/op 304 B/op 2 allocs/op
BenchmarkMapGet-8 16536015 324 ns/op 23 B/op 1 allocs/op
BenchmarkConcurrentMapGet-8 13165708 401 ns/op 24 B/op 2 allocs/op
BenchmarkFreeCacheGet-8 10137682 690 ns/op 136 B/op 2 allocs/op
BenchmarkBigCacheGet-8 11423854 450 ns/op 152 B/op 4 allocs/op
BenchmarkBigCacheSetParallel-8 34233472 148 ns/op 317 B/op 3 allocs/op
BenchmarkFreeCacheSetParallel-8 34222654 268 ns/op 350 B/op 3 allocs/op
BenchmarkConcurrentMapSetParallel-8 19635688 240 ns/op 200 B/op 6 allocs/op
BenchmarkBigCacheGetParallel-8 60547064 86.1 ns/op 152 B/op 4 allocs/op
BenchmarkFreeCacheGetParallel-8 50701280 147 ns/op 136 B/op 3 allocs/op
BenchmarkConcurrentMapGetParallel-8 27353288 175 ns/op 24 B/op 2 allocs/op
PASS
ok github.com/allegro/bigcache/v3/caches_bench 256.257sSchreibt und liest in BigCache schneller als in Freecache. Schreibvorgänge zur Karte sind am langsamsten.
go version
go version go1.13 linux/amd64
go run caches_gc_overhead_comparison.go
Number of entries: 20000000
GC pause for bigcache: 1.506077ms
GC pause for freecache: 5.594416ms
GC pause for map: 9.347015ms go version
go version go1.13 linux/arm64
go run caches_gc_overhead_comparison.go
Number of entries: 20000000
GC pause for bigcache: 22.382827ms
GC pause for freecache: 41.264651ms
GC pause for map: 72.236853ms
Der Test zeigt, wie lange die GC -Pausen für Caches mit 20 ml Einträgen gefüllt sind. BigCache und Freecache haben eine sehr ähnliche GC -Pause.
Sie können auf den Systemspeicher stoßen und eine exponentielle Erhöhung berichten. Dies ist jedoch zu erwartendem Verhalten. GO -Laufzeit verteilt den Speicher in Stücken oder "Spannweiten" und informiert das Betriebssystem, wenn sie nicht mehr verlangt werden, indem sie ihren Zustand in "Leerlauf" ändern. Die "Spannweiten" bleiben Teil der Verbrauchsressourcenverwendung, bis das Betriebssystem die Adresse umversuchen muss. Weitere Lektüre hier verfügbar.
BigCache basiert auf der in der 1.5-Version von GO (Ausgabe-9477) vorgestellten Optimierung. In dieser Optimierung heißt es, dass GC seinen Inhalt weglassen, wenn MAP ohne Zeiger in Schlüssel und Werten verwendet wird. Daher verwendet BigCache map[uint64]uint32 wobei Schlüssel gehasht sind und Werte Offsets von Einträgen sind.
Die Einträge werden in Bytescheiben aufbewahrt, um GC erneut wegzulassen. Die Größe der Byte -Scheiben kann zu Gigabyte wachsen, ohne auf die Leistung zu beeinflussen, da GC nur einen einzelnen Zeiger aufweist.
BigCache verwaltet keine Kollisionen. Wenn ein neuer Artikel eingefügt wird und es mit zuvor gespeichertem Artikel kollidiert wird, überschreibt der neue Artikel zuvor gespeicherte Wert.
Beide Caches bieten die gleichen Kernmerkmale, reduzieren GC -Overhead auf unterschiedliche Weise. BigCache basiert auf map[uint64]uint32 , Freecache implementiert seine eigene Zuordnung, die auf Scheiben basiert, um die Anzahl von Zeigern zu verringern.
Die Ergebnisse von Benchmark -Tests werden oben angegeben. Einer der Vorteile von BigCache gegenüber Freecache besteht darin, dass Sie die Größe des Cache im Voraus nicht kennen müssen, da BigCache, wenn es voll ist, zusätzlichen Speicher für neue Einträge zuweisen, anstatt vorhandene vorhandene als derzeit Freecache zu überschreiben. So harte Maximalgröße in BigCache auch eingestellt werden kann. Überprüfen Sie HardmaxCachesize.
Dieses Paket enthält auch eine einfach bereitstellbare HTTP -Implementierung von BigCache, die im Serverpaket zu finden ist.
BigCache Genesis ist in Allegro.Tech Blog -Beitrag beschrieben: Schreiben eines sehr schnellen Cache -Service in Go
BigCache wird unter der Apache 2.0 -Lizenz veröffentlicht (siehe Lizenz)