当 map 中的 key 和 value 都是基础类型时,GC 就不会扫到 map 里的 key 和 value最终他们采用了 map[uint64]uint32 作为 cacheShard 中的关键存储 。key 是 sharding 时得到的 uint64 hashed key,value 则只存 offset ,整体使用 FIFO 的 bytes queue,也符合按照时序淘汰的需求,非常精巧 。
经过优化,bigcache 在 2000w 条记录下 GC 的表现
go version go version go1.13 linux/arm64效果挺明显 , 但是对于低延时的服务来说 , 22ms 的 GC 时间还是很致命的 , 对象数还是尽量能控制住比较好 。
go run caches_gc_overhead_comparison.go Number of entries: 20000000GC pause for bigcache: 22.382827msGC pause for freecache: 41.264651msGC pause for map: 72.236853ms
5. 小结认真学完 bigcache 的代码 , 我们至少有以下几点收获:
- 可以通过 sharding 来降低资源竞争
- 可以用位运算来取余数做 sharding (需要是 2 的整数幂 - 1)
- 避免 map 中出现指针、使用 go 基础类型可以显著降低 GC 压力、提升性能
- bigcache 底层存储是 bytes queue,初始化时设置合理的配置项可以减少 queue 扩容的次数,提升性能
- https://github.com/allegro/bigcache
- 《allegro.tech blog - Writing a very fast cache service with millions of entries in Go》https://blog.allegro.tech/2016/03/writing-fast-cache-service-in-go.html
- 《鸟窝 - 妙到颠毫: bigcache优化技巧》https://colobu.com/2019/11/18/how-is-the-bigcache-is-fast/
- 《Stefanie Lai - Our Go Cache Library Choices》https://medium.com/codex/our-go-cache-library-choices-406f2662d6b
- 《熊喵君的博客 - Golang 高性能 LocalCache:BigCache 设计与分析》https://pandaychen.Github.io/2020/03/03/BIGCACHE-ANALYSIS/
- https://github.com/coocood/freecache
- https://github.com/glycerine/offheap 堆外内存
【手撕 Golang 高性能内存缓存库 bigcache!】
推荐阅读
- 离婚7年!王子豪亲手撕掉了自己母亲马蓉的“遮羞布”
- 手撕鬼子就算了,输血管也能忍了,但古装配黑丝,是真的离谱!
- 如何使用Netty模拟一个Web服务端
- 玩手机就算了,手撕鬼子也忍了,但古装配黑丝,真的别太离谱啊!
- 手撕鬼子就算了,玩手机也忍了,但古装配黑丝,是真的离谱啊!
- Golang 中的 IO 包详解:常用的可导出函数详解
- 清华发布SmartMoE:一键实现高性能MoE稀疏大模型分布式训练
- Golang中降本增效的常规实践
- “京圈太子妃”白百何:一夜狂赚8000万,手撕杨颖炮轰王珞丹等人
- 正宗手撕鸡是蒸的还是煮的 正宗手撕鸡是蒸的还是煮的好吃