implement and use striped LRU cache to lower mutex contention (#15764)

* Implement Striped LRU cache

* ci

* fix

Co-authored-by: Mattermod <mattermod@users.noreply.github.com>
Этот коммит содержится в:
Florent Peterschmitt
2020-12-09 14:55:14 +01:00
коммит произвёл GitHub
родитель 96d76760f0
Коммит 349b83f23a
34 изменённых файлов: 872 добавлений и 203 удалений

24
services/cache/lru.go поставляемый
Просмотреть файл

@@ -9,21 +9,22 @@ import (
"time"
"github.com/mattermost/mattermost-server/v5/model"
"github.com/tinylib/msgp/msgp"
"github.com/vmihailenco/msgpack/v5"
)
// LRU is a thread-safe fixed size LRU cache.
type LRU struct {
name string
lock sync.RWMutex
size int
len int
currentGeneration int64
evictList *list.List
items map[string]*list.Element
lock sync.RWMutex
defaultExpiry time.Duration
name string
invalidateClusterEvent string
currentGeneration int64
len int
}
// LRUOptions contains options for initializing LRU cache
@@ -32,6 +33,9 @@ type LRUOptions struct {
Size int
DefaultExpiry time.Duration
InvalidateClusterEvent string
// StripedBuckets is used only by LRUStriped and shouldn't be greater than the number
// of CPUs available on the machine running this cache.
StripedBuckets int
}
// entry is used to hold a value in the evictList.
@@ -43,7 +47,7 @@ type entry struct {
}
// NewLRU creates an LRU of the given size.
func NewLRU(opts *LRUOptions) Cache {
func NewLRU(opts LRUOptions) Cache {
return &LRU{
name: opts.Name,
size: opts.Size,
@@ -141,19 +145,15 @@ func (l *LRU) set(key string, value interface{}, ttl time.Duration) error {
var buf []byte
var err error
// We use a fast path for hot structs.
if msgpVal, ok := value.(msgp.Marshaler); ok {
buf, err = msgpVal.MarshalMsg(nil)
if err != nil {
return err
}
} else {
// Slow path for other structs.
buf, err = msgpack.Marshal(value)
if err != nil {
return err
}
}
if err != nil {
return err
}
l.lock.Lock()