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

请收藏!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.

相关推荐
热点推荐
美国十大领域全球领跑,差距还在拉大,正视实力才是真清醒!

美国十大领域全球领跑,差距还在拉大,正视实力才是真清醒!

保德全
2026-02-03 19:30:03
追觅今年已出资超60亿成立新公司 布局苏州、厦门等地

追觅今年已出资超60亿成立新公司 布局苏州、厦门等地

CNMO科技
2026-02-06 09:37:52
港口保卫战已爆发,后果不堪设想;连发2道檄文,中港通告巴拿马

港口保卫战已爆发,后果不堪设想;连发2道檄文,中港通告巴拿马

生活魔术专家
2026-02-06 11:10:56
黄奕再现释放女神光彩,身穿黄金修身连衣裙女人味四溢!

黄奕再现释放女神光彩,身穿黄金修身连衣裙女人味四溢!

说不尽的人心
2026-02-06 13:47:26
1967年,梁兴初厉声质问副政委:邓华你也敢动?谁给你的胆子?

1967年,梁兴初厉声质问副政委:邓华你也敢动?谁给你的胆子?

鉴史录
2026-02-05 16:28:29
洗衣液为什么卖不动?超市员工:人们越来越难骗,都买洗衣粉去了

洗衣液为什么卖不动?超市员工:人们越来越难骗,都买洗衣粉去了

文雅笔墨
2026-02-05 15:41:01
程序员高广辉猝死后续!他早逝有原因,父亲一直不赞成他的婚姻

程序员高广辉猝死后续!他早逝有原因,父亲一直不赞成他的婚姻

细品名人
2026-02-03 07:48:27
好惨烈的身高对比差距,中越边境上的一张军人合影突然火了起来

好惨烈的身高对比差距,中越边境上的一张军人合影突然火了起来

我心纵横天地间
2026-01-30 22:17:29
马斯克母亲误将深蓝认作特斯拉 深蓝汽车CEO姜海荣回应

马斯克母亲误将深蓝认作特斯拉 深蓝汽车CEO姜海荣回应

环球网资讯
2026-02-06 13:01:06
大逆转!湖人双杀76人,詹姆斯一战连创3大神迹,东契奇腿筋重伤

大逆转!湖人双杀76人,詹姆斯一战连创3大神迹,东契奇腿筋重伤

老侃侃球
2026-02-06 13:41:46
俄钾肥巨头前CEO确认身亡,遗体在塞浦路斯英军基地海滩被发现

俄钾肥巨头前CEO确认身亡,遗体在塞浦路斯英军基地海滩被发现

红星新闻
2026-02-05 18:37:26
杭州女子拒缴物业费,小区突然不让她继续停车了,“我觉得不合理,不应该捆绑在一起……”

杭州女子拒缴物业费,小区突然不让她继续停车了,“我觉得不合理,不应该捆绑在一起……”

都市快报橙柿互动
2026-02-05 21:46:48
医生:希望你的血液检查报告里,永远不要出现这几项异常

医生:希望你的血液检查报告里,永远不要出现这几项异常

全球军事记
2025-11-25 13:59:34
纪实:四川18岁校花被51岁和尚藏禅房3个月,被解救时已神志不清

纪实:四川18岁校花被51岁和尚藏禅房3个月,被解救时已神志不清

谈史论天地
2026-02-05 12:38:12
狂秀操作!3笔交易送走半支队,整整省了1亿啊,冠军和薪资全都要

狂秀操作!3笔交易送走半支队,整整省了1亿啊,冠军和薪资全都要

球童无忌
2026-02-05 11:41:16
萝莉岛文件再公开!背后更可怕的,是每年50万“消失的孩子”

萝莉岛文件再公开!背后更可怕的,是每年50万“消失的孩子”

秋枫凋零
2026-02-04 21:04:24
张本智和不敌黄镇廷,被球迷喊哭了,赛后,黄镇廷发言的情商真高

张本智和不敌黄镇廷,被球迷喊哭了,赛后,黄镇廷发言的情商真高

观察鉴娱
2026-02-06 09:35:47
著名数学家、越南首位菲尔兹奖得主吴宝珠将加盟香港大学

著名数学家、越南首位菲尔兹奖得主吴宝珠将加盟香港大学

澎湃新闻
2026-02-05 22:23:03
艾滋病新增130万!很多人中招很冤枉!在外“5不碰”一定要记死

艾滋病新增130万!很多人中招很冤枉!在外“5不碰”一定要记死

今朝牛马
2025-12-31 19:31:04
章泽天父母离婚内幕曝光:和母亲一起生活,同父异母妹妹被扒

章泽天父母离婚内幕曝光:和母亲一起生活,同父异母妹妹被扒

没有偏旁的常庆
2026-02-06 06:55:05
2026-02-06 14:27:00
腾讯技术工程
腾讯技术工程
不止于技术
1363文章数 600关注度
往期回顾 全部

科技要闻

微信封禁元宝红包后,又把阿里千问封了

头条要闻

女子付4980元买500双鞋仅收90余双 涉事商家销号失联

头条要闻

女子付4980元买500双鞋仅收90余双 涉事商家销号失联

体育要闻

西甲射手榜第2,身价不到姆巴佩1/40

娱乐要闻

微博之夜红毯好精彩,堪比婚礼现场

财经要闻

很意外,美债危机要化解了

汽车要闻

标配华为乾崑解决方案 华境S完成六座满载冬测

态度原创

游戏
健康
教育
家居
公开课

快上车!腾讯新作《粒粒的小人国》首测即将开启,手慢无!

转头就晕的耳石症,能开车上班吗?

教育要闻

换成你如何回答孩子?是像梅宇一样继续误导孩子,还是有别的方式!

家居要闻

现代轻奢 温馨治愈系

公开课

李玫瑾:为什么性格比能力更重要?

无障碍浏览 进入关怀版