前言
这篇专注讲golang的缓存生态,把github上golang缓存比较好的项目集中起来分析一下,也算是给之后的发展打补丁。
一 golang缓存现状
缓存框架的必备要求:
1.支持并发
合理运用锁,什么时候加锁什么时候解锁,防止脏数据;又要防止死锁活锁资源占用
合理运用golang sync包实现了两种锁Mutex (互斥锁)和RWMutex(读写锁)
2.支持内存限制 ( 限制最大的可使用空间 )
怎么去设定缓存参数使得缓存的内存限制得到有效的控制。涉及到golang gc,缓存要对内存实际使用量做限制,内存激增同样会导致资源竞争问题。
Go 请求内存很容易,但释放给操作系统却很难。当碎片被清空的同时,goroutines 去访问 key 的时候,会开始分配内存空间,此时之前的内存空间并没有被完全释放,这导致内存的激增,甚至会出发 OOM 错误。
而且缓存访问的模式还受 Zipf 定律的束缚。最常访问的几个 key 仍然存在几个锁,因此产生 Goroutines 的竞争问题。这种方式不满足多核之间的扩展的需求。
3.缓存扩展问题
在多核和多 Goroutines 之间更好的扩展
单机使用,或者只有一个请求者连续请求的情况下,缓存做到资源管理。多核多goroutine就会涉及到缓存动态扩展问题,业务量上来了怎么去迁移数据保证请求的资源最大限度发挥效用,往往会用到缓存分片
在非随机密钥的情况下,很好地扩展 (eg. Zipf)
齐夫定律可以表述为