欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Golang實現(xiàn)多存儲驅(qū)動設計SDK案例

 更新時間:2022年09月08日 11:27:14   作者:7small7  
這篇文章主要介紹了Golang實現(xiàn)多存儲驅(qū)動設計SDK案例,Gocache是一個基于Go語言編寫的多存儲驅(qū)動的緩存擴展組件,更多具體內(nèi)容感興趣的小伙伴可以參考一下

前言:

Gocache是一個基于Go語言編寫的多存儲驅(qū)動的緩存擴展組件。它為您帶來了許多緩存數(shù)據(jù)的功能。

支持功能

多個緩存驅(qū)動存儲:支持內(nèi)存、redis或您自定義存儲驅(qū)動。

支持如下功能:

  • 鏈式緩存:使用具有優(yōu)先級順序的多個緩存(例如,內(nèi)存然后回退到redis共享緩存)。
  • 可加載緩存:允許您調(diào)用回調(diào)函數(shù)將數(shù)據(jù)放回緩存中。
  • 指標緩存,可讓您存儲有關緩存使用情況的指標(命中、未命中、設置成功、設置錯誤……)。
  • 自動編組/解組緩存值作為結(jié)構(gòu)的編組器。
  • 在存儲中定義默認值并在設置數(shù)據(jù)時覆蓋它們。
  • 通過過期時間和/或使用標簽緩存失效。
  • 泛型的使用。

默認情況下,Gocache支持如下幾種緩存驅(qū)動:

  • 內(nèi)存 (bigcache) (allegro/bigcache)。
  • 內(nèi)存 (ristretto) (dgraph-io/ristretto)。
  • 內(nèi)存 (go-cache) (patrickmn/go-cache)。
  • 內(nèi)存緩存(bradfitz/memcache)。
  • Redis (go-redis/redis)。
  • 空閑緩存(coocood/freecache)。
  • Pegasus ( apache/incubator-pegasus )基準測試。

開發(fā)緣由

在作者的官網(wǎng)博客中提到這樣的幾句話:

當我開始在 GraphQL Go 項目上實現(xiàn)緩存時,它已經(jīng)有一個內(nèi)存緩存,它使用了一個具有簡單 API 的小庫,但也使用了另一個內(nèi)存緩存庫來使用具有不同庫和 API 的批處理模式加載數(shù)據(jù),做同樣的事情:緩存項目。后來,我們還有一個需求:除了這個內(nèi)存緩存之外,我們還想使用 Redis 添加一層分布式緩存,主要是為了避免我們的新 Kubernetes pod 在將新版本的應用程序投入生產(chǎn)時出現(xiàn)空緩存。

因此,作者想到是時候擁有一個統(tǒng)一的API來管理多個緩存存儲:內(nèi)存、redis、memcache 或任何你想要的。

如何使用

安裝

要開始使用最新版本的 go-cache,您可以使用以下命令:

go get github.com/eko/gocache/v3

為避免嘗試導入庫時出現(xiàn)任何錯誤,請使用以下導入語句:

import (
	"github.com/eko/gocache/v3/cache"
	"github.com/eko/gocache/v3/store"
)

如果您遇到任何錯誤,請務必運行g(shù)o mod tidy以清理您的 go.mod 文件。

存儲適配器

首先,當您要緩存項目時,您必須選擇要緩存項目的位置:在內(nèi)存中?在共享的 redis 或 memcache 中?或者可能在另一個存儲中。

目前,Gocache 實現(xiàn)了以下存儲:

  • BigCache:內(nèi)存中的存儲。
  • Ristretto : DGraph 提供的另一個內(nèi)存存儲。
  • Memcache:基于 bradfitz/gomemcache 客戶端庫的 memcache 存儲。
  • Redis:基于 go-redis/redis 客戶端庫的 redis 存儲。

所有這些商店都實現(xiàn)了一個非常簡單的 API,它遵循以下接口:

type StoreInterface interface {
	Get(key interface{}) (interface{}, error)
	Set(key interface{}, value interface{}, options *Options) error
	Delete(key interface{}) error
	Invalidate(options InvalidateOptions) error
	Clear() error
	GetType() string
}

此接口代表您可以在商店中執(zhí)行的所有操作,并且每個操作都調(diào)用客戶端庫中的必要方法。所有這些存儲都有不同的配置,具體取決于您要使用的客戶端庫,

例如,初始化 Memcache 存儲:

store := store.NewMemcache(
	memcache.New("10.0.0.1:11211", "10.0.0.2:11211", "10.0.0.3:11212"),
	&store.Options{
		Expiration: 10*time.Second,
	},
)

