แคชที่รวดเร็วพร้อมกันพร้อมกับการเขียนในหน่วยความจำที่เขียนขึ้นเพื่อให้รายการจำนวนมากโดยไม่มีผลกระทบต่อประสิทธิภาพ BigCache เก็บรายการไว้ในกอง แต่ละเว้น GC สำหรับพวกเขา เพื่อให้บรรลุเป้าหมายนั้นจะต้องมีการดำเนินการกับชิ้นงานไบต์ดังนั้นรายการ (DE) การทำให้เป็นอนุกรมด้านหน้าของแคชจะต้องใช้ในกรณีที่ใช้งานส่วนใหญ่
ต้องไป 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 การทดสอบเกณฑ์มาตรฐานทำโดยใช้ CPU i7-6700K @ 4.00GHz พร้อม RAM 32GB บน Ubuntu 18.04 LTS (5.2.12-050212-Generic)
สามารถดูซอร์สโค้ดของมาตรฐานได้ที่นี่
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.257sการเขียนและอ่านใน BigCache นั้นเร็วกว่าใน FreeCache การเขียนไปยังแผนที่ช้าที่สุด
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
การทดสอบแสดงให้เห็นว่าการหยุด GC หยุดสำหรับแคชที่เต็มไปด้วยรายการ 20mln ใช้เวลานานเท่าใด BigCache และ Freecache มีเวลาหยุด GC ที่คล้ายกันมาก
คุณอาจพบกับหน่วยความจำของระบบการรายงานสิ่งที่ดูเหมือนจะเพิ่มขึ้นแบบทวีคูณอย่างไรก็ตามนี่เป็นพฤติกรรมที่คาดหวัง ไปรันไทม์จัดสรรหน่วยความจำเป็นชิ้นหรือ 'ช่วง' และจะแจ้งระบบปฏิบัติการเมื่อพวกเขาไม่ต้องการอีกต่อไปโดยการเปลี่ยนสถานะเป็น 'ว่าง' 'ช่วง' จะยังคงเป็นส่วนหนึ่งของการใช้ทรัพยากรกระบวนการจนกว่าระบบปฏิบัติการจะต้องเปลี่ยนที่อยู่ มีการอ่านเพิ่มเติมที่นี่
BigCache อาศัยการเพิ่มประสิทธิภาพที่นำเสนอใน 1.5 เวอร์ชันของ GO (ปัญหา -9477) การเพิ่มประสิทธิภาพนี้ระบุว่าหากใช้แผนที่ที่ไม่มีพอยน์เตอร์ในปุ่มและค่าใช้จ่าย GC จะละเว้นเนื้อหา ดังนั้น BigCache ใช้ map[uint64]uint32 โดยที่กุญแจถูกแฮชและค่าเป็นรายการของรายการ
รายการจะถูกเก็บไว้ในชิ้นไบต์เพื่อละเว้น GC อีกครั้ง ขนาดชิ้นไบต์สามารถเติบโตเป็นกิกะไบต์โดยไม่มีผลกระทบต่อประสิทธิภาพเนื่องจาก GC จะเห็นตัวชี้เดียวเท่านั้น
BigCache ไม่ได้จัดการกับการชน เมื่อมีการแทรกรายการใหม่และแฮชจะปะทะกับรายการที่เก็บไว้ก่อนหน้านี้รายการใหม่จะเขียนทับค่าที่เก็บไว้ก่อนหน้านี้
แคชทั้งสองให้คุณสมบัติหลักเดียวกัน แต่พวกเขาลดค่าใช้จ่าย GC ในรูปแบบที่แตกต่างกัน BigCache อาศัยอยู่บน map[uint64]uint32 , FreeCache ใช้การทำแผนที่ของตัวเองที่สร้างขึ้นบนชิ้นเพื่อลดจำนวนพอยน์เตอร์
ผลลัพธ์จากการทดสอบมาตรฐานแสดงไว้ด้านบน หนึ่งในข้อได้เปรียบของ BigCache มากกว่า FreeCache คือคุณไม่จำเป็นต้องรู้ขนาดของแคชล่วงหน้าเพราะเมื่อ BigCache เต็มมันสามารถจัดสรรหน่วยความจำเพิ่มเติมสำหรับรายการใหม่แทนการเขียนทับรายการที่มีอยู่ในปัจจุบัน อย่างไรก็ตามขนาดสูงสุดของ BigCache สามารถตั้งค่าได้ตรวจสอบ HardmaxCachesize
แพ็คเกจนี้ยังรวมถึงการใช้งาน HTTP ที่ปรับใช้ได้อย่างง่ายดายของ BigCache ซึ่งสามารถพบได้ในแพ็คเกจเซิร์ฟเวอร์
BigCache Genesis อธิบายไว้ในโพสต์บล็อก Allegro.Tech: การเขียนบริการแคชที่รวดเร็วมากใน GO
BigCache เปิดตัวภายใต้ใบอนุญาต Apache 2.0 (ดูใบอนุญาต)