GroupCache教程

什么是GroupCache

groupcache 是 memcached 作者 Brad Fitzpatrick 用 Go 语言 编写的缓存及缓存过滤库,作为 memcached 许多场景下的替代版本。

groupcache 不像其它的一些缓存数据库有个服务端,需要客户端去连接,换句话说,它本没有服务端或者人人都是服务端。相对于 memcached,groupcache 提供更小的功能集和更高的效率,以第三方库的形式提供服务。

groupcache使用

groupcache 是一个缓存系统,开始应用在 Google 下载站点 dl.google.com,后来也使用在 Google Blogger 和 Google Code 这些数据更改频率较低的系统中。

groupcache 没有 update/delete 命令,只有 set 命令,使用 lru 存储策略,空间占满时便淘汰最不常使用的缓存,所以适合数据更改频率较低的应用。

groupcache 集群使用 “一致性哈希“ 分布节点,单节点出现问题对整体系统影响较小。

GroupCache与Memcached对比

不需要对服务器进行单独的设置,这将大幅度减少部署和配置的工作量。groupcache 既是客户端库也是服务器库,并连接到自己的 peer 上。

具有缓存过滤机制。众所周知,在 memcached 出现 “Sorry,cache miss(缓存丢失)” 时,经常会因为不受控制用户数量的请求而导致数据库(或者其它组件)产生 “惊群效应(thundering herd)”;groupcache 会协调缓存填充,只会将重复调用中的一个放于缓存,而处理结果将发送给所有相同的调用者。

不支持多个版本的值。如果 “foo” 键对应的值是 “bar”,那么键 “foo” 的值永远都是 “bar”。这里既没有缓存的有效期,也没有明确的缓存回收机制,因此同样也没有 CAS 或者 Increment/Decrement。

基于上一点的改变,groupcache 就具备了自动备份 “超热” 项进行多重处理,这就避免了 memcached 中对某些键值过量访问而造成所在机器 CPU 或者 NIC 过载。

GroupCache特性

groupcache 避免多次非缓存查询, 并且支持多节点缓存(即便多节点,也还支持同一个 key 同一时刻只查询一次)。除此之外还支持分组,不同分组有各自的查询方式和缓存,分组只是逻辑上的,互不影响,所以这里分组同一分组的情况。

groupcache 没有支持 cache 的过期时间,而是限制 cache 的总内存大小,通过 LRU 的方法使用 cache,到达上限后,最少被使用的会被最先清除出缓存。

groupcache 在此基础上,添加了多节点的支持,每个节点(peer)都有缓存,只缓存属于它的 key(通过将字符串 key 平均分到不同的 peer)。

不同的 peer 只负责查询和缓存它的属于它的 key。如果一个 peer 接收到不属于它的 key,它就转发到别的 peer 上进行查询。什么 key 属于哪个 peer 通过一个神奇的 hash 算法实现的。

只加载一次是 groupcache 最重要的特性,groupcache 可以阻止加载两次,因为一次 Load 操作开始并未完成前,后面的其它查询都会等待这个结果,这其它查询包括从本地的查询和从别的节点的查询。假设一种查询路经(这个例子中,耗时的操作只在 peer2 中进行了一次):

  • 查询节点 peer1,查询的 key 不属于 peer1。
  • peer1 发现这个 key 属于 peer2,以同一 key 查询 peer2。
  • peer2 发现该 key 属于自己,但没有在自己的缓存中。
  • peer2 发起耗时查询(比如 DB 查询)并等待完成。
  • 再次以同一 key 查询节点 peer1,但是 peer1 还有同一个 key 的查询还未完成,所以阻塞等待。
  • 以同一 key 查询 peer2, peer2 发现这个 key 属于自己,但没有自己的缓存中。
  • peer2 发起查询,但是 peer2 的同一个 key 还在查询,所以等待。
  • peer2 的第一个查询完成,并放到 peer2 的 main cache 中 。peer2 的第二个查询被通知,得到同一结果。
  • peer2 的第一个查询是 peer1 转发来的,所以结果被返回 peer1,并被放到 peer1 的 hot cache 中,peer1 的第一个查询结束。peer1 的第二个被阻塞的查询也被通知而拿到了结果。

groupcache教程总结

groupcache 是 memcached 作者 Brad Fitzpatrick 用 Go 语言编写的缓存及缓存过滤库,作为 memcached 许多场景下的替代版本。