Go 服务开发高手课
15
15
1.0x
00:00/00:00
登录|注册

08|并发map:百万数据本地缓存,如何降延时减毛刺?

你好,我是徐逸。
在上节课的内容中,我们一起学习了锁和无锁编程技术,还使用分段锁和 map 类型,实现了一个缓存结构。不过,值得留意的是,其实 Go 语言的 sync 包已经提供了一种并发安全的 Map 类型。
今天,我就以大规模数据缓存的数据结构设计要点为例,带你掌握 sync.Map 类型以及针对 map 的 GC 优化技巧。
假如我们现在需要实现一个 key-value 类型的本地缓存,且缓存的 key 特别多,达到百万甚至千万级别,那么我们该怎么设计,才能在并发环境下高性能、安全地访问这个缓存呢?
针对大规模数据缓存的场景,我们在数据结构设计上要考虑的技术点有两个。
如何实现并发安全的 map 类型。
如何减少甚至避免因大规模数据缓存导致的 GC 开销。

并发 map 选择

实际上,大规模且有读写操作的数据缓存,咱们可以考虑的 map 类型有两种,一个是分段锁实现的 map 类型,另一个是 sync 包提供的 Map 类型。
那么我们到底该选择哪个呢?
在选型之前,我们需要先掌握 sync.Map 类型的基础知识和原理。
sync.Map 是 Go 语言 sync 包中提供的一个内置的并发安全的 map 类型。它在设计上考虑了高并发场景,尽量避免加锁操作从而提升读写性能。
sync.Map 该如何使用呢?下面我给了一段简单的代码,这段代码使用了 sync.Map 提供的 Store、Load 和 Delete 方法,分别用于写、读和删除操作。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
  • 解释
  • 总结

1. sync.Map是Go语言中提供的内置并发安全的map类型,适用于读多写少的场景,但在大规模数据缓存时可能存在读性能退化和写入性能开销的问题。 2. 在大规模数据缓存时,为了避免GC开销,可以将map中的key-value类型设计成非指针类型且大小不超过128字节,从而避免GC扫描。 3. 在缓存大规模数据时,可以使用成熟的开源库来实现,如bigcache,它利用了map的key-value特性来避免GC扫描,但可能会引起其他开销。 4. 在大规模数据缓存时,GC耗时会随数据规模增加而增加,因为GC在做对象扫描标记时需要扫描标记map里面的全量key-value对象,数据越多,需要扫描的对象越多,GC时间也就越长。 5. 在大规模数据缓存时,key-value的大小不能超过128字节,否则会导致GC性能开销变大,因为超过128字节的key-value会退化成指针,导致被GC扫描。 6. sync.Map的底层数据结构是read和dirty两个map结构,其中read存储了部分写入Map的内容,用来加速读操作,而dirty存储了全量内容,需要加锁才能读写数据。 7. sync.Map的使用场景相对苛刻,占用内存较高,更适用于读多写少的场景,且在大规模数据缓存时可能存在读性能退化和写入性能开销的问题。 8. 在大规模数据缓存时,应该选择分段锁实现的map而不是sync.Map类型来缓存数据,因为很难准确地预估读写比例,且读写比例会随着业务的发展变化,同时两个map的内存和拷贝开销也是不得不考虑的稳定性风险点。 9. 在缓存大规模数据时,为了避免GC开销,可以将map中的key-value类型设计成非指针类型且大小不超过128字节,从而避免GC扫描。 10. 在大规模数据缓存时,GC耗时会随数据规模增加而增加,因为GC在做对象扫描标记时需要扫描标记map里面的全量key-value对象,数据越多,需要扫描的对象越多,GC时间也就越长。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《Go 服务开发高手课》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(1)

  • 最新
  • 精选
  • 快叫我小白
    runtime.GC 这个函数为何在函数内外都调用一次呀?而且测试函数似乎没产生需要回收的临时结构体,我们调用GC函数仅仅是为了观察垃圾回收的扫描时间吗?
    2024-12-25归属地:上海
收起评论
显示
设置
留言
1
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部
文章页面操作
MAC
windows
作用
esc
esc
退出沉浸式阅读
shift + f
f11
进入/退出沉浸式
command + ⬆️
home
滚动到页面顶部
command + ⬇️
end
滚动到页面底部
⬅️ (仅针对订阅)
⬅️ (仅针对订阅)
上一篇
➡️ (仅针对订阅)
➡️ (仅针对订阅)
下一篇
command + j
page up
向下滚动一屏
command + k
page down
向上滚动一屏
p
p
音频播放/暂停
j
j
向下滚动一点
k
k
向上滚动一点
空格
空格
向下滚动一屏
播放器操作
MAC
windows
作用
esc
esc
退出全屏
⬅️
⬅️
快退
➡️
➡️
快进
空格
空格
视频播放/暂停(视频全屏时生效)