Skip to content

Client-Side Caching - Enhancing Thread-Safety in Key Retrieval #2402

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
GuyKomari opened this issue Apr 30, 2023 · 0 comments · May be fixed by #3268
Open

Client-Side Caching - Enhancing Thread-Safety in Key Retrieval #2402

GuyKomari opened this issue Apr 30, 2023 · 0 comments · May be fixed by #3268
Labels
type: bug A general bug
Milestone

Comments

@GuyKomari
Copy link

GuyKomari commented Apr 30, 2023

Feature Request

The existing implementation of the get method in the ClientSideCaching class fails to provide a mechanism that guarantees the exclusive access of a single thread to fetch a value from the Redis server for a specific key.
Consequently, under high concurrent load scenarios involving the same key, the current implementation may cause redundant and unnecessary calls to the Redis server.

Current implementation get:

    @Override
    public V get(K key) {

        V value = cacheAccessor.get(key);

        if (value == null) {
            value = redisCache.get(key);

            if (value != null) {
                cacheAccessor.put(key, value);
            }
        }

        return value;
    }

Describe the solution you'd like

Utilize a local locking mechanism to guarantee that at any given time, only a single thread is permitted to retrieve a value from the Redis cache for a particular key.

private final ConcurrentHashMap<K, ReentrantLock> keyLocks = new ConcurrentHashMap<>();

public V get(K key) {
        V value = cacheAccessor.get(key);

        if (value == null) {
            // Acquire a lock for this key
            ReentrantLock lock = keyLocks.computeIfAbsent(key, k -> new ReentrantLock());
            lock.lock();

            try {
                // Double-check to see if the value has been added by another thread
                value = cacheAccessor.get(key);

                // If the value is not in the cache, fetch it from Redis server and set it in client-cache
                if (value == null) {
                    value = redisCache.get(key);

                    if (value != null) {
                        cacheAccessor.put(key, value);
                    }
                }
            } finally {
                lock.unlock();
            }
        }

        return value;
    }
@tishun tishun added this to the Backlog milestone Jun 28, 2024
@tishun tishun added the type: bug A general bug label Jun 28, 2024
yybmion added a commit to yybmion/lettuce that referenced this issue Apr 20, 2025
Added per-key locking mechanism to ensure that only a single thread
fetches a value from Redis cache for a specific key. This prevents
redundant Redis server calls under high concurrent load.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: bug A general bug
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants