首页 新闻 会员 周边 捐助

Windows下redis服务端MSOpenTech缓存按目录存储用哪个命令

0
悬赏园豆:100 [已解决问题] 解决于 2016-08-10 13:03

Windows下redis使用的两个问题:
1.本意我的key是存用户ID,value存token,但是接口上验证token,我得先判断token有没有,redis提供了根据键查找是否存 在,所以我只能把token存成key,但是token太长了,怕存成键有问题,可读性也差,关键时候登录服务器想根据用户ID看某个用户的token也 不方便找。想请教下大家这里怎么设计的?redis有没有提供了方法查是否存在某个value?我现在根据键查找代码:

public static bool KeyExists(string key, int db = -1)
{
    try
    {
        using (var client = ConnectionMultiplexer.Connect(_conn))
        {
            return Manager.GetDatabase(db).KeyExists(key);
        }
    }
    catch (Exception)
    {
        return false;
    }
}

2.redis默认16个库,按照库存缓存已经搞出来了,如图:

但是一个库下,按照目录存缓存,始终没找到什么命令,看网友的这个图:

想请教大家这里用什么命令按照目录存缓存,dos命令或者C# RedisHelper都可以,麻烦知道的提供下思路

oppoic的主页 oppoic | 小虾三级 | 园豆:770
提问于:2016-08-10 10:49
< >
分享
最佳答案
0

如果想按照目录存,在Key前加上前辍就可以,记得用冒号分开,如你想把一些键放到group这个目录下,就在Key前加上group:key,这样就可以

收获园豆:100
韩天伟 | 小虾三级 |园豆:697 | 2016-08-10 10:55