然后,必須將初始化的存儲傳遞給緩存對象構(gòu)造函數(shù)。

緩存適配器

一個緩存接口來統(tǒng)治它們。

緩存接口與存儲接口完全相同,因為基本上,緩存將對存儲執(zhí)行操作:

type CacheInterface interface {
	Get(key interface{}) (interface{}, error)
	Set(key, object interface{}, options *store.Options) error
	Delete(key interface{}) error
	Invalidate(options store.InvalidateOptions) error
	Clear() error
	GetType() string
}

使用這個界面,我可以對緩存項執(zhí)行所有必要的操作:設置、獲取、刪除、無效數(shù)據(jù)、清除所有緩存和另一個方法 (GetType),它可以讓我知道當前緩存項是什么,很有用在某些情況下。

從這個接口開始,實現(xiàn)的緩存類型如下:

  • Cache:允許操作來自給定存儲的數(shù)據(jù)的基本緩存。
  • Chain:一個特殊的緩存適配器,允許鏈接多個緩存(可能是因為你有一個內(nèi)存緩存,一個redis緩存等......)。
  • Loadable: 一個特殊的緩存適配器,允許指定一種回調(diào)函數(shù),如果過期或失效,自動將數(shù)據(jù)重新加載到緩存中。
  • Metric:一個特殊的緩存適配器,允許存儲有關緩存數(shù)據(jù)的指標:設置、獲取、失效、成功與否的項目數(shù)。 當所有這些緩存都實現(xiàn)相同的接口并且可以相互包裝時,美妙之處就出現(xiàn)了:一個指標緩存可以采用一個可加載的緩存,該緩存可以采用一個可以采用多個緩存的鏈式緩存。

下面是一個簡單的 Memcache 示例:

memcacheStore := store.NewMemcache(
	memcache.New("10.0.0.1:11211", "10.0.0.2:11211", "10.0.0.3:11212"),
	&store.Options{
		Expiration: 10*time.Second,
	},
)
cacheManager := cache.New(memcacheStore)
err := cacheManager.Set("my-key", []byte("my-value"), &cache.Options{
	Expiration: 15*time.Second, // Override default value of 10 seconds defined in the store
})
if err != nil {
    panic(err)
}
value := cacheManager.Get("my-key")
cacheManager.Delete("my-key")
cacheManager.Clear() 
// Clears the entire cache, in case you want to flush all cache

現(xiàn)在,假設您想要一個鏈式緩存,其中包含一個內(nèi)存 Ristretto 存儲和一個分布式 Redis 存儲作為后備,

并帶有一個 marshaller 和指標作為結(jié)果:

// Initialize Ristretto cache and Redis client
ristrettoCache, err := ristretto.NewCache(&ristretto.Config{NumCounters: 1000, MaxCost: 100, BufferItems: 64})
if err != nil {
    panic(err)
}
redisClient := redis.NewClient(&redis.Options{Addr: "127.0.0.1:6379"})

// Initialize stores
ristrettoStore := store.NewRistretto(ristrettoCache, nil)
redisStore := store.NewRedis(redisClient, &cache.Options{Expiration: 5*time.Second})

// Initialize Prometheus metrics
promMetrics := metrics.NewPrometheus("my-amazing-app")
// Initialize chained cache
cacheManager := cache.NewMetric(promMetrics, cache.NewChain(
    cache.New(ristrettoStore),
    cache.New(redisStore),
))
// Initializes a marshaler
marshal := marshaler.New(cacheManager)

key := BookQuery{Slug: "my-test-amazing-book"}
value := Book{ID: 1, Name: "My test amazing book", Slug: "my-test-amazing-book"}

// Set the value in cache using given key
err = marshal.Set(key, value)
if err != nil {
    panic(err)
}
returnedValue, err := marshal.Get(key, new(Book))
if err != nil {
    panic(err)
}
// Then, do what you want with the value

我們還沒有談到 Marshaler,但它是 Gocache 的另一個功能:我們提供了一項服務來幫助您自動編組/解組您的對象從/到您的存儲。

這在使用 struct 對象作為鍵而不是內(nèi)存存儲時很有用,因為您必須將對象轉(zhuǎn)換為字節(jié)。

所有這些功能:帶有內(nèi)存和 redis 的鏈式緩存、Prometheus 指標和封送處理程序只需大約 20 行代碼即可完成。

編寫自己的緩存或存儲

如果您想實現(xiàn)自己的專有緩存,也很容易做到。

這是一個簡單的示例,以防您想要記錄在緩存中完成的每個操作(這不是一個好主意,但很好,這是一個簡單的 todo 示例):

