网易首页 > 网易号 > 正文 申请入驻

请收藏!golang本地缓存选型对比及原理总结

0
分享至

作者:jaydenwen,PCG创造营后后台开发工程师

golang本地缓存(cache)组件原理总结

提到本地缓存大家都不陌生,只要是个有点经验的后台开发人员,都知道缓存的作用和弊端。本篇文章我们就来简单聊聊在golang做业务开发的过程中,本地缓存的一些可选的开源方案。分析它们的特点,以及内部的实现原理。
1.本地缓存需求分析

首先来梳理一下业务开发过程中经常面临的本地缓存的一些需求。我们一般做缓存就是为了能提高系统的读写性能,缓存的命中率越高,也就意味着缓存的效果越好。其次本地缓存一般都受限于本地内存的大小,所有全量的数据一般存不下。那基于这样的场景一方面是想缓存的数据越多,则命中率理论上也会随着缓存数据的增多而提高;另外一方面是想,既然所有的数据存不下那就想办法利用有限的内存存储有限的数据。这些有限的数据需要是经常访问的,同时有一定时效性(不会频繁改变)的。基于这两个点展开,我们一般对本地缓存会要求其满 足支持过期时间、支持淘汰策略。最后再使用自动管理内存的语言例如golang等开发时,还需要考虑在加入本地缓存后引发的GC问题。

分析完我们日常本地缓存的诉求,再结合我们日常开发用到的golang语言,我们可以提炼得到golang本地缓存组件必须具备以下几个能力:

分析清楚了我们的需求,也明确了我们需要的能力。那自然优先考虑golang内置的标准库中是否存在这样的组件可以直接使用呢?
很遗憾,没有。golang中内置的可以直接用来做本地缓存的无非就是map和sync.Map。而这两者中,map是非并发安全的数据结构,在使用时需要加锁;而sync.Map虽然是线程安全的。但是需要在并发读写时加锁。此外二者均无法支持数据的过期和淘汰,同时在存储大量数据时,又会产生比较频繁的GC问题,更严重的情况下导致线上服务无法稳定运行。

既然标准库中没有我们满足上述需求的本地缓存组件,那我们就想只有两种解决方案了

  1. 业界是否有开源成熟的方案可供选择
  2. 业界无可用组件时,自己动手写一个

那首先面临的第一个问题就是方案的调研和选型,没有合适的方案时自己再来动手构建。下面我们就来给大家介绍下golang中哪些可以直接来使用的本地缓存组件吧。

2.golang本地缓存组件概览

golang中本地缓存方案可选的有如下一些:

  1. freecache
  2. bigcache
  3. fastcache
  4. offheap
  5. groupcache
  6. ristretto

下面通过笔者一段时间的调研和研究,将golang可选的开源本地缓存组件汇总为下表,方便大家在方案选型时作参考。

在上述方案中,freecache、bigcache、fastcache、ristretto、groupcache这几个大家根据实际的业务场景首选,offheap有定制需求时可考虑。

通过上表的总结,个人想再此再谈几点关于本地缓存组件的理解:
1.上述本地缓存组件中,实现零GC的方案主要就两种:
a.无GC:分配堆外内存(Mmap)
b.避免GC:map非指针优化(map[uint64]uint32)或者采用slice实现一套无指针的map
c.避免GC:数据存入[]byte slice(可考虑底层采用环形队列封装循环使用空间)

2.实现高性能的关键在于:
a.数据分片(降低锁的粒度)

上述几种缓存组件每种组件的实现都是1和2的几个分支的组合。下面我们大概给大家介绍每种组件的核心原理。

3. 主流缓存组件实现原理剖析

在本节中我们会重点分析下freecache、bigcache、fastcache、offheap这几个组件内部的实现原理。

3.1 freecache实现原理

首先分析下freecache的内部实现原理。在freecache中它通过segment来进行对数据分片,freecache内部包含256个segment,每个segment维护一把互斥锁,每一条kv数据进来后首先会根据k进行计算其hash值,然后根据hash值决定当前的这条数据落入到哪个segment中。

对于每个segment而言,它由索引、数据两部分构成。

索引:其中索引最简单的方式采用map来维护,例如map[uint64]uint32这种。而freecache并没有采用这种做法,而是通过采用slice来底层实现一套无指针的map,以此避免GC扫描。

数据:数据采用环形缓冲区来循环使用,底层采用[]byte进行封装实现。数据写入环形缓冲区后,记录写入的位置index作为索引,读取时首先读取数据header信息,然后再读取kv数据。

