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>
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
96d76760f0
Коммит
349b83f23a
@@ -68,7 +68,11 @@ func setupTestHelper(dbStore store.Store, enterprise bool, includeCacheLayer boo
|
||||
if includeCacheLayer {
|
||||
// Adds the cache layer to the test store
|
||||
options = append(options, StoreOverride(func(s *Server) store.Store {
|
||||
return localcachelayer.NewLocalCacheLayer(dbStore, s.Metrics, s.Cluster, s.CacheProvider)
|
||||
lcl, err2 := localcachelayer.NewLocalCacheLayer(dbStore, s.Metrics, s.Cluster, s.CacheProvider)
|
||||
if err2 != nil {
|
||||
panic(err2)
|
||||
}
|
||||
return lcl
|
||||
}))
|
||||
} else {
|
||||
options = append(options, StoreOverride(dbStore))
|
||||
|
||||
@@ -22,14 +22,14 @@ func StoreOverride(override interface{}) Option {
|
||||
return func(s *Server) error {
|
||||
switch o := override.(type) {
|
||||
case store.Store:
|
||||
s.newStore = func() store.Store {
|
||||
return o
|
||||
s.newStore = func() (store.Store, error) {
|
||||
return o, nil
|
||||
}
|
||||
return nil
|
||||
|
||||
case func(*Server) store.Store:
|
||||
s.newStore = func() store.Store {
|
||||
return o(s)
|
||||
s.newStore = func() (store.Store, error) {
|
||||
return o(s), nil
|
||||
}
|
||||
return nil
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ const LINK_CACHE_SIZE = 10000
|
||||
const LINK_CACHE_DURATION = 1 * time.Hour
|
||||
const MaxMetadataImageSize = MaxOpenGraphResponseSize
|
||||
|
||||
var linkCache = cache.NewLRU(&cache.LRUOptions{
|
||||
var linkCache = cache.NewLRU(cache.LRUOptions{
|
||||
Size: LINK_CACHE_SIZE,
|
||||
})
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ import (
|
||||
"os/exec"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
@@ -114,7 +115,7 @@ type Server struct {
|
||||
|
||||
timezones *timezones.Timezones
|
||||
|
||||
newStore func() store.Store
|
||||
newStore func() (store.Store, error)
|
||||
|
||||
htmlTemplateWatcher *utils.HTMLTemplateWatcher
|
||||
sessionCache cache.Cache
|
||||
@@ -286,34 +287,51 @@ func NewServer(options ...Option) (*Server, error) {
|
||||
return nil, errors.Wrapf(err, "Unable to connect to cache provider")
|
||||
}
|
||||
|
||||
s.sessionCache = s.CacheProvider.NewCache(&cache.CacheOptions{
|
||||
Size: model.SESSION_CACHE_SIZE,
|
||||
})
|
||||
s.seenPendingPostIdsCache = s.CacheProvider.NewCache(&cache.CacheOptions{
|
||||
var err error
|
||||
if s.sessionCache, err = s.CacheProvider.NewCache(&cache.CacheOptions{
|
||||
Size: model.SESSION_CACHE_SIZE,
|
||||
Striped: true,
|
||||
StripedBuckets: runtime.NumCPU() - 1,
|
||||
}); err != nil {
|
||||
return nil, errors.Wrap(err, "Unable to create session cache")
|
||||
}
|
||||
if s.seenPendingPostIdsCache, err = s.CacheProvider.NewCache(&cache.CacheOptions{
|
||||
Size: PENDING_POST_IDS_CACHE_SIZE,
|
||||
})
|
||||
s.statusCache = s.CacheProvider.NewCache(&cache.CacheOptions{
|
||||
Size: model.STATUS_CACHE_SIZE,
|
||||
})
|
||||
}); err != nil {
|
||||
return nil, errors.Wrap(err, "Unable to create pending post ids cache")
|
||||
}
|
||||
if s.statusCache, err = s.CacheProvider.NewCache(&cache.CacheOptions{
|
||||
Size: model.STATUS_CACHE_SIZE,
|
||||
Striped: true,
|
||||
StripedBuckets: runtime.NumCPU() - 1,
|
||||
}); err != nil {
|
||||
return nil, errors.Wrap(err, "Unable to create status cache")
|
||||
}
|
||||
|
||||
s.createPushNotificationsHub()
|
||||
|
||||
if err := utils.InitTranslations(s.Config().LocalizationSettings); err != nil {
|
||||
return nil, errors.Wrapf(err, "unable to load Mattermost translation files")
|
||||
if err2 := utils.InitTranslations(s.Config().LocalizationSettings); err2 != nil {
|
||||
return nil, errors.Wrapf(err2, "unable to load Mattermost translation files")
|
||||
}
|
||||
|
||||
s.initEnterprise()
|
||||
|
||||
if s.newStore == nil {
|
||||
s.newStore = func() store.Store {
|
||||
s.newStore = func() (store.Store, error) {
|
||||
s.sqlStore = sqlstore.New(s.Config().SqlSettings, s.Metrics)
|
||||
|
||||
lcl, err2 := localcachelayer.NewLocalCacheLayer(
|
||||
retrylayer.New(s.sqlStore),
|
||||
s.Metrics,
|
||||
s.Cluster,
|
||||
s.CacheProvider,
|
||||
)
|
||||
if err2 != nil {
|
||||
return nil, errors.Wrap(err2, "cannot create local cache layer")
|
||||
}
|
||||
|
||||
searchStore := searchlayer.NewSearchLayer(
|
||||
localcachelayer.NewLocalCacheLayer(
|
||||
retrylayer.New(s.sqlStore),
|
||||
s.Metrics,
|
||||
s.Cluster,
|
||||
s.CacheProvider,
|
||||
),
|
||||
lcl,
|
||||
s.SearchEngine,
|
||||
s.Config(),
|
||||
)
|
||||
@@ -330,17 +348,20 @@ func NewServer(options ...Option) (*Server, error) {
|
||||
return timerlayer.New(
|
||||
searchStore,
|
||||
s.Metrics,
|
||||
)
|
||||
), nil
|
||||
}
|
||||
}
|
||||
|
||||
if htmlTemplateWatcher, err := utils.NewHTMLTemplateWatcher("templates"); err != nil {
|
||||
mlog.Error("Failed to parse server templates", mlog.Err(err))
|
||||
if htmlTemplateWatcher, err2 := utils.NewHTMLTemplateWatcher("templates"); err2 != nil {
|
||||
mlog.Error("Failed to parse server templates", mlog.Err(err2))
|
||||
} else {
|
||||
s.htmlTemplateWatcher = htmlTemplateWatcher
|
||||
}
|
||||
|
||||
s.Store = s.newStore()
|
||||
s.Store, err = s.newStore()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "cannot create store")
|
||||
}
|
||||
|
||||
s.configListenerId = s.AddConfigListener(func(_, _ *model.Config) {
|
||||
s.configOrLicenseListener()
|
||||
|
||||
@@ -62,7 +62,11 @@ func setupTestHelper(dbStore store.Store, enterprise bool, includeCacheLayer boo
|
||||
options = append(options, app.ConfigStore(memoryStore))
|
||||
if includeCacheLayer {
|
||||
options = append(options, app.StoreOverride(func(s *app.Server) store.Store {
|
||||
return localcachelayer.NewLocalCacheLayer(dbStore, s.Metrics, s.Cluster, s.CacheProvider)
|
||||
lcl, err2 := localcachelayer.NewLocalCacheLayer(dbStore, s.Metrics, s.Cluster, s.CacheProvider)
|
||||
if err2 != nil {
|
||||
panic(err2)
|
||||
}
|
||||
return lcl
|
||||
}))
|
||||
} else {
|
||||
options = append(options, app.StoreOverride(dbStore))
|
||||
|
||||
Ссылка в новой задаче
Block a user