.Net Core Three Redis client comparison and Reviews

Foreword

  Slightly more complex Internet projects, technology selection may involve Redis, .NetCore ecological more perfect, more and more .NetCore support of Redis client,

The following three common Redis client, I believe we usually use some more or less, usually combined with the use of three clients, some feelings and experiences.

To more macro background: 

 

Package Name background github star Dependence on .NetStandard2.0 target frame
Stackexchange.redis Veteran .Net Redis client, free, unlimited, Stackoverflow endorsement 3700
Microsoft.Extensions.Caching.StackExchangeRedis .Netcore 2.2 for IDistributedCache Redis interface distributed cache  
CSRedisCore Famous people achieve third-party clients, redis.io official website recommended 894

Reviews

Three support Redis client connection string substantially the same configuration

  "connectionstrings": {
    "redis": "localhost:6379,password=abcdef,connectTimeout=5000,writeBuffer=40960"
  }

StackExchange.Redis

  Positioning high-performance, general-purpose Redis .Net client ; conveniently used Redis fully functional; Redis support the Cluster

  • High-performance core in that the multiplexer (Redis supports efficient sharing of the plurality of connecting the calling thread)
Redis = ConnectionMultiplexer.Connect ConnectionMultiplexer ( " server1: 6379, server2: 6379 " );
 // core library is the daily application of the IDatabase 
the IDatabase db = redis.GetDatabase (); 

// support Pub / Sub 
the ISubscriber Sub = redis.GetSubscriber ( ); 
sub.Subscribe ( " messages " , (Channel, Message) => { 
    Console.WriteLine (( String ) Message); 
});
 --- 
sub.Publish ( " messages " , " Hello " );
It is also because multiplexing, StackExchange.Redis unique characteristics Redis is not supported by "blocking POPs" , this feature is of critical theory RedisMQ.
If you need blocking pops, StackExchange.Redis official recommended pub / sub model simulation to achieve.
  • Please pay attention to the daily operation of the API IDatabase interface, support for asynchronous method, here I am [ the client operating Redis try not to use asynchronous methods do not agree with the argument], I think for the asynchronous method or comply with Microsoft best practices: For IO intensive operations , you can use asynchronous try to use asynchronous
_redisDB0.StringDecrementAsync ( " ProfileUsageCap " , ( Double ) . 1 )      // corresponding to the self-energizing redis API: DECR MyKey 
 _redisDB0.HashGetAsync (profileUsage, eqidPair.ProfileId))       // corresponding to API redis: Key hget field1 
_redisDB0.HashDecrementAsync (profileUsage, eqidPair .ProfileId, . 1 )   //   corresponding to the hash redis increment api: HINCRBY myhash field -1

 

  • ConnectionMultiplexer way to support the switch at any time Redis DB, for the operation of multiple Redis DB, I encapsulates a common Redis DB operation client.
 public class RedisStore
    {
        private static Lazy<ConnectionMultiplexer> LazyConnection;
        private static string connectionRedis = "localhost:6379";

        public RedisStore(string connectiontring)
        {
            connectionRedis = connectiontring ?? "localhost:6379";
            LazyConnection = new Lazy<ConnectionMultiplexer>(() => ConnectionMultiplexer.Connect(connectionRedis));
        }
        public static ConnectionMultiplexer Connection => LazyConnection.Value;
        public RedisDatabase RedisCache => new RedisDatabase(Connection);

    }

    public class RedisDatabase
    {
        private Dictionary<int, IDatabase> DataBases = new Dictionary<int, IDatabase>();
        
        public ConnectionMultiplexer RedisConnection { get; }

        public RedisDatabase(ConnectionMultiplexer Connection)
        {
            DataBases = new Dictionary<int, IDatabase>{ };
            for(var i=0;i<16;i++)
            {
                DataBases.Add(i, Connection.GetDatabase(i));
            }
            
            RedisConnection = Connection;
        }

        public IDatabase this[int index]
        {
            get
            {
                if (DataBases.ContainsKey(index))
                    return DataBases[index];
                else
                   return DataBases[0];
            }
        }
    }
RedisCache

 

Microsoft.Extensions.Caching.StackExchangeRedis

    It is seen from nuget doc, which depends on the component library StackExchange.Redis client; .NetCore client is provided for the distributed cache, the focus characteristic of Redis cache .