package customcache
import (
	"log"

	"github.com/eko/gocache/cache"
	"github.com/eko/gocache/store"
)
const LoggableType = "loggable"
type LoggableCache struct {
	cache cache.CacheInterface
}
func NewLoggable(cache cache.CacheInterface) *LoggableCache {
	return &LoggableCache{
		cache: cache,
	}
}

func (c *LoggableCache) Get(key interface{}) (interface{}, error) {
	log.Print("Get some data...")
	return c.cache.Get(key)
}

func (c *LoggableCache) Set(key, object interface{}, options *store.Options) error {
	log.Print("Set some data...")
	return c.cache.Set(key, object, options)
}
func (c *LoggableCache) Delete(key interface{}) error {
	log.Print("Delete some data...")
	return c.cache.Delete(key)
}
func (c *LoggableCache) Invalidate(options store.InvalidateOptions) error {
	log.Print("Invalidate some data...")
	return c.cache.Invalidate(options)
}
func (c *LoggableCache) Clear() error {
	log.Print("Clear some data...")
	return c.cache.Clear()
}
func (c *LoggableCache) GetType() string {
	return LoggableType
}

同樣,您也可以實現(xiàn)自定義存儲。如果您認為其他人可以使您的緩存或存儲實現(xiàn)受益,請不要猶豫,打開拉取請求并直接為項目做出貢獻,以便我們一起討論您的想法并帶來更強大的緩存庫。

壓縮

生成模擬測試數(shù)據(jù):

go get github.com/golang/mock/mockgen
make mocks

測試套件可以運行:

make test # run unit test
make benchmark-store # run benchmark test

到此這篇關于Golang實現(xiàn)多存儲驅(qū)動設計SDK案例的文章就介紹到這了,更多相關Golang SDK內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • 一文帶你掌握Go語言并發(fā)模式中的Context的上下文管理

    一文帶你掌握Go語言并發(fā)模式中的Context的上下文管理

    在?Go?的日常開發(fā)中,Context?上下文對象無處不在,無論是處理網(wǎng)絡請求、數(shù)據(jù)庫操作還是調(diào)用?RPC?等場景,那你真的熟悉它的正確用法嗎,隨著本文一探究竟吧
    2023-05-05
  • 手把手帶你走進Go語言之運算符解析

    手把手帶你走進Go語言之運算符解析

    這篇文章主要介紹了手Go語言之運算符解析,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-09-09
  • GO語言映射(Map)用法分析

    GO語言映射(Map)用法分析

    這篇文章主要介紹了GO語言映射(Map)用法,以實例形式較為詳細的分析了針對映射的創(chuàng)建、填充、遍歷及修改等操作的技巧,需要的朋友可以參考下
    2014-12-12
  • Go并發(fā)控制WaitGroup的使用場景分析

    Go并發(fā)控制WaitGroup的使用場景分析

    WaitGroup,可理解為Wait-Goroutine-Group,即等待一組goroutine結(jié)束,本文通過具體場景結(jié)合實際例子給大家介紹使用WaitGroup控制的實現(xiàn)方法,感興趣的朋友跟隨小編一起看看吧
    2021-07-07
  • Go語言中Map的神奇操作小結(jié)

    Go語言中Map的神奇操作小結(jié)

    Map是一個強大而又有趣的工具,它可以幫助我們高效地存儲和操作鍵值對數(shù)據(jù),本文主要介紹了Go語言中Map的各種操作,包括增加、查找、刪除、遍歷等,具有一定的參考價值,感興趣的可以了解一下
    2023-08-08
  • Go并發(fā)編程之sync.Once使用實例詳解

    Go并發(fā)編程之sync.Once使用實例詳解

    sync.Once使用起來很簡單, 下面是一個簡單的使用案例,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2021-11-11
  • 如何在golang中使用shopspring/decimal來處理精度問題

    如何在golang中使用shopspring/decimal來處理精度問題

    本文主要介紹了如何在golang中使用shopspring/decimal來處理精度問題,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-04-04
  • golang版本升級的簡單實現(xiàn)步驟

    golang版本升級的簡單實現(xiàn)步驟

    個人感覺Go在眾多高級語言中,是在各方面都比較高效的,下面這篇文章主要給大家介紹了關于golang版本升級的簡單實現(xiàn)步驟,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2023-02-02
  • golang 如何替換掉字符串里面的換行符\n

    golang 如何替換掉字符串里面的換行符\n

    這篇文章主要介紹了golang 替換掉字符串里面的換行符\n操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-03-03
  • Go?time包AddDate使用解惑實例詳解

    Go?time包AddDate使用解惑實例詳解

    這篇文章主要為大家介紹了Go?time包AddDate使用解惑實例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-09-09

最新評論