groupcache源码阅读(二)——缓存并发控制
本文最后更新于:2024年7月6日 早上
互斥锁——sync.Mutex
多个协程(goroutine)同时读写同一个变量,在并发度较高的情况下,会发生冲突。确保一次只有一个协程(goroutine)可以访问该变量以避免冲突,这称之为互斥
,互斥锁可以解决这个问题。
sync.Mutex 是一个互斥锁,可以由不同的协程加锁和解锁。
sync.Mutex
是 Go 语言标准库提供的一个互斥锁,当一个协程(goroutine)获得了这个锁的拥有权后,其它请求锁的协程(goroutine) 就会阻塞在 Lock()
方法的调用上,直到调用 Unlock()
锁被释放。
Groupcache的并发数据对象
ByteView
对于Groupcache这种key、value的缓存,value再上一篇文章中显示了是一个空接口。而这里用ByteView
明确了,value的具体含义。
只读数据结构 ByteView
用来表示缓存值,是 GeeCache 主要的数据结构之一
1 |
|
ByteView对象配套的增删改查
1 |
|
cache再度封装lru.Cache
在groupcache.go中定义的cache是对底层lur的并发封装
1 |
|
对应的增删改查:
1 |
|
主体结构 Group
Group 是 GroupCache 最核心的数据结构,负责与用户的交互,并且控制缓存值存储和获取的流程。
具体流程如下:
上述的过程均在group对象中完成,以下是group的结构体:
1 |
|
对Group的实例化:
1 |
|
Group 的 Get 方法
1 |
|
- Get 方法实现了上述所说的流程 。
- 流程 1:从 mainCache 中查找缓存,如果存在则返回缓存值。
- 流程 2:节点选择,判断是本地还是远端节点
- 流程 3:缓存不存在,则调用 load 方法,load 调用 getLocally(分布式场景下会调用 getFromPeer 从其他节点获取),getLocally 调用用户回调函数
g.getter.Get()
获取源数据,并且将源数据添加到缓存 mainCache 中(通过 populateCache 方法)
总结
通过上面的代码已经可以看出Group单节点内,对于并发请求缓存数据,实际上就是加入了一个互斥锁,已经对缓存数据进行只读拷贝,确保读取的安全。