MM-59932: Migrate remaining caches to Redis (#27880)
- We introduce 2 new APIs: 1. Scan: this allows incremental iteration without blocking the Redis server and is the recommended way to iterate over keys. With this, we have entirely removed the need for Keys. 2. RemoveMulti: this allows deletion of multiple keys in a single operation which optimizes network round trips. - While here, we make a small improvement to GetStatusFromCache, where we remove the shallow copy which wasn't necessary because we always serialize the data from the cache. - We do not use Redis for session cache because of frequent requests to iterate the entire cache which leads to a lot of `SCAN` calls. - Avoid broadcasting status update messages for Redis case. - Setting cache expiry for status cache - Removing .Set method altogether to prevent any chances of setting an item with no expiry. https://mattermost.atlassian.net/browse/MM-59932 ```release-note NONE ```
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
e5842e67a8
Коммит
a1012d33eb
@@ -11,6 +11,7 @@ import (
|
||||
"github.com/mattermost/mattermost/server/public/model"
|
||||
"github.com/mattermost/mattermost/server/public/shared/mlog"
|
||||
"github.com/mattermost/mattermost/server/public/shared/request"
|
||||
"github.com/mattermost/mattermost/server/v8/platform/services/cache"
|
||||
)
|
||||
|
||||
func (ps *PlatformService) ReturnSessionToPool(session *model.Session) {
|
||||
@@ -50,18 +51,52 @@ func (ps *PlatformService) AddSessionToCache(session *model.Session) {
|
||||
}
|
||||
|
||||
func (ps *PlatformService) ClearUserSessionCacheLocal(userID string) {
|
||||
if keys, err := ps.sessionCache.Keys(); err == nil {
|
||||
var session *model.Session
|
||||
for _, key := range keys {
|
||||
if err := ps.sessionCache.Get(key, &session); err == nil {
|
||||
if session.UserId == userID {
|
||||
ps.sessionCache.Remove(key)
|
||||
if m := ps.metricsIFace; m != nil {
|
||||
m.IncrementMemCacheInvalidationCounterSession()
|
||||
}
|
||||
var toDelete []string
|
||||
// First, we iterate over the entire session cache.
|
||||
err := ps.sessionCache.Scan(func(keys []string) error {
|
||||
if len(keys) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
toPass := make([]any, 0, len(keys))
|
||||
for i := 0; i < len(keys); i++ {
|
||||
var session *model.Session
|
||||
toPass = append(toPass, &session)
|
||||
}
|
||||
|
||||
errs := ps.sessionCache.GetMulti(keys, toPass)
|
||||
for i, err := range errs {
|
||||
if err != nil {
|
||||
if err != cache.ErrKeyNotFound {
|
||||
return err
|
||||
}
|
||||
continue
|
||||
}
|
||||
gotSession := *(toPass[i].(**model.Session))
|
||||
if gotSession == nil {
|
||||
ps.logger.Warn("Found nil session in ClearUserSessionCacheLocal. This is not expected")
|
||||
continue
|
||||
}
|
||||
// If we find the userID matches the passed userID,
|
||||
// we mark it up for deletion.
|
||||
if gotSession.UserId == userID {
|
||||
toDelete = append(toDelete, keys[i])
|
||||
if m := ps.metricsIFace; m != nil {
|
||||
m.IncrementMemCacheInvalidationCounterSession()
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
ps.logger.Warn("Error while scanning in ClearUserSessionCacheLocal", mlog.Err(err))
|
||||
return
|
||||
}
|
||||
// Now, we delete everything.
|
||||
err = ps.sessionCache.RemoveMulti(toDelete)
|
||||
if err != nil {
|
||||
ps.logger.Warn("Error while removing keys in ClearUserSessionCacheLocal", mlog.Err(err))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Ссылка в новой задаче
Block a user