The library is based IDistributedCache interface, the interface is a general versatility distributed cache, the cache contents of the read and write to byte [] form ; signature additional function can be used also more likely to increase [general, check Operation]
// add Redis cache service 
services.AddStackExchangeRedisCache(options =>
{
  options.Configuration = Configuration.GetConnectionString("redis");
  options.InstanceName = "SampleInstance";
});

// Set Cache Item (by byte[])
 lifetime.ApplicationStarted.Register(() =>
            {
                var currentTimeUTC = DateTime.UtcNow.ToString();
                byte[] encodedCurrentTimeUTC = Encoding.UTF8.GetBytes(currentTimeUTC);
                var options = new DistributedCacheEntryOptions()
                    .SetSlidingExpiration(TimeSpan.FromMinutes(20));
                cache.Set("cachedTimeUTC", encodedCurrentTimeUTC, options);
            });  

// Retrieve Cache Item
[HttpGet]
[Route("CacheRedis")]
public async Task<string> GetAsync()
{
            var ret = "";
            var bytes = await _cache.GetAsync("cachedTimeUTC");
            if (bytes! = null ) 
            { 
                right = Encoding.UTF8.GetString (bytes); 
                _logger.LogInformation (right); 
            } 
            Return   await Task.FromResult (right); 
}

① Clearly, the Cache component and can not do are free to switch Redis DB, currently available in the connection string redis -time configuration items which you want to use Redis DB

① generates key = SampleInstancecachedTimeUTC specified items in the cache redis DB (default 0)

② Redis does not support bytes [] in the form of stored value, more than byte [] Hash is actually stored in the form

 

 

 CSRedisCore

The functional components of more powerful, the actual more games are played Redis application scenarios .
- Normal mode
- Official cluster model redis cluster
- partition mode (Author achieve)
 
Normal mode is extremely simple to use, here are tips to: the client does not support random switching Redis DB, but the author presents a way to alleviate: multi-client structure.
var redisDB = new CSRedisClient[16];                        // 多客户端
......
services.AddSingleton(redisDB);
// ---------------------------- _redisDB[0].IncrByAsync("ProfileUsageCap", -1) _redisDB[0].HGetAsync(profileUsage, eqidPair.ProfileId.ToString()) _redisDB[0].HIncrByAsync(profileUsage, eqidPair.ProfileId.ToString(), -1);

 Built-in static operation class RedisHelper, and Redis-Cli command exactly the same, so he can natively "blocking pops".

// achieve back-office services, sustainable consumption MQ message 
public  class BackgroundJob: BackgroundService 
    { 
        Private  Readonly CSRedisClient [] _redisDB;
         Private  Readonly IConfiguration _conf;
         Private  Readonly ILogger _logger;
         public BackgroundJob (CSRedisClient [] csRedisClients, IConfiguration conf, ILoggerFactory LoggerFactory) 
        { 
            _redisDB = csRedisClients; 
            _conf = the conf; 
            _logger = loggerFactory.CreateLogger (NameOf (BackgroundJob)); 
        } 
        
        //  Background 需要实现的后台任务
        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            _redisDB[0] = new CSRedisClient(_conf.GetConnectionString("redis") + ",defualtDatabase=" + 0);
            RedisHelper.Initialization(_redisDB[0]);

            while (!stoppingToken.IsCancellationRequested)
            {
                var key = $"eqidpair:{DateTime.Now.ToString("yyyyMMdd")}" ;
                 // Blocking read from the first message right List 
                var eqidpair RedisHelper.BRPop = ( . 5 , Key);
                 // the TODO the Message Handler 
                the else 
                    the await Task.Delay ( 1000 , stoppingToken); 
            } 
        } 
    }

 ----- RedisMQ producer ---
 //   one or more msg header inserted List 
RedisHelper.LPush (redisKey, eqidPairs.ToArray ()) ;
Simple and effective RedisMQ

Redis little experience:

  • Logarithmic time complexity Redis API's own heart must be used, try not to use long-running commands such as keys *, which can be observed by redis.io SlowLog command command takes a long time
  • Redis Key in accordance with ":" string has separated defined business significance, such as NewUsers: 201909: 666666 (Redis UI may be some friendly and intuitive view of the service)
  • Suitable Key-Value determined size: Redis more friendly for small value, if the value is large, taking into multiple key
  • About cache penetration, the interview will ask themselves searching Bloom filter.
  • Although there are redis persistence mechanism, but in practice it will be key-value persisted to a relational database, because for some structured query, SQL more efficient.

Guess you like

Origin www.cnblogs.com/JulianHuang/p/11418881.html