在freecache中数据的传递过程是:freecache->segment->(slot,ringbuffer)
下图是freecache的内部实现框架图。

总结: freecache通过利用数据分片减小锁的粒度,然后再存储时索引并没有采用内置的map来维护而是采用自建map减少指针来避免GC,同时数据存储时采用预先分配内存然后后边循环使用。通过上述两种方法保证了在堆上分配内存同时减少GC对系统性能的影响。

3.2 bigcache实现原理

bigcache和freecache类似,也是一个零GC、高性能的cache组件,但是它的实现和freecache还是有些差异,这儿有篇英文博客介绍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稍微好一点。大家可以思考下他们性能的差异可能会在哪里呢?

3.3 fastcache实现原理

本节介绍下fastcache的实现原理,根据fastcache官方文档介绍,它的灵感来自于bigcache。所以整体的思路和bigcache很类似,数据通过bucket进行分片。fastcache由512个bucket构成。每个bucket维护一把读写锁。在bucket内部数据同理是索引、数据两部分构成。索引用map[uint64]uint64存储。数据采用chunks二维的切片(二维数组)存储。不过值得注意的是fastcache有一个很大的特性是,它的内存分配是在堆外分配的,而不是在堆上分配的。堆外分配的内存。这样做也就避免了golang GC的影响。下图是fastcache内部实现框架图。

总结: fastcache一方面充分利用了分片来降低锁的粒度,另一方面在索引存储时采用了对map的优化,同时在分配内存时,直接从堆外申请内存,自己实现了分配和释放内存的逻辑。通过上述手段使得GC的影响降到了最低。fastcache唯一的缺陷是官方提供的版本没有提供针对kv数据的过期时间这个特性。所以如果需要这个特性的话,需要自己动手二次开发。整体从性能上来看是比bigcache和freecache都更优。

3.4 offheap实现原理

本节介绍下offheap的相关内容,offheap其实功能就比较简单了,就是一个基于堆外内存构建的哈希表。它通过直接调用系统调用函数来分配内存。然后在内部通过数组来实现哈希表。实现过程中当发生哈希冲突时,它是采用探测法来解决。由于是在堆外分配的内存上构建的哈希表。导致它的GC开销非常的小。下图是offheap的内部实现框架图。

总结:offheap内部由于是采用探测法解决哈希冲突的,所以当哈希冲突严重时数据删除、查询都会带来非常复杂的处理流程。而且性能也会有一些损耗。可以作为学习和研究的项目还是非常不错的。

4.总结

本文主要从日常需求出发,分析了日常业务过程中对本地缓存的需求,再调研了业界可选的一些组件并进行了对比,希望对本地缓存选型上起到一些参考和帮助。最后再对其中比较重要的几个组件如freecache、bigcache、fastcache、offheap等做了内部实现的简单介绍。上述内容只是从架构层面展开介绍,后续有时间再从源码层面做一些分析。由于篇幅限制本篇内容并未对map、sync.Map、go-cache、groupcache进行介绍。感兴趣的读者可以自行搜索资料进行阅读。如果大致理解了上述原理的童鞋也可以自己动手实践起来,造个轮子看看。

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
几乎全是假货!利润高达2400%,为何消费者还前赴后继争相购买?

几乎全是假货!利润高达2400%,为何消费者还前赴后继争相购买?

星星跌入梦里中
2026-09-26 05:47:11
开始动真格!追溯30年倒查来了,这4类人要当心!

开始动真格!追溯30年倒查来了,这4类人要当心!

细说职场
2026-10-25 12:40:29
多名院士研究发现:吃一块生姜,就等于给血管添一次堵,真的假的

多名院士研究发现:吃一块生姜,就等于给血管添一次堵,真的假的

路医生健康科普
2026-10-26 11:10:11
易建联为妻儿建的洛杉矶豪宅烧成灰,如今2000平空地估价曝光,数字让人意外,中介爆出实情

易建联为妻儿建的洛杉矶豪宅烧成灰,如今2000平空地估价曝光,数字让人意外,中介爆出实情

LULU生活家
2026-08-31 15:33:38
“这种儿子,在南方都养不起!”山东高中生一顿饭量,刷新认知

“这种儿子,在南方都养不起!”山东高中生一顿饭量,刷新认知

泽泽先生
2026-10-24 02:13:06
42天,150万人,世界第四军事强国被打回原形:这场仗把中国彻底打醒了

42天,150万人,世界第四军事强国被打回原形:这场仗把中国彻底打醒了

