美文网首页
groupcache 一 sigleflight

groupcache 一 sigleflight

作者: n_xy | 来源:发表于2021-04-08 17:20 被阅读0次

    缓存击穿

    百度给的定义:

    缓存击穿是指热点key在某个时间点过期的时候,而恰好在这个时间点对这个Key有大量的并发请求过来,从而大量的请求打到db。

    在某个时间点缓存大量过期,导致原来应该命中的请求未命中,直接请求数据库,然后数据库就识相的挂掉了。

    解决方法有很多,在学groupcache源码中发现了一个有趣的库--sigleflight,groupcache获取缓存的方式大概是: 本地cache-其他节点cache-数据源。这样的话会产生一种情况就是许多请求的是同一个数据,sigleflight就是为了防止这种情况,它会把所有的同一目标请求集中发送一次.

    源码

    两个结构体

    //实际请求函数的封装
    // call is an in-flight or completed Do call
    type call struct {
        wg  sync.WaitGroup
        //
        val interface{}
        err error
    }
    //管理所有对不同key的请求映射
    // Group represents a class of work and forms a namespace in which
    // units of work can be executed with duplicate suppression.
    type Group struct {
        mu sync.Mutex       // protects m
        //管理现存的调用的映射
        m  map[string]*call // lazily initialized
    }
    
    

    接下来就是执行请求的函数,也是保证只请求一次的关键

    //fn 是实际请求的函数,返回结果和错误(interface{}, error)
    // Do executes and returns the results of the given function, making
    // sure that only one execution is in-flight for a given key at a
    // time. If a duplicate comes in, the duplicate caller waits for the
    // original to complete and receives the same results.
    func (g *Group) Do(key string, fn func() (interface{}, error)) (interface{}, error) {
        //map会改变,所以上锁
        g.mu.Lock()
        if g.m == nil {
            g.m = make(map[string]*call)
        }
        //请求已经存在,放锁等待
        if c, ok := g.m[key]; ok {
            g.mu.Unlock()
            c.wg.Wait()
            return c.val, c.err
        }
        //不存在 新建一个存进去
        c := new(call)
        //只需要在这里加一就可
        c.wg.Add(1)
        g.m[key] = c
        g.mu.Unlock()
        
        //执行完毕,通知等待的请求
        c.val, c.err = fn()
        c.wg.Done()
        
        //请求完了删除map映射
        g.mu.Lock()
        delete(g.m, key)
        g.mu.Unlock()
    
        return c.val, c.err
    }
    
    

    相关文章

      网友评论

          本文标题:groupcache 一 sigleflight

          本文链接:https://www.haomeiwen.com/subject/dkdtkltx.html