Redis is a key-value storage system. Similar to memcached, it supports storing more value types, including string (string), list (linked list), set (set), and Zset (ordered collection). These data types support Push/pop, Add/remove, and intersection-set and difference sets, and richer operations, and these operations are atomic. Based on this, Redis supports sorting in a variety of different ways. As with memcached, data is cached in memory to ensure efficiency. The difference is that Redis periodically writes the updated data to disk or writes the modified operation to the appended record file, and Master-slave (Master-Slave) synchronization is implemented on this basis.
It is used primarily for data storage (caching), publication subscriptions, Message Queuing, and distributed locks.
1.redis installation can be installed using Windows and Linux and Docker installations
Official website https://redis.io/
Chinese http://www.redis.cn/
2. Visualization Tools
Redisdesktopmanager
3. C # Driver
The more well-known C # drivers are Servicestack.redis and Stackexchange.redis
Due to the Servicestack.redis, the default thread pool is provided as a charge, which is mainly the limit of the number of concurrent payments to be lifted.
The Stackexchange.redis does not provide the default thread pool without the concurrency limit and is free.
The Stackexchange.redis package class is easy to use.
Public classRedismanager {/// <summary> ///Lock Object/// </summary> Private Static Object_locker =New Object(); /// <summary> ///Stackexchange.redis Object/// </summary> Private StaticConnectionmultiplexer _redis; /// <summary> ///Proxy Type///None = 0,///twemproxy = 1,/// </summary> Private Static intProxy =int. Parse (configurationmanager.appsettings["Redis_proxy"] ??"0"); /// <summary> ///is the Sentinel server///Yes=1,///no=0,/// </summary> Private Static intIssentinel =int. Parse (configurationmanager.appsettings["Redis_redisissentinel"] ??"0"); /// <summary> ///the password for the Redis Master data server in Sentinel mode/// </summary> Private Static stringAuthpassword = configurationmanager.appsettings["Redis_redisissentinel"]; /// <summary> ///ServerName/// </summary> Private Static stringServiceName = configurationmanager.appsettings["Redis_servicename"]; /// <summary> ///get Stackexchange.redis Single-instance object/// </summary> Public Staticconnectionmultiplexer Instance {Get { if(_redis = =NULL|| !_redis. isconnected) {Lock(_locker) {if(_redis = =NULL|| !_redis. isconnected) {_redis=GetManager (); return_redis; } } } return_redis; } } /// <summary> ///Build Links/// </summary> /// <param name= "connectionString" ></param> /// <returns></returns> Private Staticconnectionmultiplexer GetManager () {returnGetcurrentredis (); } /// <summary> ///Each connection string is separated by commas and Sentinel does not support passwords/// </summary> /// <returns></returns> Staticconnectionmultiplexer Getcurrentredis () {varconnectionString = configurationmanager.appsettings["Redis_host"]; Connectionmultiplexer Conn; varoption =Newconfigurationoptions (); Option. Proxy= (proxy) proxy;//proxy mode, currently supported TW//Automatic connection of master Redis in Sentinel mode if(Issentinel = =1) { varConfigarr = Connectionstring.split (New Char[] {','}, Stringsplitoptions.removeemptyentries); Configarr.tolist (). ForEach (i={option. Endpoints.add (i); }); Option. Tiebreaker="";//This line must be added in Sentinel modeOption.commandmap =Commandmap.sentinel; Conn=connectionmultiplexer.connect (option); for(inti =0; I < option. Endpoints.count; i++) { Try{connectionString=Conn. Getserver (option. Endpoints[i]). Sentinelgetmasteraddressbyname (ServiceName). ToString (); Console.WriteLine ("current main Master[{0}]:{1}", I, connectionString); Break; } Catch(Redisconnectionexception ex)//timed out { Continue; } Catch(Exception ex) {Continue; } } } returnConnectionmultiplexer.connect (connectionString +", password="+Authpassword); } }
View Code
Message Queuing:
Team
/// <summary> ///Message Queuing-queued/// </summary> Static voidListleftpush () { while(true) { stringmsg = $"{datetime.now:hh:mm}-{globaxid}-{thread.currentthread.managedthreadid}-{stringextend.getranstring (8)}"; RedisManager.Instance.GetDatabase (REDISCONFIG.DEMODB). Listleftpush (Redisconfig.demokey, msg); Globaxid++; Console.WriteLine ($"Leftpush:{msg}"); Task.delay ( -); Thread.Sleep ( -); } }
View Code
Out team:
/// <summary> ///Message Queuing-out of team/// </summary> Static voidListleftpush () { while(true) { //Listleftpush varmsg =RedisManager.Instance.GetDatabase (REDISCONFIG.DEMODB). Listleftpop (Redisconfig.demokey); if(!Msg. IsNullOrEmpty) {Console.WriteLine ($"out of team: {msg}"); Task.delay ( $); } Else{Thread.Sleep ( +); } } }
View Code
Effect:
4.2 Publish a subscription:
Release
/// <summary> ///Publish/// </summary> Static voidPublish () { while(true) { Lock(lockobj) {stringmsg = $"{datetime.now:hh:mm}-{globaxid}-{stringextend.getranstring (8)}"; varSub =RedisManager.Instance.GetSubscriber (); Sub. Publish (Redisconfig.demochannel1, msg); Console.WriteLine ($"Publish:{msg}"); Globaxid++; } task.delay ( $); Thread.Sleep ( -); } }
View CodeSubscription
/// <summary> ///Subscribe/// </summary> Static voidSubscribe () { while(true) { Lock(lockobj) {//string msg = $ "publish:{datetime.now:hh:mm}-{globaxid}-{stringextend.getranstring (8)}"; varSub =RedisManager.Instance.GetSubscriber (); Sub. Subscribe (Redisconfig.demochannel1, Subhandel); } task.delay ( $); Thread.Sleep ( -); } } Static voidSubhandel (Redischannel CNL, Redisvalue val) {if(!val. IsNullOrEmpty) {Console.WriteLine ($"Subscribe{val}, Thread: {Thread.CurrentThread.ManagedThreadId}, whether the thread pool: {Thread.CurrentThread.IsThreadPoolThread} "); } Else{Thread.Sleep ( +); } }
View Code
C#redis use