這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
1.go開源groupcache項目——groupcache介紹
代碼下載地址如下:
https://github.com/golang/groupcache
目標是在很多情境下替換memcached。
1 memcached
Memcached 是一個高效能的分布式記憶體對象緩衝系統,用於動態Web應用以減輕資料庫負載。它通過在記憶體中快取資料和對象來減少讀取資料庫的次數,從而提高動態、資料庫驅動網站的速度。Memcached基於一個儲存鍵/值對的hashmap。其守護進程(daemon )是用C寫的,但是用戶端可以用任何語言來編寫,並通過memcached協議與守護進程通訊。
2 GROUPCACHE簡單介紹
groupcache 是使用 Go 語言編寫的緩衝及緩衝過濾庫,作為 memcached 許多情境下的替代版本。
2.1 與memcached差異
首先,groupcache 與 memcached 的相似之處:通過 key 分區,並且通過 key 來查詢響應的 peer。
其次,groupcache 與 memcached 的不同之處:
1. 不需要對伺服器進行單獨的設定,這將大幅度減少部署和配置的工作量。groupcache 既是用戶端庫也是伺服器庫,並串連到自己的 peer 上。
2. 具有緩衝過濾機制。眾所周知,在 memcached 出現“Sorry,cache miss(緩衝丟失)”時,經常會因為不受控制使用者數量的請求而導致資料庫(或者其它組件)產生“驚群效應(thundering herd)”;groupcache 會協調緩衝填充,只會將重複調用中的一個放於緩衝,而處理結果將發送給所有相同的調用者。
3. 不支援多個版本的值。如果“foo”鍵對應的值是“bar”,那麼鍵“foo”的值永遠都是“bar”。這裡既沒有緩衝的有效期間,也沒有明確的緩衝回收機制,因此同樣也沒有CAS 或者 Increment/Decrement。
4. 基於上一點的改變,groupcache 就具備了自動備份“超熱”項進行多重處理,這就避免了 memcached 中對某些索引值過量訪問而造成所在機器 CPU 或者 NIC 過載。
跟memcached 差異最大的地方在於「沒有更改與刪除的功能」,一旦寫進去後就不會變動。在放棄update/delete 的特性後,換來的是:
l Cluster 的能力。
l 處理熱點的能力。
以往在memcached server 之間是沒有交集的,在groupcache 則是cluster 起來。另外以前在memcached 會因為同時存取同一個key 而造成single CPU overloading 的問題,在groupcache 則透過auto-mirror 機制解決。
3 測試
需要下載:go getgithub.com/golang/protobuf/proto
3.1 代碼
packagemain
import(
"fmt"
"log"
"net/http"
"os"
"strings"
groupcache"github.com/golang/groupcache"
)
funcmain(){
//Usage:./test_groupcacheport
me:=":"+os.Args[1]
peers:=groupcache.NewHTTPPool("http://localhost"+me)
peers.Set("http://localhost:8081","http://localhost:8082","http://localhost:8083")
helloworld:=groupcache.NewGroup("helloworld",1024*1024*1024*16,groupcache.GetterFunc(
func(ctxgroupcache.Context,keystring,destgroupcache.Sink)error{
log.Println(me)
dest.SetString(me)
returnnil
}))
fmt.Println("GroupName:",helloworld.Name())
http.HandleFunc("/xbox/",func(whttp.ResponseWriter,r*http.Request){
parts:=strings.SplitN(r.URL.Path[len("/xbox/"):],"/",1)
iflen(parts)!=1{
http.Error(w,"BadRequest",http.StatusBadRequest)
return
}
vardata[]byte
helloworld.Get(nil,parts[0],groupcache.AllocatingByteSliceSink(&data))
w.Write(data)
log.Println("Gets:",helloworld.Stats.Gets.String())
log.Println("Load:",helloworld.Stats.Loads.String())
log.Println("LocalLoad:",helloworld.Stats.LocalLoads.String())
log.Println("PeerError:",helloworld.Stats.PeerErrors.String())
log.Println("PeerLoad:",helloworld.Stats.PeerLoads.String())
})
http.ListenAndServe(me,nil)
}
3.2 執行如下
需要加入參數
./test.exe 1989
輸入一個連接埠號碼啟動運行。