前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >groupcache源码分析

groupcache源码分析

作者头像
月牙寂道长
发布2019-07-02 14:17:50
1.5K0
发布2019-07-02 14:17:50
举报
文章被收录于专栏:月牙寂月牙寂

版权声明:本文为作者原创,如需转载请通知本人,并标明出处和作者。擅自转载的,保留追究其侵权的权利。golang群:570992072。qq 29185807 个人公众号:月牙寂道长 公众号微信号yueyajidaozhang https://cloud.tencent.com/developer/article/1454568

本文公众号文章链接:https://mp.weixin.qq.com/s/nL6iD6oDcFyuZM-eGSllXg

本文csdn博客文章链接:https://cloud.tencent.com/developer/article/1454568

groupcache是go语言开发的缓存库。用于替换memcache的。

代码目录:

主要的代码框架如下

那么我们一个一个来讲解下。

一、lru

github.com/golang/groupcache/lru/lru.go

Cache结构体里,有两个东西关注下。ll list和cache,用了一个map来做查找,用ll来做lru刷新。

二、consistenthash

github.com/golang/groupcache/consistenthash/consistenthash.go

一致性hash,这里的代码也是很简单的。想要了解的,可以先去看看一致性hash原理

三、singleflight

github.com/golang/groupcache/singleflight/singleflight.go

这个文件里的代码很少,但很重要

Group结构体里,包含了一个map,value是call,其中包含了一个wg。这个wg是重点

这里面用了waitgroup来实现并发写的拦截,合并成一个写。

这个才是这个代码的重要之处。

先上锁,从map中查找key锁对应的wg,没找到则new一个wg。找到了则,wg.wait等待

然后解锁,进行回调函数(这里一般为写操作),也就是合并操作。

操作完,则调用wg.done表示操作完成。并从map中将此次key的删除掉。

那些并发wg.wait的操作,这个时候则会等到操作完的信号。

四、byteview sinks

github.com/golang/groupcache/byteview.go

这个代码里面封装了一个数据结构

github.com/golang/groupcache/sinks.go

而这个里面则封装了sink这个接口。然后基于ByteView,又封装了很多sink接口的数据结构。

五、groupcachepb

github.com/golang/groupcache/groupcachepb/groupcache.pb.go

这个是自动生成的代码,protobuf协议,用于http数据传输用的。

六、http

github.com/golang/groupcache/http.go

http的话,就分为两个部分。http server部分,还有一个部分则是分布式peer部分。

先看结构体

最重要的几个为:

HTTPPool.peers 分布式的peers

HTTPPool.httpGetters 分布式的peer得get接口 httpGetter

HTTPPoolOptions.HashFn 一致性hash的hash方法

先看下初始化,初始化后,调用了http.Handle,这个是标准库net/http的Handle。看到这里就知道在注册路由了。路由路径为opts.BasePath,对应的路由处理则为p。

这里有三个重要的东西

BashPath,默认为/_groupcache/

peers,利用一致性hash初始化

注册了PeerPicker,这个是http模块通过peers.go中的接口来与groupcache连接的部分

我们看下httpGetter结构体

看下红色框中的,baseURL,这个就是后面Get的url

再看看注册接口,通过key通过一致性hash查找到peer,然后返回了分布式peer的接口

从分布式peer部分获取cache

先构造了url,由peer的basePath,加上group name再加上key。构造Get获取

最后写入out中

再有就是http server部分。这个为本地向外提供访问接口部分

先讲path进行分割,获取到groupname,key。

然后通过groupcache获取到key对应的value。

最后通过pb编码发送出去。

网络这块就完结了

七、peers接口

github.com/golang/groupcache/peers.go

这个文件里的代码,则为groupcache与http直接的接口部分

这个就是接口

注册接口,这个在http部分已经讲过了

getPeers则为即将要讲解的groupcache部分需要用到的函数。

八、groupcache

github.com/golang/groupcache/groupcache.go

那么一步一步来

Getter为用户需要注册给groupcache的部分,当没有被缓存的时候,需要到原始地方获取value的函数。

Group结构体,解释下重要的部分

getter为用户注册的原始get部分

peers则为与http部分进行联结的接口

maincache为分布式中本地分配到的cache部分

hotcache为分布式中非本地的被本地访问过的cache部分

loadGroup则为fiightGroup是一个合并操作的部分

初始化很简单。有一个loadGroup初始化为了上面介绍过的合并操作。

Get的是,先查找lookupCache,查找不到会load

继续跟踪

先从maincache中查找,再从hotcache中查找。

查找不到则继续load

这里就是合并操作

这里有个double check的概念,又重新lookupcache一次。

查找不到,则获取peer(peers.pickpeer),通过分布式网络获取(getFromPeer)

如果还找不到则getlocally。

最后有一个popilatecache操作。

流程是全部结束了。

继续看下细节部分

从peer获取Get

用户注册的原始获取部分

这里是刷新缓存部分,当缓存超过容量,则刷新掉old cache。

龚浩华

月牙寂道长

QQ 29185807

2018年03月27日

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018年03月28日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档