Skip to content

Commit

Permalink
注解
Browse files Browse the repository at this point in the history
  • Loading branch information
[email protected] committed May 25, 2020
1 parent bbc607a commit 9d59005
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 6 deletions.
8 changes: 8 additions & 0 deletions ReadMe_CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@

### 功能介绍
groupcache是go语言开发的缓存库。用于替换memcache的。
#### 客户端行为
```text
当客户端连上groupcache时,能做的只有get获取数据,如果本地有所需要的数据,则直接返回,
如果没有,则通过一致性哈希函数判断这个key所对应的peer,然后通过http从这个peer上获取数据;
如果这个peer上有需要的数据,则通过http回复给之前的那个groupcache;groupcache收到之后,保存在本地hotCache中,并返回给客户端;
如果peer上也没有所需要的数据,则groupcache从数据源(数据库或者文件)获取数据,并将数据保存在本地mainCache,并返回给客户端
```

#### 系统框架
![](./2.png)

Expand Down
18 changes: 12 additions & 6 deletions groupcache.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,9 +145,12 @@ func callInitPeerServer() {
// 对于一个 Group 来说,会缓存自己节点的数据和访问比较频繁的 peer节点 的数据,用LRU算法控制缓存。
// 当 cache 没有命中的时候,首先看看这个请求归不归该节点管,若是就是调用 getter:
type Group struct {
name string
getter Getter // 传入的回调函数,给出了当本地miss同时缓存节点miss,或者本地miss,但该key属于本节点维护时该如何获取数据的函数
peersOnce sync.Once
name string
getter Getter // 传入的回调函数,给出了当本地miss同时缓存节点miss,或者本地miss,但该key属于本节点维护时该如何获取数据的函数
peersOnce sync.Once
// http实现了该接口,使用
// func (p *HTTPPool) PickPeer(key string) (ProtoGetter, bool)
// 函数选取节点
peers PeerPicker // peer 节点调度器
cacheBytes int64 // 最大cache字节数

Expand Down Expand Up @@ -211,12 +214,12 @@ func (g *Group) initPeers() {
}

func (g *Group) Get(ctx context.Context, key string, dest Sink) error {
g.peersOnce.Do(g.initPeers) // 首次运行,初始化对等节点
g.peersOnce.Do(g.initPeers) // 首次运行,初始化对等节点,把httppool赋值给 groupcache.PeerPicker
g.Stats.Gets.Add(1) // 设置stats
if dest == nil { // 必须指定数据载体
return errors.New("groupcache: nil dest Sink")
}
// 必须指定数据载体
// 必须指定数据载体(从maincache、hotcache查找)
value, cacheHit := g.lookupCache(key)

// 本地缓存命中
Expand All @@ -240,12 +243,14 @@ func (g *Group) Get(ctx context.Context, key string, dest Sink) error {
if destPopulated {
return nil
}
return setSinkView(dest, value)
return setSinkView(dest, value) // 把数据设置给sink
}

// load loads key either by invoking the getter locally or by sending it to another machine.
// 从对等节点或自定义查找逻辑(getter)中获取数据
func (g *Group) load(ctx context.Context, key string, dest Sink) (value ByteView, destPopulated bool, err error) {
g.Stats.Loads.Add(1)
// loadGroup.Do是个竞争的方法,相同的key同时只会有一个访问
viewi, err := g.loadGroup.Do(key, func() (interface{}, error) {
// Check the cache again because singleflight can only dedup calls
// that overlap concurrently. It's possible for 2 concurrent
Expand Down Expand Up @@ -278,6 +283,7 @@ func (g *Group) load(ctx context.Context, key string, dest Sink) (value ByteView
g.Stats.LoadsDeduped.Add(1)
var value ByteView
var err error
// 通过一致性hash获取对等节点,与httppool对应
if peer, ok := g.peers.PickPeer(key); ok {
// 根据分布式一致性hash查找对应节点, ok为true表明不是本机
// 向对应节点请求数据
Expand Down
3 changes: 3 additions & 0 deletions peers.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ type PeerPicker interface {
// NoPeers is an implementation of PeerPicker that never finds a peer.
type NoPeers struct{}

// 所有的peer结构都要实现PeerPicker接口,即给定一个字符串,返回一个ProtoGetter,ok bool。
// 在后面还会看到,如果是有peer的情况,用的是HTTPPool来代替NoPeers。
func (NoPeers) PickPeer(key string) (peer ProtoGetter, ok bool) { return }

var (
Expand Down Expand Up @@ -73,6 +75,7 @@ func RegisterPerGroupPeerPicker(fn func(groupName string) PeerPicker) {
portPicker = fn
}

// 会根据groupName返回这种peer结构,当然它们的共同点是一样的,也就是返回值类型为PeerPicker接口
func getPeers(groupName string) PeerPicker {
if portPicker == nil {
return NoPeers{}
Expand Down

0 comments on commit 9d59005

Please sign in to comment.