提到本地缓存大家都不陌生,只要是个有点经验的后台开发人员,都知道缓存的作用和弊端。本篇文章我们就来简单聊聊在 golang 做业务开发的过程中,本地缓存的一些可选的开源方案。分析它们的特点,以及内部的实现原理。
英文博客介绍 bigcache 设计原理的,内容稍长感兴趣的可以阅读下,下面我们介绍一下 bigcache 的实现原理。
bigcache 同样是采用分片的方式构成,一个 bigcache 对象包含 2^n 个 cacheShard 对象,默认是 1024 个。每个 cacheShard 对象维护着一把 sync.RWLock 锁(读写锁)。所有的数据会分散到不同的 cacheShard 中。
每个 cacheShard 同样由索引和数据构成。索引采用 map[uint64]uint32 来存储,数据采用 entry([]byte)环形队列存储。索引中存储的是该条数据在 entryBuffer 写入的位置 pos。每条 kv 数据按照 TLV 的格式写入队列。
不过值得注意的是,和 bigcache 和 freecache 不同的一点在于它的环形队列可以自动扩容。同时 bigcache 中数据的过期是通过全局的时间窗口维护的,每个单独的 kv 无法设置不同的过期时间。
下面是 bigcache 的内容实现原理框架图。
总结:bigcache 思路和 freecache 大体相同,只不过在索引存储时更为巧妙,直接采用内置的 map 结构加上基础数据类型来实现。同时底层存储数据的队列也可以根据空间大小来决定是否扩容。唯一的缺陷是无法针对每个 key 进行设置不同的过期时间。这个个人认为如果想用 bigcache 同时想要这个特性,可以进行二次开发一下。
通过性能测试数据来看,bigcache 性能要比 freecache 稍微好一点。大家可以思考下他们性能的差异可能会在哪里呢?