성능에 영향을 미치지 않고 많은 수의 항목을 유지하기 위해 빠르고 동시, 메모리 캐시를 퇴치합니다. BigCache는 힙에 대한 항목을 유지하지만 GC를 생략합니다. 이를 달성하기 위해 바이트 슬라이스의 작업이 이루어 지므로 대부분의 사용 사례에서 캐시 앞의 항목 (DE) 직렬화가 필요합니다.
Go 1.12 이상이 필요합니다.
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 ))캐시로드를 미리 예측할 수 있으면 추가 메모리 할당을 피할 수 있으므로 사용자 정의 초기화를 사용하는 것이 좋습니다.
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 는 시간입니다. 그 후, 항목은 죽은 사람이라고 불릴 수 있지만 삭제할 수는 없습니다.
CleanWindow 는 시간입니다. 그 후, 모든 죽은 출품작은 삭제되지만 여전히 생명이있는 출품작은 아닙니다.
Bigcache, Freecache 및 MAP의 세 캐시를 비교했습니다. 벤치 마크 테스트는 Ubuntu 18.04 LTS (5.2.12-050212-Generic)에서 32GB RAM을 갖춘 i7-6700K CPU @ 4.00GHz를 사용하여 수행되었습니다.
벤치 마크 소스 코드는 여기에서 찾을 수 있습니다
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.257sBigcache의 글쓰기 및 읽기는 Freecache보다 빠릅니다. MAP에 쓰는 것은 가장 느립니다.
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
테스트에 따르면 20mln의 항목으로 채워진 캐시의 GC 일시 중지 시간이 표시됩니다. Bigcache와 Freecache는 GC 일시 중지 시간이 매우 유사합니다.
기하 급수적으로 증가한 것으로 보이는 시스템 메모리를보고 할 수 있지만 이는 행동이 예상됩니다. GO 런타임은 청크 또는 '스팬'에 메모리를 할당하고 상태를 '유휴 상태'로 변경하여 더 이상 필요하지 않은 경우 OS에 알립니다. 'SPANS'는 OS가 주소를 용도 변경해야 할 때까지 프로세스 리소스 사용의 일부를 유지합니다. 추가로 읽을 수 있습니다.
BigCache는 1.5 버전의 GO (Issue-9477)로 제시된 최적화에 의존합니다. 이 최적화는 키와 값에 포인터가없는 맵이 사용되면 GC가 컨텐츠를 생략 할 것이라고 명시합니다. 따라서 BigCache는 키를 map[uint64]uint32 하고 값은 항목의 오프셋입니다.
항목은 바이트 슬라이스로 보관되어 GC를 다시 생략합니다. 바이트 슬라이스 크기는 성능에 영향을 미치지 않고 기가 바이트로 성장할 수 있습니다. GC는 단일 포인터 만 볼 수 있기 때문입니다.
BigCache는 충돌을 처리하지 않습니다. 새 항목이 삽입되고 해시가 이전에 저장된 항목과 충돌하면 새 항목은 이전에 저장된 값을 덮어 씁니다.
두 캐시는 동일한 코어 기능을 제공하지만 GC 오버 헤드를 다양한 방식으로 줄입니다. BigCache는 map[uint64]uint32 , FreeCache는 포인터 수를 줄이기 위해 슬라이스에 구축 된 자체 매핑을 구현합니다.
벤치 마크 테스트 결과는 위에 나와 있습니다. Freecache보다 큰 캐시의 장점 중 하나는 캐시의 크기를 미리 알 필요가 없다는 것입니다. BigCache가 가득 차면 Freecache가 현재하는 것처럼 기존 항목을 덮어 쓰는 대신 새 항목에 대한 추가 메모리를 추가 할 수 있기 때문입니다. 그러나 BigCache의 최대 최대 크기도 설정할 수 있습니다. HardMaxCachesize를 확인하십시오.
이 패키지에는 서버 패키지에서 찾을 수있는 BigCache의 쉽게 배포 가능한 HTTP 구현도 포함되어 있습니다.
BigCache Genesis는 Allegro.tech 블로그 게시물에 설명되어 있습니다. GO에서 매우 빠른 캐시 서비스 작성
BigCache는 Apache 2.0 라이센스에 따라 릴리스됩니다 (라이센스 참조)