diff --git a/1.png b/1.png new file mode 100644 index 0000000..0214969 Binary files /dev/null and b/1.png differ diff --git a/ReadMe_CN.md b/ReadMe_CN.md new file mode 100644 index 0000000..43fbf11 --- /dev/null +++ b/ReadMe_CN.md @@ -0,0 +1,27 @@ +## groupcache快速入门 + +### 功能介绍 +groupcache是go语言开发的缓存库。用于替换memcache的。 +#### 代码框架 +![](./1.png) + +### 使用入门 +```shell +cd example +go build +./main 127.0.0.1:8001 127.0.0.1:8002 127.0.0.1:8003 +``` + +### 分析目的 ++ consistenthash(提供一致性哈希算法的支持), ++ lru(提供了LRU方式清楚缓存的算法), ++ singleflight(保证了多次相同请求只去获取值一次,减少了资源消耗), +https://segmentfault.com/a/1190000018464029 + +### 参考资料 ++ [《groupcache 使用入门》](http://betazk.github.io/2014/12/groupcache%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8%E7%9A%84%E4%B8%80%E4%B8%AA%E7%AE%80%E5%8D%95%E4%BE%8B%E5%AD%90/) ++ [Playing with groupcache](https://capotej.com/blog/2013/07/28/playing-with-groupcache/) + + +https://www.jianshu.com/p/5c3db568b8b8 +https://juejin.im/entry/57c3ce697db2a200680ab024 \ No newline at end of file diff --git a/example/go.mod b/example/go.mod new file mode 100644 index 0000000..fd3f90c --- /dev/null +++ b/example/go.mod @@ -0,0 +1,7 @@ +module main + +go 1.14 + +require github.com/golang/groupcache v0.0.0 + +replace github.com/golang/groupcache v0.0.0 => ../ diff --git a/example/go.sum b/example/go.sum new file mode 100644 index 0000000..2a44bb7 --- /dev/null +++ b/example/go.sum @@ -0,0 +1,19 @@ +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= diff --git a/example/main b/example/main new file mode 100755 index 0000000..98dfdb9 Binary files /dev/null and b/example/main differ diff --git a/example/main.go b/example/main.go new file mode 100644 index 0000000..49fdd7c --- /dev/null +++ b/example/main.go @@ -0,0 +1,77 @@ +package main + +import ( + "context" + "flag" + "fmt" + "io/ioutil" + "log" + "net/http" + "os" + "strconv" + "strings" + + "github.com/golang/groupcache" +) + +var ( + peers_addrs = []string{"127.0.0.1:8001", "127.0.0.1:8002", "127.0.0.1:8003"} + rpc_addrs = []string{"127.0.0.1:9001", "127.0.0.1:9002", "127.0.0.1:9003"} + index = flag.Int("index", 0, "peer index") +) + +func main() { + flag.Parse() + peers_addrs := make([]string, 3) + rpc_addrs := make([]string, 3) + if len(os.Args) > 0 { + for i := 1; i < 4; i++ { + peers_addrs[i-1] = os.Args[i] + rpcaddr := strings.Split(os.Args[i], ":")[1] + port, _ := strconv.Atoi(rpcaddr) + rpc_addrs[i-1] = ":" + strconv.Itoa(port+1000) + } + } + if *index < 0 || *index >= len(peers_addrs) { + fmt.Printf("peer_index %d not invalid\n", *index) + os.Exit(1) + } + peers := groupcache.NewHTTPPool(addrToURL(peers_addrs[*index])) + var stringcache = groupcache.NewGroup("SlowDBCache", 64<<20, groupcache.GetterFunc( + func(ctx context.Context, key string, dest groupcache.Sink) error { + result, err := ioutil.ReadFile(key) + if err != nil { + log.Fatal(err) + return err + } + fmt.Printf("asking for %s from dbserver\n", key) + dest.SetBytes([]byte(result)) + return nil + })) + + peers.Set(addrsToURLs(peers_addrs)...) + + http.HandleFunc("/zk", func(rw http.ResponseWriter, r *http.Request) { + log.Println(r.URL.Query().Get("key")) + var data []byte + k := r.URL.Query().Get("key") + fmt.Printf("cli asked for %s from groupcache\n", k) + stringcache.Get(nil, k, groupcache.AllocatingByteSliceSink(&data)) + rw.Write([]byte(data)) + }) + go http.ListenAndServe(rpc_addrs[*index], nil) + rpcaddr := strings.Split(os.Args[1], ":")[1] + log.Fatal(http.ListenAndServe(":"+rpcaddr, peers)) +} + +func addrToURL(addr string) string { + return "http://" + addr +} + +func addrsToURLs(addrs []string) []string { + result := make([]string, 0) + for _, addr := range addrs { + result = append(result, addrToURL(addr)) + } + return result +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..646ee36 --- /dev/null +++ b/go.mod @@ -0,0 +1,8 @@ +module groupcache + +go 1.14 + +require ( + github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e + github.com/golang/protobuf v1.4.2 +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..3ffe5d2 --- /dev/null +++ b/go.sum @@ -0,0 +1,20 @@ +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=