groupcache源码阅读笔记
2015-07-28 17:45
507 查看
groupcache简介
已发布至个人博客,地址在这里groupcache是大神Brad Fitzpatrick使用golang开发的一个缓存系统。代码地址在这里。可以作为memcache的替代品存在。不过两者也是有不同的,groupcache既是客户端也是服务器,也就是说它是作为一个库存在的,跟业务代码共生,这样的好处就是,部署简单,谁用谁知道。
我在刚开始看代码的时候,grep了半天main,什么都没找到,囧,希望大家先理解这一点。
groupcache的代码结构包括下面几部分:
consistenthash一致性hash,其作用参见这里,在groupcache里,其用来决定key存放在哪个实例里面。
groupcachepb protobuffer的源码在这里,在groupcache中,同一个group中的多个实例交互数据,使用pb,减少数据体积。
lru 这里是最终存数据的地方,里面使用了两种数据结构,map和list,map用来保存key-value数据,list按访问顺序保存value,这样实现lru,在清理数据的时候,将最久未访问的数据清除掉。
singleflight 用来控制调用只被执行一次。在这里用来控制,当数据在本地缓存中不存在时,不会都将请求发到数据库或者其他的实例中,以此来避免”惊群”。实现还是很巧妙的,而且这种方案在golang本身的代码中也有采用,如果你的业务中有类似需求,也可以借鉴此处的代码。
btyeview.go 这个可以理解为一种数据格式,在groupcache中,将所有的value都保存为byteview的格式。优先使用[]byte表示,否则使用string。
groupcache.go 这是groupcache的核心,这里定义了groupcache的核心数据结构—group,以及围绕group的get等核心操作。
http.go 这里是业务和groupcache交互的接口
peers.go 同一个group里可以有多个节点,peers是用来表示这种关系的
sinks.go 这个东西用来接收Get到的数据
Get之旅
下面描述一次Get请求在groupcache里经过的历程。代码在groupcache.go中。首先Group会去初始化它的peers节点,但是又不能每次get的时候都去调用,所以这里采用了sync.once用来保证只执行一次。
将GETS状态+1,跟我们在memcache中看到的各种统计信息一样,用来统计Cache Get, Cache Miss
从当前节点获取缓存内容,从mainCache中获取,如果没有从hotCache中获取。
如果当前节点没有获取到结果,则会从peers的节点中获取内容,如果没有,则会从用户定义的getter方法中获取信息(此时会使用singleflight,来保证只有1个请求会真正发起请求,也就是,如果对当前节点有5个对key=test的请求,则只有1个会真正向peers发起请求,而其他四个请求会block,直到请求返回。而且先从peers请求,再从getter中获取也是有讲究的,因为,如果在3台业务机上同时对key=test发起请求,那么会保证只会调用一次getter,从而避免memcache等缓存的业务冷启动问题)
将获取的结果返回
func (g *Group) Get(ctx Context, key string, dest Sink) error { g.peersOnce.Do(g.initPeers) // 1 g.Stats.Gets.Add(1) // 2 if dest == nil { return errors.New("groupcache: nil dest Sink") } value, cacheHit := g.lookupCache(key) // if cacheHit { g.Stats.CacheHits.Add(1) return setSinkView(dest, value) } // Optimization to avoid double unmarshalling or copying: keep // track of whether the dest was already populated. One caller // (if local) will set this; the losers will not. The common // case will likely be one caller. destPopulated := false value, destPopulated, err := g.load(ctx, key, dest) if err != nil { return err } if destPopulated { return nil } return setSinkView(dest, value) }
groupcache的一种部署架构
groupcache的一种部署架构相关文章推荐
- Go语言将支持Android
- Golang实现的聊天程序服务端和客户端代码分享
- Golang学习笔记(三):控制流
- Golang学习笔记(二):类型、变量、常量
- Golang中的sync.WaitGroup用法实例
- Go语言struct类型介绍
- golang使用正则表达式解析网页
- Golang极简入门教程(三):并发支持
- Golang极简入门教程(四):编写第一个项目
- Golang记录、计算函数执行耗时、运行时间的一个简单方法
- Golang学习笔记(四):array、slice、map
- 理解Golang中的数组(array)、切片(slice)和map
- golang语言中for循环语句用法实例
- Golang学习笔记(一):简介
- golang操作mongodb的方法
- GO语言(golang)基础知识
- ubuntu下搭建Go语言(golang)环境
- Golang 内存模型详解(一)
- 在Golang中使用C语言代码实例
- Golang极简入门教程(二):方法和接口