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

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;

 

posted @ 2017-11-22 17:10  llsfast  阅读(3335)  评论(0编辑  收藏  举报