Remove/Delete all/one item from StackExchange.Redis cache

60,166

Solution 1

To remove a single item:

_cache.KeyDelete(key);

To remove all involves the FLUSHDB or FLUSHALL redis command; both are available in StackExchange.Redis; but, for reasons discussed here, they are not on the IDatabase API (because: they affect servers, not logical databases).

As per the "So how do I use them?" on that page:

server.FlushDatabase(); // to wipe a single database, 0 by default
server.FlushAllDatabases(); // to wipe all databases

(quite possibly after using GetEndpoints() on the multiplexer)

Solution 2

I could not able to flush database in Azure Redis Cache, got this error:

This operation is not available unless admin mode is enabled: FLUSHDB

Instead iterate through all keys to delete:

var endpoints = connectionMultiplexer.GetEndPoints();
var server = connectionMultiplexer.GetServer(endpoints.First());
//FlushDatabase didn't work for me: got error admin mode not enabled error
//server.FlushDatabase();
var keys = server.Keys();
foreach (var key in keys)
{
  Console.WriteLine("Removing Key {0} from cache", key.ToString());
  _cache.KeyDelete(key);
}

Solution 3

Both answers by @Rasi and @Marc Gravell contain pieces of code needed. Based on above, here is working snippet assuming there is just 1 server:

You need to connect to redis with allowAdmin=true, one way to obtain such options is to assign AllowAdmin to already parsed string:

var options = ConfigurationOptions.Parse("server:6379");
options.AllowAdmin = true;
var redis = ConnectionMultiplexer.Connect(options);

Then to flush all databases:

var endpoints = redis.GetEndPoints();
var server = redis.GetServer(endpoints[0]);
server.FlushAllDatabases();

Above will work on any redis deployment, not just Azure.

Solution 4

You can delete hash as well ie if you want to clear specific value from any cached list. For example, we have an emp list and inside with different department as cached.

public static void DeleteHash(string key, string cacheSubKey)
        {
            if (string.IsNullOrEmpty(key))
                throw new ArgumentNullException("key");

            Cache.HashDelete(key, cacheSubKey);
        }

so you can pass Key name and cache subkey as well.

Share:
60,166
Imran Qadir Baksh - Baloch
Author by

Imran Qadir Baksh - Baloch

Updated on July 09, 2022

Comments

  • Imran Qadir Baksh - Baloch
    Imran Qadir Baksh - Baloch almost 2 years

    I am using StackExchange.Redis client with Azure Redis Cache Service. Here is my class,

    public class RedisCacheService : ICacheService
    {
        private readonly ISettings _settings;
        private readonly IDatabase _cache;
    
        public RedisCacheService(ISettings settings)
        {
            _settings = settings;
            var connectionMultiplexer = ConnectionMultiplexer.Connect(settings.RedisConnection);
            _cache = connectionMultiplexer.GetDatabase();
        }
    
        public bool Exists(string key)
        {
            return _cache.KeyExists(key);
        }
    
        public void Save(string key, string value)
        {
            var ts = TimeSpan.FromMinutes(_settings.CacheTimeout);
            _cache.StringSet(key, value, ts);
        }
    
        public string Get(string key)
        {
            return _cache.StringGet(key);
        }
    
        public void Remove(string key)
        {
            // How to remove one
        }
    
        public void Clear()
        {
            // How to remove all
        }
    }
    

    Update: From the help of Marc, Here is my final class

    public class RedisCacheService : ICacheService
    {
        private readonly ISettings _settings;
        private readonly IDatabase _cache;
        private static ConnectionMultiplexer _connectionMultiplexer;
    
        static RedisCacheService()
        {
            var connection = ConfigurationManager.AppSettings["RedisConnection"];
            _connectionMultiplexer = ConnectionMultiplexer.Connect(connection);
        }
    
        public RedisCacheService(ISettings settings)
        {
            _settings = settings;
            _cache = _connectionMultiplexer.GetDatabase();
        }
    
        public bool Exists(string key)
        {
            return _cache.KeyExists(key);
        }
    
        public void Save(string key, string value)
        {
            var ts = TimeSpan.FromMinutes(_settings.CacheTimeout);
            _cache.StringSet(key, value, ts);
        }
    
        public string Get(string key)
        {
            return _cache.StringGet(key);
        }
    
        public void Remove(string key)
        {
            _cache.KeyDelete(key);
        }
    
        public void Clear()
        {
            var endpoints = _connectionMultiplexer.GetEndPoints(true);
            foreach (var endpoint in endpoints)
            {
                var server = _connectionMultiplexer.GetServer(endpoint);
                server.FlushAllDatabases();    
            }
        }
    }
    

    Now I don't know how to remove all items or single item from redis cache.

  • Imran Qadir Baksh - Baloch
    Imran Qadir Baksh - Baloch almost 10 years
    Thanks. Howdo I get the server.
  • Marc Gravell
    Marc Gravell almost 10 years
    @user960567 from the multiplexer; multiplexer.GetServer(...); the easiest thing to do is to request an endpoint from multiplexer.GetEndpoints(true). Obviously this is all a lot easier if you are only talking to one server. This is all explained at the end of the linked article.
  • Imran Qadir Baksh - Baloch
    Imran Qadir Baksh - Baloch almost 10 years
    But I only have connection string from azure, xx.redis.cache.windows.net,ssl=true,password=.... How then I get the server.
  • Imran Qadir Baksh - Baloch
    Imran Qadir Baksh - Baloch almost 10 years
    Also my RedisCacheService is per request(asp.net). Is it fine to instantiate ConnectionMultiplexer and IDatabase per request.
  • Marc Gravell
    Marc Gravell almost 10 years
    @user960567 the IDatabase: yes; the ConnectionMultiplexer: no; please read the first paragraph of Basic Usage
  • Imran Qadir Baksh - Baloch
    Imran Qadir Baksh - Baloch almost 10 years
    OK Thanks. GetEndpoints means I have to loop all end points and get server and call FlushAllDatabases. Thanks.
  • Marc Gravell
    Marc Gravell almost 10 years
    @user960567 you should probably only call FlushAllDatabases on the master servers (!IsSlave); and most likely that actually means one server.
  • Imran Qadir Baksh - Baloch
    Imran Qadir Baksh - Baloch almost 10 years
    I am using Azure Redis Preview(Basic). Not sure they use Master/Slave.
  • Marc Gravell
    Marc Gravell almost 10 years
    @user960567 actually, I'm pretty sure they do, but: I suspect that isn't available to the external caller; so indeed, if you only know one address, there's a very good chance that it is a master, and that GetEndpoints will return exactly one item
  • Sean Kearney
    Sean Kearney almost 10 years
    Make sure you set allowAdmin=true in the config string (or ConfigurationOptions). github.com/StackExchange/StackExchange.Redis/blob/master/Doc‌​s/…
  • Imran Qadir Baksh - Baloch
    Imran Qadir Baksh - Baloch over 9 years
    Mark I got another interesting issue, stackoverflow.com/questions/27718453/…
  • Imran Qadir Baksh - Baloch
    Imran Qadir Baksh - Baloch about 9 years
    Mark please check I have added bounty now stackoverflow.com/questions/27718453/…
  • Karthik
    Karthik over 4 years
    @SeanKearney - The link is broken. Here is the updated link stackexchange.github.io/StackExchange.Redis/…