纪史行者
2026-10-26 05:45:09
尼克斯成为2011年的独行侠后 首个遭遇开季三连败的卫冕冠军

尼克斯成为2011年的独行侠后 首个遭遇开季三连败的卫冕冠军

北青网-北京青年报
2026-10-26 14:52:02
六轮投票没结果!欧尔班参选联合国秘书长?美媒:中美俄一致支持

六轮投票没结果!欧尔班参选联合国秘书长?美媒:中美俄一致支持

孤单是寂寞的毒
2026-10-26 13:54:43
不出意外的话,我国未来超50%的家庭用户都会选择HEV油混车

不出意外的话,我国未来超50%的家庭用户都会选择HEV油混车

浩渺青史
2026-10-24 00:50:02
惨烈,又有人倒下了

惨烈,又有人倒下了

揭幕者
2026-10-26 15:42:25
吃北京人的饭,砸北京人的碗,你太恶心了!

吃北京人的饭,砸北京人的碗,你太恶心了!

奇思妙想生活家
2026-10-26 14:46:54
炸裂!刘涛被当众摸胸!“搂腰”挣扎不脱,瞬间冷脸!对方身份曝光

炸裂!刘涛被当众摸胸!“搂腰”挣扎不脱,瞬间冷脸!对方身份曝光

手工制作阿歼
2026-10-26 14:28:51
CBA最大黑马产生:4连胜,保持不败 要冲击总冠军?

CBA最大黑马产生:4连胜,保持不败 要冲击总冠军?

体育哲人
2026-10-26 11:56:12
2020年克林顿坦言出轨原因,莱温斯基:拉开裤链后他要用雪茄助兴

2020年克林顿坦言出轨原因,莱温斯基:拉开裤链后他要用雪茄助兴

万国明信片
2026-06-28 18:07:20
上海大学宣布2027级研究生停招5个专业,包括计算机科学与技术、智能医学诊疗,背后原因很现实

上海大学宣布2027级研究生停招5个专业,包括计算机科学与技术、智能医学诊疗,背后原因很现实

凯旋学长
2026-10-26 16:30:23
27层的楼,装得下600个仆人,装不下一个母亲对儿子身体的担心

27层的楼,装得下600个仆人,装不下一个母亲对儿子身体的担心

鱼语昱雨轩
2026-10-26 03:16:38
杨议直播被问“你和郭德纲谁挣得多”,当场回怼:他挣再多也不给你一分,又不是你爹!

杨议直播被问“你和郭德纲谁挣得多”,当场回怼:他挣再多也不给你一分,又不是你爹!

可乐谈情感
2026-10-18 13:53:15
63岁穆帅再现经典:跪滑握拳庆祝!神换人造绝杀 近6次战巴萨不败

63岁穆帅再现经典:跪滑握拳庆祝!神换人造绝杀 近6次战巴萨不败

我爱英超
2026-10-26 06:39:27
同学聚会都吹自己官大,我埋头吃饭,结账时省里一把手来给我敬酒

同学聚会都吹自己官大,我埋头吃饭,结账时省里一把手来给我敬酒

千秋文化
2026-04-30 19:13:04
曼联内讧炸锅!名宿爆料:多名队友不愿和 B 费同场

曼联内讧炸锅!名宿爆料:多名队友不愿和 B 费同场

一隅非生
2026-10-26 10:20:24
2026-10-26 23:07:00
腾讯技术工程
腾讯技术工程
不止于技术
1465文章数 601关注度
往期回顾 全部

科技要闻

K3.1 Pro发布才两天,Kimi道歉补额度!

头条要闻

外媒称"中印边境发生冲突印度指责中国军队" 中方回应

头条要闻

外媒称"中印边境发生冲突印度指责中国军队" 中方回应

体育要闻

13年后重回诺坎普,穆里尼奥又滑跪了

娱乐要闻

胡歌杨幂刘诗诗袁弘陈龙结伴去埃及

财经要闻

卢锋:全球失衡背后 大国博弈与多边治理

汽车要闻

云辇-M上车 第二代海豹07让驾驶者也能爱上的家用车

态度原创

教育
时尚
房产
家居
游戏

教育要闻

10月21日雅思大作文示范写作 | 文物是否应该物归原主

秋天裤子不要总穿紧身款,还是阔腿裤更显瘦,舒适百搭又不挑人

房产要闻

海甸岛26万人,还缺一个年轻人“待得住”的地方

家居要闻

2026建博会(广州) 公装联探展交流活动

《塞尔达传说》真人电影ins账号突然被删!会跳票吗

无障碍浏览 进入关怀版