README ¶
Memcache Client
This is a memcache client library for the Go programming language, which uses memcache's binary protocol and supports namespacing out of the box.
Installing
To add this libraty to your project, just run:
go get github.com/kinescope/mc
Example
package main
import (
"context"
"log"
"time"
"github.com/kinescope/mc"
)
func main() {
cache, err := mc.New(&mc.Options{
Addrs: []string{"127.0.0.1:11211"},
DialTimeout: 500 * time.Millisecond,
KeyHashFunc: mc.XXKeyHashFunc, // or mc.DefaultKeyHashFunc. Hash function to use for namespaces
ConnMaxLifetime: 15 * time.Minute,
MaxIdleConnsPerAddr: 20,
})
if err != nil {
log.Fatal(err)
}
ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(time.Second))
defer cancel()
type example struct {
A string
B string
}
var value mc.Value
err = value.Marshal(example{
A: "A",
B: "B",
})
if err != nil {
log.Fatal(err)
}
err = cache.Set(ctx, &mc.Item{
Key: "cache_key",
Value: value,
}, mc.WithExpiration(1_800, 60) /*mc.WithMinUses(10),*/, mc.WithNamespace("my_namespace"))
if err != nil {
log.Fatal(err)
}
i, err := cache.Get(ctx, "cache_key")
if err != nil {
log.Fatal(err)
}
var v example
if err := i.Value.Unmarshal(&v); err != nil {
log.Fatal(err)
}
log.Println(v)
Namespacing
Let's say you have a user with some user_id like 123
. Given a user and all his related keys, you want a one-stop switch to invalidate all of their cache entries at the same time.
With namespacing you need to add a mc.WithNamespace
option when setting any user related key.
// set user name for id
var userName mc.Value
err = userName.Marshal("John")
err = cache.Set(ctx, &mc.Item{
Key: "123",
Value: userName,
}, mc.WithNamespace("user_123"))
// set user email for name
var userEmail mc.Value
err = userEmail.Marshal("example@gmail.com")
err = cache.Set(ctx, &mc.Item{
Key: "John",
Value: userEmail,
}, mc.WithNamespace("user_123"))
Then invalidating all of the keys for a user with id 123
would be as easy as:
cache.PurgeNamespace(ctx, "user_123") // both 123:John and John:example@gmail.com entries will be deleted
Namespaces are hashed by default to prevent collisions. There are two available hash functions - mc.XXKeyHashFunc
, witch uses xx-hash, and mc.DefaultKeyHashFunc
- witch doesn't hash keys at all.
For more info on namespaces see memcache wiki.
Other options
mc.WithExpiration(exp, scale uint32)
- after expiration time passes, first request for an item will get a cache miss, any other request will get a hit in a time window ofscale
seconds. See memcache wiki.mc.WithMinUses(number uint32)
- if an item under the key has been set less thannumber
of times, requesting an item will result in a cache miss. See tests for clarity.
Contributing
For contributing see CONTRIBUTING.md
Licensing
The code in this project is licensed under MIT license.
Documentation ¶
Index ¶
- Constants
- Variables
- type Client
- func (c *Client) Add(ctx context.Context, i *Item, o ...Option) error
- func (c *Client) CompareAndSwap(ctx context.Context, i *Item, o ...Option) error
- func (c *Client) Dec(ctx context.Context, key string, delta uint64) (uint64, error)
- func (c *Client) Delete(ctx context.Context, key string) error
- func (c *Client) Get(ctx context.Context, key string) (*Item, error)
- func (c *Client) GetMulti(ctx context.Context, keys ...string) (_ map[string]*Item, retErr error)
- func (c *Client) Inc(ctx context.Context, key string, delta uint64, o ...Option) (uint64, error)
- func (c *Client) PurgeNamespace(ctx context.Context, ns string) error
- func (c *Client) Set(ctx context.Context, i *Item, o ...Option) error
- type Item
- type Option
- type Options
- type Value
Constants ¶
const ( DefaultTimeout = 500 * time.Millisecond DefaultConnMaxLifetime = 30 * time.Minute DefaultMaxIdleConnsPerAddr = 10 )
const MagicValue = 0x42
Variables ¶
var ( DefaultKeyHashFunc = func(key string) []byte { return str2byte(key) } XXKeyHashFunc = func(key string) []byte { hash := xxHashPool.Get().(*xxhash.Digest) hash.Reset() hash.WriteString(key) sum := hash.Sum(nil) { xxHashPool.Put(hash) } return sum } )
var ( ErrCacheMiss = errors.New("memcache: cache miss") ErrNotStored = errors.New("memcache: item not stored") ErrNoServers = errors.New("memcache: no servers configured or available") ErrBadIncrDec = errors.New("memcache: incr or decr on non-numeric value") ErrCASConflict = errors.New("memcache: compare-and-swap conflict") ErrServerError = errors.New("memcache: server error") ErrMalformedKey = errors.New("memcache: key is too long or contains invalid characters") ErrAlreadyExists = errors.New("memcache: item already exists") ErrValueTooLarge = errors.New("memcache: value too large") ErrInvalidArguments = errors.New("memcache: invalid arguments") )
Functions ¶
This section is empty.
Types ¶
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
func (*Client) CompareAndSwap ¶
type Option ¶
type Option func(c *opts)
func WithExpiration ¶
https://github.com/memcached/memcached/wiki/ProgrammingTricks#scaling-expiration при истечении срока жизни первый зарос получает cache miss, все остальные -- hit, в течении указанного scale