Go的sync.Map为何在多读少写场景下表现更优?
- 内容介绍
- 文章标签
- 相关推荐
本文共计1198个文字,预计阅读时间需要5分钟。
相关专题
sync.Map 的 read map 为什么能无锁读取
因为 read 字段是 atomic.value,底层存储的是一个只读的 readonly 结构(含 map[interface{}]*entry),所有 load 操作都直接原子读取这个结构,不涉及任何锁。只要 key 在 read.m 中存在且未被标记为 expunged,整个读过程就是纯内存访问,没有竞争、没有调度开销。
常见错误现象:Load 耗时突然升高、pprof 显示 sync.(*Mutex).Lock 占比上升——大概率是 read 频繁 miss,被迫 fallback 到加锁读 dirty。
使用场景:HTTP handler 中查用户 session(key 是 requestID)、配置中心热加载后的只读查询。
性能影响:90%+ 的 Load 走这条路径,延迟稳定在纳秒级;但一旦 miss,就得锁住 mu 去查 dirty,延迟跳到微秒甚至毫秒级。
Store 新 key 为什么会触发锁和晋升开销
当写入一个 read 中完全不存在的 key 时,sync.Map 必须把数据写进 dirty,而 dirty 是受 mu Mutex 保护的。
本文共计1198个文字,预计阅读时间需要5分钟。
相关专题
sync.Map 的 read map 为什么能无锁读取
因为 read 字段是 atomic.value,底层存储的是一个只读的 readonly 结构(含 map[interface{}]*entry),所有 load 操作都直接原子读取这个结构,不涉及任何锁。只要 key 在 read.m 中存在且未被标记为 expunged,整个读过程就是纯内存访问,没有竞争、没有调度开销。
常见错误现象:Load 耗时突然升高、pprof 显示 sync.(*Mutex).Lock 占比上升——大概率是 read 频繁 miss,被迫 fallback 到加锁读 dirty。
使用场景:HTTP handler 中查用户 session(key 是 requestID)、配置中心热加载后的只读查询。
性能影响:90%+ 的 Load 走这条路径,延迟稳定在纳秒级;但一旦 miss,就得锁住 mu 去查 dirty,延迟跳到微秒甚至毫秒级。
Store 新 key 为什么会触发锁和晋升开销
当写入一个 read 中完全不存在的 key 时,sync.Map 必须把数据写进 dirty,而 dirty 是受 mu Mutex 保护的。

