美文网首页
golang sync map思考总结

golang sync map思考总结

作者: 凯文不上班 | 来源:发表于2019-03-05 21:49 被阅读0次

一、核心结构体先贴一下

type Map struct {
    mu Mutex    //互斥锁,用于锁定dirty map

    read atomic.Value //优先读map,支持原子操作,注释中有readOnly不是说read是只读,而是它的结构体。read实际上有写的操作

    dirty map[interface{}]*entry // dirty是一个当前最新的map,允许读写

    misses int // 主要记录read读取不到数据加锁读取read map以及dirty map的次数,当misses等于dirty的长度时,会将dirty复制到read
}

type readOnly struct {
    m       map[interface{}]*entry
    amended bool // true if the dirty map contains some key not in m. // key在dirty中,不在read中
}

dirty map[interface{}]*entry

type entry struct {
    // p points to the interface{} value stored for the entry.
    //
    // If p == nil, the entry has been deleted and m.dirty == nil.
    //
    // If p == expunged, the entry has been deleted, m.dirty != nil, and the entry
    // is missing from m.dirty.  // entry不存在 dirty中
    //
    // Otherwise, the entry is valid and recorded in m.read.m[key] and, if m.dirty
    // != nil, in m.dirty[key].
    //
    // An entry can be deleted by atomic replacement with nil: when m.dirty is
    // next created, it will atomically replace nil with expunged and leave
    // m.dirty[key] unset.
    //
    // An entry's associated value can be updated by atomic replacement, provided
    // p != expunged. If p == expunged, an entry's associated value can be updated
    // only after first setting m.dirty[key] = e so that lookups using the dirty
    // map find the entry.
    p unsafe.Pointer // *interface{}
}

二、思考总结

核心思想是用空间换时间,用两个map来存储数据,readdirtyread支持原子操作,可以看作是dirty 的cache,dirty是更底层的数据存储层
4种操作:读key、增加key、更新key、删除key的基本流程
读key:先到read中读取,如果有则直接返回结果,如果没有或者是被删除(有特殊value值可以判断),则到dirty加锁中读取,如果有返回结果并更新miss数
增加key:直接增加到dirty中
更新key:先到read中看看有没有,如果有直接更新key,如果没有则到dirty中更新
删除key:先到read中看看有没有,如果有则直接更新为nil,如果没有则到dirty中直接删除

read的替换:当read多次都没有命中数据,达到阈值,表示这个cache命中率太低,这时直接将整个readdirty替换掉,然后dirty又重新置为nil,下一次再添加一个新key的时候,会触发一次readdirty的复制,这样二者又保持了一致。

虽然readdirty有冗余,但这些map的value数据是通过指针指向同一个数据,所以尽管实际的value会很大,但是冗余的空间占用还是有限的。

总结,如果对map的读操作远远多于写操作(写操作包括新增和删除key),那么sync.Map是很合适,能够大大提升性能

相关文章

  • golang sync map思考总结

    一、核心结构体先贴一下 二、思考总结 核心思想是用空间换时间,用两个map来存储数据,read和dirty,rea...

  • Go sync.Map

    map并发读线程安全,并发读写线程不安全。 sync.Map 读写分离 空间换时间 Map Golang1.6之前...

  • golang中线程安全的map

    最近在项目中需要在多线程下操作map,查阅资料后发现golang得sync包中有提供一个sync.map可以作为线...

  • Golang之Map源码解析

    在Golang情景中,Map主要分为两种:sync.Map和内置Map,两者主要区别是内置Map不支持并发读写,s...

  • golang代码级调优

    golang代码级调优方法 基本优化 提前预估size, make之临时的map,slice,可采用sync.po...

  • 技术好文集合

    缓存热点key 大value问题,解决方案 golang sync.Map 如何理解互斥锁、条件锁、读写锁以及自旋锁?

  • (九)golang sync map 源码分析

    golang中的map是不支持并发操作的,golang推荐用户直接用读写锁对map进行保护,也有第三方类库使用分段...

  • Go map底层实现

    golang map源码详解Golang map 如何进行删除操作?

  • Go语言——sync.Map详解

    Go语言——sync.Map详解 sync.Map是1.9才推荐的并发安全的map,除了互斥量以外,还运用了原子操...

  • go 中的 sync.Map

    sync.map sync.Map 的使用和内置的 map 类型一样,只不过它是并发安全的。 Store:存储一对...

网友评论

      本文标题:golang sync map思考总结

      本文链接:https://www.haomeiwen.com/subject/kscauqtx.html