博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
groupcache源码分析
阅读量:4030 次
发布时间:2019-05-24

本文共 2445 字,大约阅读时间需要 8 分钟。

 

本文公众号文章链接:

本文csdn博客文章链接:

 

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日

第一时间获取文章,可以关注本人公众号:月牙寂道长,也可以扫码关注

 

你可能感兴趣的文章
No.182 - LeetCode1325 - C指针的魅力
查看>>
mac:移动python包路径
查看>>
mysql:sql create database新建utf8mb4 数据库
查看>>
mysql:sql alter database修改数据库字符集
查看>>
mysql:sql alter table 修改列属性的字符集
查看>>
mysql:sql drop table (删除表)
查看>>
mysql:sql truncate (清除表数据)
查看>>
scrapy:xpath string(.)非常注意问题
查看>>
yuv to rgb 转换失败呀。天呀。谁来帮帮我呀。
查看>>
yuv420 format
查看>>
单纯的把Y通道提取出来能正确显示出灰度图来为什么我的Qt就显示不出来呢转换有问题呀?
查看>>
YUV420只绘制Y通道
查看>>
yuv420 还原为RGB图像
查看>>
LED恒流驱动芯片
查看>>
驱动TFT要SDRAM做为显示缓存
查看>>
使用file查看可执行文件的平台性,x86 or arm ?
查看>>
qt5 everywhere 编译summary
查看>>
qt5 everywhere编译完成后,找不到qmake
查看>>
arm-linux开机读取硬件时钟,设置系统时钟。
查看>>
交叉编译在x86上调试好的qt程序
查看>>