2016-04-16 89 views
2

內存鍵值存儲效率,我想知道是否有golang任何包,將有到期,高效如何實現在golang

我查了幾個,下面是them之一,但從實施透視它鎖定整個緩存寫入一個條目(檢查this)這是不需要的權利?

是否可以鎖定一個條目而不是鎖定整個緩存?

+1

不要自吹自擂,但我寫了[cmap](https://github.com/OneOfOne/cmap)來解決這個問題。 – OneOfOne

+0

實現的分解方式看起來不錯。但我想要的密鑰也有失效,這在cmap中是不存在的 – Raghu

回答

1

從您在問題掛鉤同一回購,還有分片策略的實現,應爲您提供每個分區的鎖,相較於整個鎖緩存。例如,如果您決定使用4個緩存進行分區,則可以計算該密鑰的某個散列的模數,並將該模數存儲在該索引的緩存中。細化這種相同的方法,理論上可以使用子分區分片,通過二叉樹分解密鑰,爲您提供所需的緩存(和鎖定)粒度。

+0

好趕上!我沒有看到分片實現,但它只是在實驗階段:( – Raghu

+0

那麼,只是分叉它,出口符號,使用它,修復它,並提交公關:) – Laurent

0

要鎖定一個條目並不容易,但您想要更高效,Go中的一個好習慣是使用通道與順序流程進行通信。這樣,就沒有共享變量和鎖。

的一個簡單的例子:

type request struct { 
    reqtype string 
    key  string 
    val  interface{} 
    response chan<- result 
} 

type result struct { 
    value interface{} 
    err error 
} 


type Cache struct{ requests chan request } 

func New() *Cache { 
    cache := &Cache{requests: make(chan request)} 
    go cache.server() 
    return cache 
} 

func (c *Cache) Get(key string) (interface{}, error) { 
    response := make(chan result) 
    c.requests <- request{key, response} 
    res := <-response 
    return res.value, res.err 
} 

func (c *Cache) Set(key, val string) { 
    c.requests <- request{"SET", key, val, response} 
} 

func (c *Cache) server() { 
    cache := make(map[string]interface{}) 
    for req := range memo.requests { 
     switch req.reqtype { 
      case "SET": 
       cache[req.key] = req.val 
      case "GET": 
       e := cache[req.key] 
       if e == nil { 
        req.response <- result{e, errors.New("not exist")} 
       } else { 
        req.response <- result{e, nil} 
       } 
     } 
    } 
} 
+1

雖然這可行,但它比使用「sync.RWMutex」更慢 – OneOfOne

+0

我對頻道的體驗是,除非你有一些體面的網絡開銷水平的異步任務(或本地計算),與內存鎖相比,它們的使用率不夠高性能。所以這又回到了互斥體(以及在其實現之下的自旋鎖)。YMMV。我建議的一個建議是始終將互斥體定義放在它在結構中鎖定的字段的上方。 – Laurent