新聞中心
緩存組件默認(rèn)提供了一個(gè)高速的內(nèi)存緩存,操作效率非常高效,?CPU?性能損耗在?ns?納秒級別。

網(wǎng)站建設(shè)哪家好,找創(chuàng)新互聯(lián)!專注于網(wǎng)頁設(shè)計(jì)、網(wǎng)站建設(shè)、微信開發(fā)、微信小程序定制開發(fā)、集團(tuán)企業(yè)網(wǎng)站建設(shè)等服務(wù)項(xiàng)目。為回饋新老客戶創(chuàng)新互聯(lián)還提供了陽信免費(fèi)建站歡迎大家使用!
使用示例
基本使用
package main
import (
"fmt"
"github.com/GOgf/gf/v2/os/gcache"
"github.com/gogf/gf/v2/os/gctx"
)
func main() {
// 創(chuàng)建一個(gè)緩存對象,
// 當(dāng)然也可以便捷地直接使用gcache包方法
var (
ctx = gctx.New()
cache = gcache.New()
)
// 設(shè)置緩存,不過期
err := cache.Set(ctx, "k1", "v1", 0)
if err != nil {
panic(err)
}
// 獲取緩存值
value, err := cache.Get(ctx, "k1")
if err != nil {
panic(err)
}
fmt.Println(value)
// 獲取緩存大小
size, err := cache.Size(ctx)
if err != nil {
panic(err)
}
fmt.Println(size)
// 緩存中是否存在指定鍵名
b, err := cache.Contains(ctx, "k1")
if err != nil {
panic(err)
}
fmt.Println(b)
// 刪除并返回被刪除的鍵值
removedValue, err := cache.Remove(ctx, "k1")
if err != nil {
panic(err)
}
fmt.Println(removedValue)
// 關(guān)閉緩存對象,讓GC回收資源
if err = cache.Close(ctx); err != nil {
panic(err)
}
}執(zhí)行后,輸出結(jié)果為:
v1
1
true
v1過期控制
package main
import (
"fmt"
"github.com/gogf/gf/v2/os/gcache"
"github.com/gogf/gf/v2/os/gctx"
"time"
)
func main() {
var (
ctx = gctx.New()
)
// 當(dāng)鍵名不存在時(shí)寫入,設(shè)置過期時(shí)間1000毫秒
_, err := gcache.SetIfNotExist(ctx, "k1", "v1", time.Second)
if err != nil {
panic(err)
}
// 打印當(dāng)前的鍵名列表
keys, err := gcache.Keys(ctx)
if err != nil {
panic(err)
}
fmt.Println(keys)
// 打印當(dāng)前的鍵值列表
values, err := gcache.Values(ctx)
if err != nil {
panic(err)
}
fmt.Println(values)
// 獲取指定鍵值,如果不存在時(shí)寫入,并返回鍵值
value, err := gcache.GetOrSet(ctx, "k2", "v2", 0)
if err != nil {
panic(err)
}
fmt.Println(value)
// 打印當(dāng)前的鍵值對
data1, err := gcache.Data(ctx)
if err != nil {
panic(err)
}
fmt.Println(data1)
// 等待1秒,以便k1:v1自動過期
time.Sleep(time.Second)
// 再次打印當(dāng)前的鍵值對,發(fā)現(xiàn)k1:v1已經(jīng)過期,只剩下k2:v2
data2, err := gcache.Data(ctx)
if err != nil {
panic(err)
}
fmt.Println(data2)
}執(zhí)行后,輸出結(jié)果為:
[k1]
[v1]
v2
map[k1:v1 k2:v2]
map[k2:v2]GetOrSetFunc*
?GetOrSetFunc?獲取一個(gè)緩存值,當(dāng)緩存不存在時(shí)執(zhí)行指定的?f func() (interface{}, error)?,緩存該?f?方法的結(jié)果值,并返回該結(jié)果。
需要注意的是,?GetOrSetFunc?的緩存方法參數(shù)?f?是在緩存的鎖機(jī)制外執(zhí)行,因此在?f?內(nèi)部也可以嵌套調(diào)用?GetOrSetFunc?。但如果?f?的執(zhí)行比較耗時(shí),高并發(fā)的時(shí)候容易出現(xiàn)?f?被多次執(zhí)行的情況(緩存設(shè)置只有第一個(gè)執(zhí)行的?f?返回結(jié)果能夠設(shè)置成功,其余的被拋棄掉)。而?GetOrSetFuncLock?的緩存方法?f?是在緩存的鎖機(jī)制內(nèi)執(zhí)行,因此可以保證當(dāng)緩存項(xiàng)不存在時(shí)只會執(zhí)行一次?f?,但是緩存寫鎖的時(shí)間隨著?f?方法的執(zhí)行時(shí)間而定。
我們來看一個(gè)示例:
package main
import (
"fmt"
"github.com/gogf/gf/v2/os/gcache"
"github.com/gogf/gf/v2/os/gctx"
"time"
)
func main() {
var (
ch = make(chan struct{}, 0)
ctx = gctx.New()
key = `key`
value = `value`
)
for i := 0; i < 10; i++ {
go func(index int) {
<-ch
_, err := gcache.GetOrSetFuncLock(ctx, key, func() (interface{}, error) {
fmt.Println(index, "entered")
return value, nil
}, 0)
if err != nil {
panic(err)
}
}(i)
}
close(ch)
time.Sleep(time.Second)
}執(zhí)行后,終端輸出(帶有隨機(jī)性,但是只會輸出一條信息):
9 entered可以看到,多個(gè)?goroutine?同時(shí)調(diào)用?GetOrSetFuncLock?方法時(shí),由于該方法有并發(fā)安全控制,因此最終只有一個(gè)?goroutine?的數(shù)值生成函數(shù)執(zhí)行成功,成功之后其他?goroutine?拿到數(shù)據(jù)后則立即返回不再執(zhí)行對應(yīng)的數(shù)值生成函數(shù)。
LRU緩存淘汰控制
package main
import (
"fmt"
"github.com/gogf/gf/v2/os/gcache"
"github.com/gogf/gf/v2/os/gctx"
"time"
)
func main() {
var (
ctx = gctx.New()
cache = gcache.New(2) // 設(shè)置LRU淘汰數(shù)量
)
// 添加10個(gè)元素,不過期
for i := 0; i < 10; i++ {
if err := cache.Set(ctx, i, i, 0); err != nil {
panic(err)
}
}
size, err := cache.Size(ctx)
if err != nil {
panic(err)
}
fmt.Println(size)
keys, err := cache.Keys(ctx)
if err != nil {
panic(err)
}
fmt.Println(keys)
// 讀取鍵名1,保證該鍵名是優(yōu)先保留
value, err := cache.Get(ctx, 1)
if err != nil {
panic(err)
}
fmt.Println(value)
// 等待一定時(shí)間后(默認(rèn)1秒檢查一次),
// 元素會被按照從舊到新的順序進(jìn)行淘汰
time.Sleep(3 * time.Second)
size, err = cache.Size(ctx)
if err != nil {
panic(err)
}
fmt.Println(size)
keys, err = cache.Keys(ctx)
if err != nil {
panic(err)
}
fmt.Println(keys)
}執(zhí)行后,輸出結(jié)果為:
10
[2 3 5 6 7 0 1 4 8 9]
1
2
[1 9]性能測試
測試環(huán)境
CPU: Intel(R) Core(TM) i5-4460 CPU @ 3.20GHz
MEM: 8GB
SYS: Ubuntu 16.04 amd64測試結(jié)果
john@john-B85M:~/Workspace/Go/GOPATH/src/github.com/gogf/gf/v2/os/gcache$ go test *.go -bench=".*" -benchmem
goos: linux
goarch: amd64
Benchmark_CacheSet-4 2000000 897 ns/op 249 B/op 4 allocs/op
Benchmark_CacheGet-4 5000000 202 ns/op 49 B/op 1 allocs/op
Benchmark_CacheRemove-4 50000000 35.7 ns/op 0 B/op 0 allocs/op
Benchmark_CacheLruSet-4 2000000 880 ns/op 399 B/op 4 allocs/op
Benchmark_CacheLruGet-4 3000000 212 ns/op 33 B/op 1 allocs/op
Benchmark_CacheLruRemove-4 50000000 35.9 ns/op 0 B/op 0 allocs/op
Benchmark_InterfaceMapWithLockSet-4 3000000 477 ns/op 73 B/op 2 allocs/op
Benchmark_InterfaceMapWithLockGet-4 10000000 149 ns/op 0 B/op 0 allocs/op
Benchmark_InterfaceMapWithLockRemove-4 50000000 39.8 ns/op 0 B/op 0 allocs/op
Benchmark_IntMapWithLockWithLockSet-4 5000000 304 ns/op 53 B/op 0 allocs/op
Benchmark_IntMapWithLockGet-4 20000000 164 ns/op 0 B/op 0 allocs/op
Benchmark_IntMapWithLockRemove-4 50000000 33.1 ns/op 0 B/op 0 allocs/op
PASS
ok command-line-arguments 47.503s 標(biāo)題名稱:創(chuàng)新互聯(lián)GoFrame教程:GoFrame緩存管理-內(nèi)存緩存
文章源于:http://fisionsoft.com.cn/article/dhojgpc.html


咨詢
建站咨詢
