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
34
server/platform/services/cache/lru.go
поставляемый
34
server/platform/services/cache/lru.go
поставляемый
@@ -57,12 +57,6 @@ func (l *LRU) Purge() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Set adds the given key and value to the store without an expiry. If the key already exists,
|
||||
// it will overwrite the previous value.
|
||||
func (l *LRU) Set(key string, value any) error {
|
||||
return l.SetWithExpiry(key, value, 0)
|
||||
}
|
||||
|
||||
// SetWithDefaultExpiry adds the given key and value to the store with the default expiry. If
|
||||
// the key already exists, it will overwrite the previous value
|
||||
func (l *LRU) SetWithDefaultExpiry(key string, value any) error {
|
||||
@@ -101,11 +95,27 @@ func (l *LRU) Remove(key string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Keys returns a slice of the keys in the cache.
|
||||
func (l *LRU) Keys() ([]string, error) {
|
||||
l.lock.RLock()
|
||||
defer l.lock.RUnlock()
|
||||
func (l *LRU) RemoveMulti(keys []string) error {
|
||||
l.lock.Lock()
|
||||
defer l.lock.Unlock()
|
||||
|
||||
// Note, this is a copy of l.Remove. But we want to avoid
|
||||
// fine-grained locking for every single removal. Therefore,
|
||||
// we copy a bit of code for simplicity.
|
||||
for _, key := range keys {
|
||||
if ent, ok := l.items[key]; ok {
|
||||
l.removeElement(ent)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Scan passes the whole slice of keys to the callback in LRU mode.
|
||||
// We don't need this callback style for LRU, but since we share
|
||||
// the same interface with Redis, we maintain parity.
|
||||
func (l *LRU) Scan(f func([]string) error) error {
|
||||
l.lock.RLock()
|
||||
keys := make([]string, l.len)
|
||||
i := 0
|
||||
for ent := l.evictList.Back(); ent != nil; ent = ent.Prev() {
|
||||
@@ -115,7 +125,9 @@ func (l *LRU) Keys() ([]string, error) {
|
||||
i++
|
||||
}
|
||||
}
|
||||
return keys, nil
|
||||
l.lock.RUnlock()
|
||||
|
||||
return f(keys)
|
||||
}
|
||||
|
||||
// Len returns the number of items in the cache.
|
||||
|
||||
Ссылка в новой задаче
Block a user