ryanking8215 / go-cache

Multi-backends cache written by golang. Supports in-memory, redis string, redis hash, dummy store. Supports TTL and context.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Go Cache

Multi-backends Cache written by Golang.

Features:

multi backends

  • local - store in local map with ttl support.
  • simple - using sync.Map for reading performence usage, without ttl support.
  • lru - local cache with lru evicted policy.
  • redis string - store in redis string type with ttl support.
  • redis hash - store in redis hash type with ttl support.
  • dummy - dummy cache for placeholder.

multi codec

  • json - json encode/decode

functional options pattern.

provides options like TTL, context support and so on.

Usage

interface

Interface "Cache" defines the common cache methods.

type Cache interface {
	Get(key interface{}, options ...Option) (interface{}, error)
	Set(key, value interface{}, options ...Option) error
	MGet(keys []interface{}, options ...Option) (map[interface{}]interface{}, error)
	MSet(keyValues map[interface{}]interface{}, options ...Option) error
	Exists(key interface{}, options ...Option) (bool, error)
	Delete(key interface{}, options ...Option) error
	Clear(options ...Option) error
	Codec() Codec
}

options

// no options
cache.Set("key", "value")
// ttl 
cache.Set("key", "value", cache.WithTTL(time.Minute))
// context, useful for redis cache
cache.Set("key", "value", cache.WithContext(context.WithTimeout(ctx, 2*time.Second)))

Feel free to combine them:

cache.Set("key", "value", cache.WithTTL(time.Minute), cache.WithContext(context.WithTimeout(ctx, 2*time.Second)))

local cache

import (
    "time"

    "github.com/ryanking8215/go-cache"
    "github.com/ryanking8215/go-cache/local"
)

func main() {
    c := local.NewCache()
    n := 10
    for i:=0; i<n; i++ {
        c.Set(i, fmt.Sprintf("%d", i))
    }
    c.Set("with ttl", "5 minute", cache.WithTTL(5*time.Minute))
}

local lru cache

import (
    "time"

    "github.com/ryanking8215/go-cache"
    "github.com/ryanking8215/go-cache/local"
)

func main() {
    n := 10
    c := local.NewLRUCache(10)
    for i:=0; i<n; i++ {
        c.Set(i, fmt.Sprintf("%d", i))
    }
    c.Set("with ttl", "5 minute", cache.WithTTL(5*time.Minute))
}

LRU cache has its default TTL for all keys when initialized, and also supports custom ttl for individual key.

redis string cache

import (
    "time"

	"github.com/go-redis/redis/v7"
	"github.com/ryanking8215/go-cache"
	"github.com/ryanking8215/go-cache/codec/json"
    rediscache "github.com/ryanking8215/go-cache/redis"
)

func main() {
    rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379", // use default Addr
		Password: "",               // no password set
		DB:       0,                // use default DB
	})
	c := rediscache.NewStringCache(rdb, json.NewCodec(), func(key string) string{
        return "test_"+key // feel free to generate your own key layout
    })
    n := 10
    c := rediscache.NewStringCache(10)
    for i:=0; i<n; i++ {
        c.Set(i, fmt.Sprintf("%d", i))
    }
    c.Set("with ttl", "5 minute", cache.WithTTL(5*time.Minute))

    // get value with codec
    v, err := c.Get(0)
    if err!=nil {
        return
    }
    var val string
    if err:=c.Codec().DecodeTo(v, &val); err!=nil {
        return
    }
}
Be aware that redis string cache doesn't support Clear() method!

redis hash cache

import (
    "time"

	"github.com/go-redis/redis/v7"
	"github.com/ryanking8215/go-cache"
	"github.com/ryanking8215/go-cache/codec/json"
    rediscache "github.com/ryanking8215/go-cache/redis"
)

func main() {
    rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379", // use default Addr
		Password: "",               // no password set
		DB:       0,                // use default DB
	})
	c := rediscache.NewHashCache(rdb, json.NewCodec(), "hash_test")
    n := 10
    for i:=0; i<n; i++ {
        c.Set(i, fmt.Sprintf("%d", i))
    }
    c.Set("with ttl", "5 minute", cache.WithTTL(5*time.Minute))
}

dummy cache

import (
    "time"

    "github.com/ryanking8215/go-cache"
)

func main() {
    c := cache.NewDummyCache()
    n := 10
    for i:=0; i<n; i++ {
        c.Set(i, fmt.Sprintf("%d", i))
    }
}

TODO

  • Local cache should have a better GC(release expired keys) implement.
  • Redis hash cache has concurrent problem. (implemented by pipeline now, lua script may work I think, or any other good advice).
  • Gob codec support.
  • More tests.

About

Multi-backends cache written by golang. Supports in-memory, redis string, redis hash, dummy store. Supports TTL and context.

License:MIT License


Languages

Language:Go 100.0%