给你一个完整的RedisHelper

    /// <summary>
    /// Redis类
    /// </summary>
    public class CacheHelper
    {
        private static ConnectionMultiplexer RedisConnection;
        private static IDatabase Database;

        /// <summary>
        /// 静态构造函数
        /// </summary>
        static CacheHelper()
        {
            if (CacheConfig.ConfigInfo.CacheEnable)
            {
                if (CacheHelper.RedisConnection == null)
                {
                    CacheHelper.RedisConnection = ConnectionMultiplexer.Connect(string.Format("{0},connectTimeout=15000,syncTimeout=15000", CacheConfig.ConfigInfo.RedisAddress), null);
                }
                if (CacheHelper.Database == null)
                {
                    CacheHelper.Database = CacheHelper.RedisConnection.GetDatabase(0, null);
                }
            }
        }
        /// <summary>
        /// 获取缓存值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <returns></returns>
        public static T Get<T>(string key)
        {
            if (!CacheConfig.ConfigInfo.CacheEnable)
            {
                return default(T);
            }
            RedisValue redisValue = CacheHelper.Database.StringGet(CacheHelper.GetLocalizedKey(key), 0);
            if (string.IsNullOrEmpty(redisValue))
            {
                return default(T);
            }
            return JsonConvert.DeserializeObject<T>(redisValue);
        }

        public static void Set<T>(string key, T value)
        {
            if (CacheConfig.ConfigInfo.CacheEnable)
            {
                string text = JsonConvert.SerializeObject(value);
                CacheHelper.Database.StringSet(CacheHelper.GetLocalizedKey(key), text, null, 0, 0);
            }
        }

        public static void Set<T>(string key, T value, TimeSpan validFor)
        {
            if (CacheConfig.ConfigInfo.CacheEnable)
            {
                string text = JsonConvert.SerializeObject(value);
                CacheHelper.Database.StringSet(CacheHelper.GetLocalizedKey(key), text, new TimeSpan?(validFor), 0, 0);
            }
        }

        public static void ListRightPush<T>(string key, T value)
        {
            if (CacheConfig.ConfigInfo.CacheEnable)
            {
                string text = JsonConvert.SerializeObject(value);
                CacheHelper.Database.ListRightPush(CacheHelper.GetLocalizedKey(key), text, 0, 0);
            }
        }

        public static T ListLeftPop<T>(string key)
        {
            if (!CacheConfig.ConfigInfo.CacheEnable)
            {
                return default(T);
            }
            RedisValue redisValue = CacheHelper.Database.ListLeftPop(CacheHelper.GetLocalizedKey(key), 0);
            if (string.IsNullOrEmpty(redisValue))
            {
                return default(T);
            }
            return JsonConvert.DeserializeObject<T>(redisValue);
        }

        public static void Remove(string key)
        {
            if (CacheConfig.ConfigInfo.CacheEnable)
            {
                CacheHelper.Database.KeyDelete(CacheHelper.GetLocalizedKey(key), 0);
            }
        }

        public static void RemoveAll()
        {
            if (CacheConfig.ConfigInfo.CacheEnable)
            {
                CacheHelper.Database.KeyDeleteWithPrefix(CacheHelper.GetLocalizedKey("*"));
            }
        }

        private static string GetLocalizedKey(string key)
        {
            return CacheConfig.ConfigInfo.CachePrefix + key;
        }
    }

    public static class RedisDatabaseExtensions
    {

        public static void KeyDeleteWithPrefix(this IDatabase database, string prefix)
        {
            if (database == null)
            {
                throw new ArgumentException("Database cannot be null", "database");
            }

            if (string.IsNullOrWhiteSpace(prefix))
            {
                throw new ArgumentException("Prefix cannot be empty", "database");
            }

            database.ScriptEvaluate(@"
                local keys = redis.call('keys', ARGV[1]) 
                for i=1,#keys,5000 do 
                redis.call('del', unpack(keys, i, math.min(i+4999, #keys)))
                end", values: new RedisValue[] { prefix });
        }

        public static int KeyCount(this IDatabase database, string prefix)
        {
            if (database == null)
            {
                throw new ArgumentException("Database cannot be null", "database");
            }

            if (string.IsNullOrWhiteSpace(prefix))
            {
                throw new ArgumentException("Prefix cannot be empty", "database");
            }

            var retVal = database.ScriptEvaluate("return table.getn(redis.call('keys', ARGV[1]))", values: new RedisValue[] { prefix });

            if (retVal.IsNull)
            {
                return 0;
            }

            return (int)retVal;
        }
    }

 

 

韩天伟 | 园豆:697 (小虾三级) | 2016-08-10 11:17

@韩天伟: 可以分目录了,感谢!但是另一个问题来了:目录下面的键都是以目录:键的形式存的,那么程序封装的时候就得给键签名拼上目录:要存的键,根据key读取的时候也要手动拼上目录:键  这样是常规做法么?

oppoic | 园豆:770 (小虾三级) | 2016-08-10 12:05

@心态要好: 一般不会每次手动拼,可以写个公用方法做这件事情,读取和写入时会用这个方法转换一下,把用哪个前辍来拼接时在这个方法里面判断

如:

 private static string GetLocalizedKey(string key)
        {
            return CacheConfig.ConfigInfo.CachePrefix + key;
        }
韩天伟 | 园豆:697 (小虾三级) | 2016-08-10 12:36

@韩天伟: 感谢,很快解决了问题,悬赏全部给你。对了,兄弟是否可以分享下项目里怎么使用redis的?我现在是16个库,每个库对应服务器上的一个项目,一个项目里不同模块用到缓存用目录区分。

oppoic | 园豆:770 (小虾三级) | 2016-08-10 13:05
其他回答(1)
0

Key一般都有规则吧?

顾晓北 | 园豆:10898 (专家六级) | 2016-08-10 10:59

Key的规则一般根据项目自已掌握

支持(0) 反对(0) 韩天伟 | 园豆:697 (小虾三级) | 2016-08-10 11:12

@韩天伟: 这种直接把用户ID当key的就是坑.

支持(0) 反对(0) 吴瑞祥 | 园豆:29449 (高人七级) | 2016-08-10 11:44

@吴瑞祥: 每个项目或每个人用时都有他自已的规则,只要不重复就没什么问题,如果一个团队要做最好封装相应的方法,以免键重复或数据重复存储

支持(0) 反对(0) 韩天伟 | 园豆:697 (小虾三级) | 2016-08-10 12:38
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册