Documentation
¶
Overview ¶
Package groupcache provides a data loading mechanism with caching and de-duplication that works across a set of peer processes.
Each data Get first consults its local cache, otherwise delegates to the requested key's canonical owner, which then checks its cache or finally gets the data. In the common case, many concurrent cache misses across a set of peers for the same key result in just one cache fill.
Example ¶
/*
// Keep track of peers in our cluster and add our instance to the pool `http://localhost:8080`
pool := groupcache.NewHTTPPoolOpts("http://localhost:8080", &groupcache.HTTPPoolOptions{})
// Add more peers to the cluster
//pool.Set("http://peer1:8080", "http://peer2:8080")
server := http.Server{
Addr: "localhost:8080",
Handler: pool,
}
// Start a HTTP server to listen for peer requests from the groupcache
go func() {
log.Printf("Serving....\n")
if err := server.ListenAndServe(); err != nil {
log.Fatal(err)
}
}()
defer server.Shutdown(context.Background())
*/
// Create a new group cache with a max cache size of 3MB
const purgeExpired = true
group := groupcache.NewGroupWithWorkspace(groupcache.Options{
Workspace: groupcache.DefaultWorkspace,
Name: "users",
PurgeExpired: purgeExpired,
CacheBytesLimit: 3_000_000,
Getter: groupcache.GetterFunc(
func(ctx context.Context, id string, dest groupcache.Sink, info *groupcache.Info) error {
// In a real scenario we might fetch the value from a database.
/*if user, err := fetchUserFromMongo(ctx, id); err != nil {
return err
}*/
user := User{
Id: "12345",
Name: "John Doe",
Age: 40,
IsSuper: true,
}
// Set the user in the groupcache to expire after 5 minutes
if err := dest.SetProto(&user, time.Now().Add(time.Minute*5)); err != nil {
return err
}
return nil
},
),
})
var user User
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
if err := group.Get(ctx, "12345", groupcache.ProtoSink(&user), nil); err != nil {
log.Fatal(err)
}
fmt.Printf("-- User --\n")
fmt.Printf("Id: %s\n", user.Id)
fmt.Printf("Name: %s\n", user.Name)
fmt.Printf("Age: %d\n", user.Age)
fmt.Printf("IsSuper: %t\n", user.IsSuper)
/*
// Remove the key from the groupcache
if err := group.Remove(ctx, "12345"); err != nil {
fmt.Printf("Remove Err: %s\n", err)
log.Fatal(err)
}
*/
Output: -- User -- Id: 12345 Name: John Doe Age: 40 IsSuper: true
Index ¶
- Variables
- func RegisterPeerPickerWithWorkspace(ws *Workspace, fn func() PeerPicker)
- type ByteView
- func (v ByteView) At(i int) byte
- func (v ByteView) ByteSlice() []byte
- func (v ByteView) Copy(dest []byte) int
- func (v ByteView) Equal(b2 ByteView) bool
- func (v ByteView) EqualBytes(b2 []byte) bool
- func (v ByteView) EqualString(s string) bool
- func (v ByteView) Expire() time.Time
- func (v ByteView) Len() int
- func (v ByteView) ReadAt(p []byte, off int64) (n int, err error)
- func (v ByteView) Reader() io.ReadSeeker
- func (v ByteView) Slice(from, to int) ByteView
- func (v ByteView) SliceFrom(from int) ByteView
- func (v ByteView) String() string
- func (v ByteView) WriteTo(w io.Writer) (n int64, err error)
- type CacheStats
- type CacheType
- type ErrNotFound
- type ErrRemoteCall
- type Getter
- type GetterFunc
- type Group
- func (g *Group) CacheStats(which CacheType) CacheStats
- func (g *Group) Get(ctx context.Context, key string, dest Sink, info *Info) error
- func (g *Group) GetForPeer(ctx context.Context, key string, dest Sink, info *Info) error
- func (g *Group) Name() string
- func (g *Group) Remove(ctx context.Context, key string) error
- func (g *Group) Set(ctx context.Context, key string, value []byte, expire time.Time, hotCache bool) error
- type HTTPPool
- type HTTPPoolOptions
- type Info
- type Logger
- type NoPeers
- type Options
- type PeerPicker
- type ProtoGetter
- type Sink
- type Stats
- type Workspace
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var DefaultWorkspace = NewWorkspace()
DefaultWorkspace is the default workspace, useful for tests. If your application does not need to recreate groupcache resources, you can use this default workspace as well.
var NowFunc lru.NowFunc = time.Now
NowFunc returns the current time which is used by the LRU to determine if the value has expired. This can be overridden by tests to ensure items are evicted when expired.
Functions ¶
func RegisterPeerPickerWithWorkspace ¶ added in v2.5.3
func RegisterPeerPickerWithWorkspace(ws *Workspace, fn func() PeerPicker)
RegisterPeerPickerWithWorkspace registers the peer initialization function. It is called once, when the first group is created. Either RegisterPeerPickerWithWorkspace or RegisterPerGroupPeerPickerWithWorkspace should be called exactly once, but not both.
Types ¶
type ByteView ¶
type ByteView struct {
// contains filtered or unexported fields
}
A ByteView holds an immutable view of bytes. Internally it wraps either a []byte or a string, but that detail is invisible to callers.
A ByteView is meant to be used as a value type, not a pointer (like a time.Time).
func (ByteView) EqualBytes ¶
EqualBytes returns whether the bytes in b are the same as the bytes in b2.
func (ByteView) EqualString ¶
EqualString returns whether the bytes in b are the same as the bytes in s.
func (ByteView) Reader ¶
func (v ByteView) Reader() io.ReadSeeker
Reader returns an io.ReadSeeker for the bytes in v.
type CacheStats ¶
type CacheStats struct {
Bytes int64
Items int64
Gets int64
Hits int64
Evictions int64
EvictionsNonExpiredOnMemFull int64 // number of evictions for non-expired items on mem full condition
}
CacheStats are returned by stats accessors on Group.
type ErrNotFound ¶
type ErrNotFound struct {
Msg string
}
ErrNotFound should be returned from an implementation of `GetterFunc` to indicate the requested value is not available. When remote HTTP calls are made to retrieve values from other groupcache instances, returning this error will indicate to groupcache that the value requested is not available, and it should NOT attempt to call `GetterFunc` locally.
func (*ErrNotFound) Error ¶
func (e *ErrNotFound) Error() string
func (*ErrNotFound) Is ¶
func (e *ErrNotFound) Is(target error) bool
type ErrRemoteCall ¶
type ErrRemoteCall struct {
Msg string
}
ErrRemoteCall is returned from `group.Get()` when a remote GetterFunc returns an error. When this happens `group.Get()` does not attempt to retrieve the value via our local GetterFunc.
func (*ErrRemoteCall) Error ¶
func (e *ErrRemoteCall) Error() string
func (*ErrRemoteCall) Is ¶
func (e *ErrRemoteCall) Is(target error) bool
type Getter ¶
type Getter interface {
// Get returns the value identified by key, populating dest.
//
// The returned data must be unversioned. That is, key must
// uniquely describe the loaded data, without an implicit
// current time, and without relying on cache expiration
// mechanisms.
Get(ctx context.Context, key string, dest Sink, info *Info) error
}
A Getter loads data for a key.
type GetterFunc ¶
A GetterFunc implements Getter with a function.
type Group ¶
type Group struct {
// Stats are statistics on the group.
Stats Stats
// contains filtered or unexported fields
}
A Group is a cache namespace and associated data loaded spread over a group of 1 or more machines.
func GetGroupWithWorkspace ¶ added in v2.5.3
GetGroupWithWorkspace returns the named group previously created with NewGroup, or nil if there's no such group.
func GetGroups ¶ added in v2.7.6
GetGroupWiths returns all groups previously created with NewGroup, or nil if there is no group.
func NewGroupWithWorkspace ¶ added in v2.5.3
NewGroupWithWorkspace creates a coordinated group-aware Getter from a Getter.
The returned Getter tries (but does not guarantee) to run only one Get call at once for a given key across an entire set of peer processes. Concurrent callers both in the local process and in other processes receive copies of the answer once the original Get completes.
The group name must be unique for each getter.
func (*Group) CacheStats ¶
func (g *Group) CacheStats(which CacheType) CacheStats
CacheStats returns stats about the provided cache within the group.
func (*Group) Get ¶
Get retrieves key for library caller, thus crosstalk is allowed. info holds optional user-supplied per-request context fields that are propagated to the peer getter load function.
func (*Group) GetForPeer ¶ added in v2.6.5
GetForPeer retrieves key for peer in a crosstalk request, thus further crosstalk won't be allowed.
type HTTPPool ¶
type HTTPPool struct {
// contains filtered or unexported fields
}
HTTPPool implements PeerPicker for a pool of HTTP peers.
func NewHTTPPoolOptsWithWorkspace ¶ added in v2.5.3
func NewHTTPPoolOptsWithWorkspace(ws *Workspace, self string, o *HTTPPoolOptions) *HTTPPool
NewHTTPPoolOptsWithWorkspace initializes an HTTP pool of peers with the given options. Unlike NewHTTPPoolWithWorkspace, this function does not register the created pool as an HTTP handler. The returned *HTTPPool implements http.Handler and must be registered using http.Handle.
func NewHTTPPoolWithWorkspace ¶ added in v2.5.3
NewHTTPPoolWithWorkspace initializes an HTTP pool of peers, and registers itself as a PeerPicker. For convenience, it also registers itself as an http.Handler with http.DefaultServeMux. The self argument should be a valid base URL that points to the current server, for example "http://example.net:8000".
func (*HTTPPool) GetAll ¶
func (p *HTTPPool) GetAll() []ProtoGetter
GetAll returns all the peers in the pool
func (*HTTPPool) Set ¶
Set updates the pool's list of peers. Each peer value should be a valid base URL, for example "http://example.net:8000".
type HTTPPoolOptions ¶
type HTTPPoolOptions struct {
// BasePath specifies the HTTP path that will serve groupcache requests.
// If blank, it defaults to "/_groupcache/".
BasePath string
// Replicas specifies the number of key replicas on the consistent hash.
// If blank, it defaults to 50.
Replicas int
// HashFn specifies the hash function of the consistent hash.
// If blank, it defaults to crc32.ChecksumIEEE.
HashFn consistenthash.Hash
// Transport optionally specifies an http.RoundTripper for the client
// to use when it makes a request.
// If nil, the client uses http.DefaultTransport.
Transport func(context.Context) http.RoundTripper
// Context optionally specifies a context for the server to use when it
// receives a request.
// If nil, uses the http.Request.Context()
Context func(*http.Request) context.Context
}
HTTPPoolOptions are the configurations of a HTTPPool.
type Info ¶ added in v2.7.0
Info defines optional user-supplied per-request context fields that are propagated to the peer getter load function.
type Logger ¶
Logger is interface for pluggable logger. slog.Defaut() creates a logger that satifiest this interface.
type NoPeers ¶
type NoPeers struct{}
NoPeers is an implementation of PeerPicker that never finds a peer.
func (NoPeers) GetAll ¶
func (NoPeers) GetAll() []ProtoGetter
type Options ¶ added in v2.6.4
type Options struct {
Workspace *Workspace
Name string
CacheBytesLimit int64
Getter Getter
// HotCacheWeight and MainCacheWeight compose the ratio between the hot cache and the main cache.
// When the cache memory limit is reached, this ratio is used to limit each cache to its limit.
// One simple way to reason about this ratio is to think of one cache usage against
// the other, and NOT one cache against the total sum.
//
// Consider some examples:
// 1) mainWeigth=8 and hotWeight=1 => the hot cache limit is 1/8 of the main cache limit.
// 2) mainWeight=2 and hotWeight=1 => the hot cache limit is 1/2 of the main cache limit.
// 3) mainWeight=1 and hotWeight=1 => the hot cache limit is equal to the main cache limit.
// 4) mainWeight=1 and hotWeight=2 => the hot cache limit is 2x the main cache limit.
// 5) mainWeight=1 and hotWeight=8 => the hot cache limit is 8x the main cache limit.
//
// If unspecified, HotCacheWeight defaults to 1.
// If unspecified, MainCacheWeight defaults to 8.
HotCacheWeight int64
MainCacheWeight int64
// PurgeExpired enables evicting expired keys on memory full condition.
PurgeExpired bool
// ExpiredKeysEvictionInterval sets interval for periodic eviction of expired keys.
// If unset, defaults to 30-minute period.
// Set to -1 to disable periodic eviction of expired keys.
ExpiredKeysEvictionInterval time.Duration
// Logger is optional pluggable logger.
// If undefined, groupcache won't log anything.
// If defined, groupcache will log errors retrieving keys from peers.
// slog.Defaut() creates a logger that satifiest this interface.
Logger Logger
}
Options define settings for group.
type PeerPicker ¶
type PeerPicker interface {
// PickPeer returns the peer that owns the specific key
// and true to indicate that a remote peer was nominated.
// It returns nil, false if the key owner is the current peer.
PickPeer(key string) (peer ProtoGetter, ok bool)
// GetAll returns all the peers in the group
GetAll() []ProtoGetter
}
PeerPicker is the interface that must be implemented to locate the peer that owns a specific key.
type ProtoGetter ¶
type ProtoGetter interface {
Get(context context.Context, in *pb.GetRequest, out *pb.GetResponse) error
Remove(context context.Context, in *pb.GetRequest) error
Set(context context.Context, in *pb.SetRequest) error
// GetURL returns the peer URL
GetURL() string
}
ProtoGetter is the interface that must be implemented by a peer.
type Sink ¶
type Sink interface {
// SetString sets the value to s.
SetString(s string, e time.Time) error
// SetBytes sets the value to the contents of v.
// The caller retains ownership of v.
SetBytes(v []byte, e time.Time) error
// SetProto sets the value to the encoded version of m.
// The caller retains ownership of m.
SetProto(m proto.Message, e time.Time) error
// contains filtered or unexported methods
}
A Sink receives data from a Get call.
Implementation of Getter must call exactly one of the Set methods on success.
`e` sets an optional time in the future when the value will expire. If you don't want expiration, pass the zero value for `time.Time` (for instance, `time.Time{}`).
func AllocatingByteSliceSink ¶
AllocatingByteSliceSink returns a Sink that allocates a byte slice to hold the received value and assigns it to *dst. The memory is not retained by groupcache.
func ByteViewSink ¶
ByteViewSink returns a Sink that populates a ByteView.
func StringSink ¶
StringSink returns a Sink that populates the provided string pointer.
func TruncatingByteSliceSink ¶
TruncatingByteSliceSink returns a Sink that writes up to len(*dst) bytes to *dst. If more bytes are available, they're silently truncated. If fewer bytes are available than len(*dst), *dst is shrunk to fit the number of bytes available.
type Stats ¶
type Stats struct {
Gets atomic.Int64 // any Get request, including from peers
CacheHits atomic.Int64 // either cache was good
GetFromPeersLatencyLower atomic.Int64 // slowest duration to request value from peers
PeerLoads atomic.Int64 // either remote load or remote cache hit (not an error)
PeerErrors atomic.Int64
Loads atomic.Int64 // (gets - cacheHits)
LoadsDeduped atomic.Int64 // after singleflight
LocalLoads atomic.Int64 // total good local loads
LocalLoadErrs atomic.Int64 // total bad local loads
ServerRequests atomic.Int64 // gets that came over the network from peers
CrosstalkRefusals atomic.Int64 // refusals for additional crosstalks
}
Stats are per-group statistics.
type Workspace ¶ added in v2.5.5
type Workspace struct {
// contains filtered or unexported fields
}
Workspace holds the "global" state for groupcache.
func NewWorkspace ¶ added in v2.5.3
func NewWorkspace() *Workspace
NewWorkspace creates new workspace.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
cmd
|
|
|
server
command
Package main implements a test server.
|
Package main implements a test server. |
|
Package consistenthash provides an implementation of a ring hash.
|
Package consistenthash provides an implementation of a ring hash. |
|
Package lru implements an LRU cache.
|
Package lru implements an LRU cache. |
|
Package singleflight provides a duplicate function call suppression mechanism.
|
Package singleflight provides a duplicate function call suppression mechanism. |