参考
groupcache源码解析-概览
consistent hash(一致性哈希算法)
Memcached大家应该都不陌生,官网的介绍是:Free & open source, high-performance, distributed memory object caching system(免费,开源,高性能的分布式内存对象缓存系统)。很多公司的产品都用到了Memcached,不过Memcached是用C语言开发的,我们的目的是提升Golang技能,所以这里我找了Golang版本的Memcached:groupcache来分析。
github地址:https://github.com/golang/groupcache
github上对groupcahe的介绍是:groupcache is a caching and cache-filling library, intended as a replacement for memcached in many cases.也就是说这是一个库,目标是在很多场景下替代memcached.等看完源码我们再反过来看groupcache有哪些优秀的特性,对比来看官方介绍里的一堆特性介绍。
一、项目概览

咋一看不太直观,consistenthash是一致性哈希,groupcachepb应该是和Protocol Buffers有关系,lru是最近最少使用淘汰算法,singleflight是单航班,什么是单航班后面看了代码再来理解吧~,testpb和groupcachepb一样,pb结尾和Protocol Buffers逃脱不了干系了。剩下的一堆根目录的源码文件啥的肯定是各种调用上面说到的几个包,所以这里我们先看最上面的5个文件夹(package)分别是什么内容,分模块攻破之后再看外层调用逻辑,把知识点再串联到一起。
groupchace明显比cache2go知识量大,源码中至少包含了以下知识点,大家可以提前Google一下这些知识点,比如rpc是什么,golang中如何使用rpc;protobuf怎么用,ring hash(一致性哈希)算法原理,lru算法原理等,singleflight是一种编程技巧,看了源码我们再来体会其中妙处。
二、一致性哈希算法
关于哈希算法,可以参考hash算法
关于一致性哈希算法,强烈建议阅读白话解析consistent hash 一致性哈希算法
看一下第一个package:【package consistenthash】的内容


从上图我们可以看到,这里只需要关注consistenthash.go这源码文件,里面有2个类型:Hash和Map,1个函数New,Map类型有4个不可导出的属性以继3个绑定的方法。
下面一个个看吧~
1、类型Hash(需要记得Hash是一个函数类型哦)。

2、Map类型(Map类型的第一个属性就是上面的Hash类型变量hash,replicas属性表示的是副本数,还记得上面我们提到的为了解决平衡性问题而引入的虚拟节点的概念吗?这些虚拟节点这是这里描述的副本数)。

3、New()函数(这个函数明显就是用来获取上面的Map类型变量实例的,初始化副本数、hash函数、hashMap表,hashMap表的key是一个表示cache服务器或者副本的hash值,value为一个具体的cache服务器,这样就完成了Cache A、Cache A1、Cache A2等副本全部映射到Cache A的功能。

4、IsEmpty()函数(这个函数就没啥可讲的了,非空判断)

5、Add()函数(将缓存服务器加到Map中,比如Cache A、Cache B作为keys,如果副本数指定的是2,那么Map中存的数据是Cache A#1、Cache A#2、Cache B#1、Cache B#2的hash结果)

6、Get()函数(这个函数相对复杂一点,比如有一个数据:name="张三"这条数据需要存,这时候通过这个函数选择一个cache服务器,返回的string类型可以是服务器ip,比如:"192.168.0.1",从而调用者能够将name="张三"存到"192.168.0.1"上)

网友评论