隐藏

Redis C# 驱动 StackExchange.Redis 应用实例

发布:2023/3/21 22:30:43作者:管理员 来源:本站 浏览次数:787

StackExchange.Redis 是一个不错的 Redis C# 驱动,使用起来也相对比较简单。


1> 引用 StackExchange.redis



PM> Install-Package StackExchange.Redis


2> StackExchange.redsi 应用实例


由于 Redis 采用单线程单进程模型,所以 Redis 连接实例可以用单例来实现;



 public class RedisContextOpertion

   {

       private static ConnectionMultiplexer _redisConnection;

       private static object objLock = new object();

       static RedisContextOpertion()

       {

           if (_redisConnection == null)

           {

               lock (objLock)

               {

                   if (_redisConnection == null)

                   {

                       //StackExchange.redsi 支持 Redis 集群;

                       // string connString = "127.0.0.1:6379,127.0.0.1:6380";

                       string connString = "127.0.0.1:6379";

                       _redisConnection = ConnectionMultiplexer.Connect(connString);

                   }

               }

           }

       }

       public static ConnectionMultiplexer RedisConnection

       {

           get

           {

               return _redisConnection;

           }            

       }        

       private RedisContextOpertion() { }


   }




调用方法:


var conn = RedisContextOpertion.RedisConnection;

var resisDb = conn.GetDatabase();


StackExchang.redis 应用实例:


A :求有序集合(Sorted Sets)差集;


构造有序集合数据源: key1,key2;


var conn = RedisContextOpertion.RedisConnection;

var redisDb = conn.GetDatabase();

SortedSetEntry[] entity = new SortedSetEntry[] {new SortedSetEntry("a",100),new SortedSetEntry("b",200) };

SortedSetEntry[] entity1 = new SortedSetEntry[] { new SortedSetEntry("b", 200), new SortedSetEntry("c", 300) };

redisDb.SortedSetAdd("key1", entity, CommandFlags.None);

redisDb.SortedSetAdd("key2", entity1, CommandFlags.None);


key1:


key2:


计算代码:



var conn = RedisContextOpertion.RedisConnection;

var redisDb = conn.GetDatabase();

//先求出两个集合的并集,同时设置重合项的乘法因子为 0(),设置聚合方式为取最小值;

//("weights", 1, 0)weights 为关健字,1 为key1的乘法因子,0为key2的乘法因子,有多个 key 时,以此类推;

redisDb.Execute("ZUNIONSTORE", "newkey", 2, "key1", "key2", "weights", 1, 0, "aggregate", "min");

//去除 score 为零的的元素,得到差集;

redisDb.Execute("ZREMRANGEBYSCORE", "newkey", 0, 0);

var queryResult = redisDb.SortedSetRangeByScoreWithScores("newkey");

Console.WriteLine("value\tscore");

foreach (var item in queryResult)

{

  Console.WriteLine("{0}\t{1}",item.Element,item.Score);

}



计算结果:


注意事项:此方法不能在 Redis 集群环境中运行,因为 Redis 不支持跨节点调用,也就是说 Redis  Cluser 不支持,带有两个或以上 key 的命令;如果想要在集群环境中应用,就必需要保证 key1 , key2 和 newkey 存放在同一个 hash 槽内,以下实例实现不同的key存放在同一个 hash 槽内;


B:Redis 集群环境中,不同 key 存放在同一 hash 槽内


其实,要想使不同的 key 存放到同一 hash 槽内是比较简单的,我们只需要使多个 key 拥有共同的部分,并用“{}”把共同的部分包裹起来就可以了。当然这样做违背了集群均衡原则,我们只在特殊情况下使用。



var conn = RedisContextOpertion.RedisConnection;


var db = redis.GetDatabase();

var entity1 = new SortedSetEntry[] { new SortedSetEntry("a", 100), new SortedSetEntry("b", 200) };

var entity2 = new SortedSetEntry[] { new SortedSetEntry("b", 200), new SortedSetEntry("c", 300) };

var commKey = "{testkey}"; // 多个 key 的共同部分;

db.SortedSetAdd(commKey + "1", entity1);

db.SortedSetAdd(commKey + "2", entity2);





C:Redis 批量添加不同类型数据;



       var conn = RedisContextOpertion.RedisConnection;

       var db = conn.GetDatabase();

       List<Task> listTask = new List<Task>();

       var batch = db.CreateBatch();

       listTask.Add(batch.StringSetAsync("key1", "a")); //添加字符串类型数据;

       listTask.Add(batch.SortedSetAddAsync("key2", "b", 1)); // 添加有序集合数据;

       batch.Execute();

       Task.WaitAll(listTask.ToArray());






E:模糊查询,在redis里,允许模糊查询有3个通配符*、?、[]、      * : 通配任意多个字符 ?: 通配单个字符 []: 通配括号内的某1个字符



       /// <summary>

       ///  redis 模糊查询 key 是否存在;

       /// </summary>

       /// <param name="pattern"></param>

       /// <returns></returns>

       public bool KeyIsExit(string pattern)

       {

           var luaScript = "return redis.call('keys',@pattern)";

           var prepared = LuaScript.Prepare(luaScript);

           var cacheResult = db.ScriptEvaluate(prepared, new { pattern = pattern });

           if (cacheResult.IsNull)

           {

               return false;

           }

           var keys = ((string[])cacheResult).ToList();

           return keys.Count > 0;

       }




       /// <summary>

       /// redis 模糊查询 key 列表;

       /// </summary>

       /// <param name="pattern"></param>

       /// <returns></returns>

       public List<string> QueryMatchKeys(string pattern)

       {

           var keys = new List<string>();

           var script = "return redis.call('keys',@pattern)";

           var prepared = LuaScript.Prepare(script);

           var cacheResult = db.ScriptEvaluate(prepared, new { pattern = pattern });

           if (cacheResult.IsNull)

           {

               return keys;

           }

           return ((string[])cacheResult).ToList();

       }






Stack.Exchange.redis 推荐的写法;



string value = await db.StringGetAsync(key);

if (value == null)

{

    value = await ComputeValueFromDatabase(...);

    db.StringSet(key, value, flags: CommandFlags.FireAndForget);

}

return value;