当前位置:网站首页>Go cache of go cache series
Go cache of go cache series
2022-07-02 20:55:00 【firstcode666】
go
Copyright
I'm a lovely groundhog , Focus on sharing Go In the workplace 、 Recruitment and job hunting , Explain Gopher Worry about ! Welcome to follow me .
Welcome aboard Go Recruitment exchange group , Come here to find like-minded friends ! Communicate and learn with marmots .
One sentence description
go-cache [1] Memory based K/V Storage / cache : ( Be similar to Memcached), For stand-alone applications
brief introduction
go-cache What is it? ?
Memory based K/V Storage / cache : ( Be similar to Memcached), For stand-alone applications , Support delete , Be overdue , Default Cache Shared lock ,
A lot of key In this case, lock competition will be serious
Why choose go-cache?
Can store any object ( Store for a given duration or permanently ), And can be composed of multiple goroutine Use cache safely .
Example
package main
import (
"fmt"
"time"
"github.com/patrickmn/go-cache"
)
type MyStruct struct {
Name string
}
func main() {
// Set timeout and cleanup time
c := cache.New(5*time.Minute, 10*time.Minute)
// Set the cache value and bring the expiration time
c.Set("foo", "bar", cache.DefaultExpiration)
// Set no expiration time KEY, This KEY Will not be automatically cleared , Want to clear use :c.Delete("baz")
c.Set("baz", 42, cache.NoExpiration)
var foo interface{}
var found bool
// Get value
foo, found = c.Get("foo")
if found {
fmt.Println(foo)
}
var foos string
// Get value , And assert that
if x, found := c.Get("foo"); found {
foos = x.(string)
fmt.Println(foos)
}
// Operate on the structure pointer
var my *MyStruct
c.Set("foo", &MyStruct{Name: "NameName"}, cache.DefaultExpiration)
if x, found := c.Get("foo"); found {
my = x.(*MyStruct)
// ...
}
fmt.Println(my)
}
Source code analysis
Source code analysis mainly focuses on the core storage structure 、Set、Get、Delete、 Regular cleaning logic for analysis . Including the overall logical architecture
Core storage structure
package cache
// Item Each specific cache value
type Item struct {
Object interface{}
Expiration int64 // Expiration time : Setup time + Cache time
}
// Cache Overall cache
type Cache struct {
*cache
}
// cache Overall cache
type cache struct {
defaultExpiration time.Duration // Default timeout
items map[string]Item // KV Yes
mu sync.RWMutex // Read-write lock , In operation ( increase , Delete ) Cache with
onEvicted func(string, interface{}) // Delete KEY At the time of the CallBack function
janitor *janitor // Periodically clear the cache structure
}
// janitor Periodically clear the cache structure
type janitor struct {
Interval time.Duration // How often to scan the cache
stop chan bool // Whether you need to stop
}
Set
package cache
func (c *cache) Set(k string, x interface{}, d time.Duration) {
// "Inlining" of set
var e int64
if d == DefaultExpiration {
d = c.defaultExpiration
}
if d > 0 {
e = time.Now().Add(d).UnixNano()
}
c.mu.Lock() // Here you can use defer?
c.items[k] = Item{
Object: x, // The actual data
Expiration: e, // Next expiration time
}
c.mu.Unlock()
}
Get
package cache
func (c *cache) Get(k string) (interface{}, bool) {
c.mu.RLock() // Lock , Limit concurrent reads and writes
item, found := c.items[k] // stay items This map[string]Item Find data
if !found {
c.mu.RUnlock()
return nil, false
}
if item.Expiration > 0 {
if time.Now().UnixNano() > item.Expiration { // It's overdue , Go straight back to nil, Why not delete it directly here ?
c.mu.RUnlock()
return nil, false
}
}
c.mu.RUnlock()
return item.Object, true
}
Delete
package cache
// Delete an item from the cache. Does nothing if the key is not in the cache.
func (c *cache) Delete(k string) {
c.mu.Lock()
v, evicted := c.delete(k)
c.mu.Unlock()
if evicted {
c.onEvicted(k, v) // Delete KEY At the time of the CallBack
}
}
func (c *cache) delete(k string) (interface{}, bool) {
if c.onEvicted != nil {
if v, found := c.items[k]; found {
delete(c.items, k)
return v.Object, true
}
}
delete(c.items, k)
return nil, false
}
Scheduled cleanup logic
package cache
func newCacheWithJanitor(de time.Duration, ci time.Duration, m map[string]Item) *Cache {
c := newCache(de, m)
C := &Cache{c}
if ci > 0 {
runJanitor(c, ci) // Run regularly to clear expired KEY
runtime.SetFinalizer(C, stopJanitor) // When C By GC Recovery time , Will stop runJanitor Association in
}
return C
}
func runJanitor(c *cache, ci time.Duration) {
j := &janitor{
Interval: ci,
stop: make(chan bool),
}
c.janitor = j
go j.Run(c) // The new collaboration process does expiration deletion logic
}
func (j *janitor) Run(c *cache) {
ticker := time.NewTicker(j.Interval)
for {
select {
case <-ticker.C: // Every cycle is traversed once
c.DeleteExpired() // Actual deletion logic
case <-j.stop:
ticker.Stop()
return
}
}
}
// Delete all expired items from the cache.
func (c *cache) DeleteExpired() {
var evictedItems []keyAndValue
now := time.Now().UnixNano()
c.mu.Lock()
for k, v := range c.items { // Lock and traverse the whole list
// "Inlining" of expired
if v.Expiration > 0 && now > v.Expiration {
ov, evicted := c.delete(k)
if evicted {
evictedItems = append(evictedItems, keyAndValue{k, ov})
}
}
}
c.mu.Unlock()
for _, v := range evictedItems {
c.onEvicted(v.key, v.value)
}
}
reflection
Lock Use
stay go-cache in , It involves reading and writing cache, Basically, locks are used , And the lock is also used when traversing , When cache When the number is very large , When reading and writing frequently , There will be serious lock conflicts .
Use a read-write lock ?
sync.RWMutex, Add RLock, Multiple reads can be allowed . Add Lock, No other reading and writing is allowed .
Whether the granularity of locks can be changed small ?
according to KEY HASH To different map in
Use sync.map?
Reduce the use of locks
runtime.SetFinalizer
In actual programming , We all want to execute a method when each object is released , Perform some counting within this method 、 Release or specific requirements , In the past, the object pointer was set nil Before calling a specific method , golang Provides runtime.SetFinalizer function , When GC When preparing to release objects , The method specified by this function will be called back , Very convenient and effective .
Object can be associated with a SetFinalizer function , When gc detected unreachable Object has an associated SetFinalizer Function time , Will execute the associated SetFinalizer function , At the same time, cancel the Association . So next time gc When , The object is back in unreachable state And there's no SetFinalizer relation , It will be recycled .
Doc
https://pkg.go.dev/github.com/patrickmn/go-cache
Compare
Similar Libraries
https://github.com/golang/groupcache
https://github.com/allegro/bigcache
https://github.com/coocood/freecache
Reference material
[1]
go-cache : https://github.com/patrickmn/go-cache
Data sharing , You can get it by replying to the secret code in the background of official account
【100】Go Resume template of senior engineer
【101 】Go The most complete interview collection in the whole network
【102】Go Super resume
Recommended reading
Welcome to follow me ! Get more information about recruitment .
边栏推荐
- 2021 v+ Quanzhen internet global innovation and Entrepreneurship Challenge, one of the top ten audio and video scene innovation and application pioneers
- Lantern Festival, come and guess lantern riddles to win the "year of the tiger Doll"!
- 想问问,现在开户有优惠吗?在线开户是安全么?
- Don't you want to have a face-to-face communication with cloud native and open source experts? (including benefits
- Welfare | Pu Aries | liv heart co branded Plush surrounding new products are on the market!
- Google Earth Engine(GEE)——Landsat 9影像全波段影像下载(北京市为例)
- Share several map bed websites for everyone to share pictures
- 股票开户要找谁?手机开户是安全么?
- 「 工业缺陷检测深度学习方法」最新2022研究综述
- Research Report on the overall scale, major manufacturers, major regions, products and application segmentation of sound quality head simulators in the global market in 2022
猜你喜欢
【871. 最低加油次数】
Web3js method to obtain account information and balance
[source code analysis] model parallel distributed training Megatron (5) -- pipestream flush
Postman interface test practice, these five questions you must know
Properties of expectation and variance
[cloud native topic -49]:kubesphere cloud Governance - operation - step by step deployment of microservice based business applications - basic processes and steps
SBT tutorial
[QT] QPushButton creation
Taiwan SSS Xinchuang sss1700 replaces cmmedia cm6533 24bit 96KHz USB audio codec chip
Implementing yolox from scratch: dataset class
随机推荐
Research Report on the overall scale, major manufacturers, major regions, products and applications of sliding door dampers in the global market in 2022
Taiwan SSS Xinchuang sss1700 replaces cmmedia cm6533 24bit 96KHz USB audio codec chip
Talk about macromolecule coding theory and Lao Wang's fallacy from the perspective of evolution theory
[12] the water of the waves is clear, which can wash my tassel. The water of the waves is muddy, which can wash my feet
Welfare | Hupu isux11 Anniversary Edition is limited to hand sale!
Research Report on the overall scale, major manufacturers, major regions, products and applications of building automation power meters in the global market in 2022
I would like to ask what securities dealers recommend? Is it safe to open a mobile account?
sense of security
1007 maximum subsequence sum (25 points) "PTA class a exercise"
「 工业缺陷检测深度学习方法」最新2022研究综述
Driverless learning (III): Kalman filter
Cs5268 perfectly replaces ag9321mcq typec multi in one docking station solution
GCC: Graph Contrastive Coding for Graph Neural NetworkPre-Training
Research Report on the overall scale, major manufacturers, major regions, products and application segmentation of multi-channel signal conditioners in the global market in 2022
Codeforces round 651 (Div. 2) (a thinking, B thinking, C game, D dichotomy, e thinking)
Wu Enda's machine learning mind mapping insists on clocking in for 23 days - building a knowledge context, reviewing, summarizing and replying
Summary of interview experience, escort your offer, full of knowledge points
[internship] solve the problem of too long request parameters
How to do interface testing? After reading this article, it will be clear
Data preparation for behavior scorecard modeling