首页 > 试题广场 >

在读多写少的场景中,需要一个 map 支持并发访问且在高并发

[单选题]
在读多写少的场景中,需要一个 map 支持并发访问且在高并发读时尾延迟更稳定。下列哪种方案最契合该需求?
  • 使用内置 map 并用一个全局的 sync.RWMutex 保护读写访问。
  • 使用 sync.Map,它针对读多写少的模式进行了优化,通常能获得更稳定的读延迟。
  • 使用单个 goroutine 通过一个 channel 串行化所有 map 操作,以避免任何加锁。
  • 为 map 中的每个键维护一个独立的互斥锁,以最大化并发度。
尾延迟:指系统在高并发压力下,处理最慢的那小部分请求的耗时,反应的是用户体验的下限,而不是平均表现。通常发生在高并发请求的尾部。例如,一个接口100次访问中,99次在10毫秒内返回,但有1次花了500毫秒,这500毫秒就是高尾延迟。导致尾延迟的原因很多,如系统资源竞争、垃圾回收(GC)停顿、锁竞争等。sync.Map通过避免锁竞争,直接优化了高并发读场景下的尾延迟。

sync.Map性能优势的关键在于其 “读写分离” 的设计思想 。
它内部维护了两个映射(map):
 1. read映射:这是一个只读的数据结构。一旦创建,其中的键值对就不会被修改(值指针的更新是原子的),只可能被替换。因此,所有协程访问它都不需要加锁,速度极快。 
 2. dirty映射:这个映射负责处理所有的写入操作(新增、更新)以及那些在 read中找不到的读取操作。访问它需要持有一把互斥锁(mutex)  。   当你调用 Load(读)方法时,sync.Map的流程如下
  •  首先无锁地检查 read映射。如果命中,直接返回结果。这是绝大多数读操作的情况。  
  • 2如果未命中,且判断可能有新数据写入(dirty映射中存在 read没有的数据),它才会加锁,然后再次检查 read映射(双检查机制),最后再去查询 dirty映射。
发表于 今天 09:19:35 回复(0)