groupcache的设计和实现分析

groupcache的设计和实现分析

            本文基于groupcache源码, 分析分布式缓存系统的设计和实现过程。本文代码大部分是来自groupcache的源码,但根据分析的需要做了少许改动。

1.本地缓存系统


            本地缓存系统的基本结构如上图所示。在内存中维护一个cache。查询时,首先查询cache中是否已经缓存查询结果。如果已经缓存,直接返回缓存结果,如果没有缓存,将查询结果Load到cache中,然后返回结果。代码如下:

type Value interface{}
type Cache interface {
    Get(key string) (Value, bool)
    Add(key string, val Value)
}

type Group struct {
    cache Cache
}

func (g *Group) Get(key string) Value {
    //look up cache first
    val, cacheHit := g.lookupCache(key)
    if cacheHit {
        return val
    }
    //if miss, load value to cache
    val = g.load(key)
    return val
}

func (g *Group) lookupCache(key) (Value, bool) {
    val, ok := g.cache.Get(key)
    return val, ok
}

2.分布式缓存系统

            在设计分布式缓存系统的时候,需要让key分布在不同的缓存节点上。当某节点收到查询请求时,如果该key归属于本节点,则在本节点获取查询结果;如果该key归属于其他节点,则本节点向归属节点获取查询结果 。如下图所示:


            此分布式缓存架构引入了2个新的问题:

1.    如何判断查询的key归属哪个节点

2.    如何从其他节点获取数据

            第1个问题实际上是一个路由问题,即给定key,路由到某个节点。这里忽略具体实现,将问题抽象出来,由2个接口表示(对应于groupcache的ProtoGetter和PeerPicker):

type Peer interface{
    Get(key string) Value
}

type Router interface{
    Route(key string) Peer
}

            接口Peer表示一个远端节点,Get方法从远端节点查询数据;接口Router表示一个路由器,Route方法将给定key路由到其归属的远端节点,如果key归属于本节点,Route方法返回nil。基于此,改写Group结构体和Group.load方法:

type Group struct {
    router Router
    cache  Cache
}
func (g *Group) load(key string) Value {
    peer := g.router.Route(key)
    if peer == nil {
        val := g.getLocally(key)
        g.cache.Add(key, val) //store result in cache
        return val
    }
    return peer.Get(g.name, key)
}

            至此,一个分布式缓存框架搭建完成了,接下来分析具体细节的实现和功能的优化完善。

 

2.1. Cache的内存结构

        Cache对象是内存中的一个容器,用来存放查询的结果。

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值