当前位置:网站首页>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 .
边栏推荐
- Research Report on the overall scale, major manufacturers, major regions, products and applications of building automation power meters in the global market in 2022
- Research Report on the overall scale, major manufacturers, major regions, products and applications of capacitive voltage transformers in the global market in 2022
- Research Report on the overall scale, major manufacturers, major regions, products and applications of micro hydraulic cylinders in the global market in 2022
- Is it safe to buy funds on securities accounts? Where can I buy funds
- Function, function, efficiency, function, utility, efficacy
- [hands on deep learning]02 softmax regression
- SBT tutorial
- Is it safe to open an account for online stock speculation? I'm a novice, please guide me
- [871. Minimum refueling times]
- Cron表达式(七子表达式)
猜你喜欢
Friends who firmly believe that human memory is stored in macromolecular substances, please take a look
Data preparation for behavior scorecard modeling
八年测开经验,面试28K公司后,吐血整理出高频面试题和答案
Talk about macromolecule coding theory and Lao Wang's fallacy from the perspective of evolution theory
The metamask method is used to obtain account information
[cloud native topic -49]:kubesphere cloud Governance - operation - step by step deployment of microservice based business applications - basic processes and steps
Sometimes only one line of statements are queried, and the execution is slow
【Hot100】21. 合并两个有序链表
Redis sentinel cluster working principle and architecture deployment # yyds dry goods inventory #
Review of the latest 2022 research on "deep learning methods for industrial defect detection"
随机推荐
SBT tutorial
台湾SSS鑫创SSS1700替代Cmedia CM6533 24bit 96KHZ USB音频编解码芯片
Burp install license key not recognized
CS5268完美代替AG9321MCQ Typec多合一扩展坞方案
[cloud native topic -49]:kubesphere cloud Governance - operation - step by step deployment of microservice based business applications - basic processes and steps
Driverless learning (4): Bayesian filtering
Exemple complet d'enregistrement du modèle pytoch + enregistrement du modèle pytoch seuls les paramètres d'entraînement sont - ils enregistrés? Oui (+ Solution)
At compilation environment setup -win
外包干了三年,废了...
Web3js method to obtain account information and balance
Spark source code compilation, cluster deployment and SBT development environment integration in idea
Add two numbers of leetcode
Research Report on the overall scale, major manufacturers, major regions, products and applications of capacitive voltage transformers in the global market in 2022
[fluent] dart generic (generic class | generic method | generic with specific type constraints)
How can testers do without missing tests? Seven o'clock is enough
For (Auto A: b) and for (Auto & A: b) usage
Complete example of pytorch model saving +does pytorch model saving only save trainable parameters? Yes (+ solution)
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
Talk about macromolecule coding theory and Lao Wang's fallacy from the perspective of evolution theory
pytorch 模型保存的完整例子+pytorch 模型保存只保存可训练参数吗?是(+解决方案)