您现在的位置是:主页>文章>Redis入门(.net实践) 网站首页

Redis入门(.net实践)

简介:

Redis 是一个速度非常快的非关系型数据库(non-relational database),它可以存储键(key)与五种不同类型的值(value)之间的映射(mapping),包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。

部署:

windows版本下载地址:https://github.com/MSOpenTech/redis/releases

本例中下载了最新的版本,如下图:

这里我把zip文件解压到c:/redis文件夹

命令:

启动redis: redis-server redis.windows.conf (关闭窗口redis服务即关闭)

安装redis服务开机自启动:redis-server --service-install redis.windows-service.conf

启动redis: redis-server --service-start

停止命令:redis-server --service-stop

卸载命令:redis-server --service-uninstall


下载数据可视化工具:https://redisdesktop.com/download 选择windows版本, 直接安装即可。


注意事项

修改Redis端口及密码的配置在文件redis.windows-service.conf中

修改端口,如图:

修改密码,如图:

配置完成后,需要重新启动redis才可生效

实践:Redis公共类库参考 (需要NuGet添加StackExchange.Redis 和 protobuf-net 引用)

namespace NetRedis {
    public abstract class RedisBase : IDisposable {
        private ConnectionMultiplexer redis;
        private Int32 db;
        public RedisBase(String redisConnString, Int32 dbNum) {
            redis = ConnectionMultiplexer.Connect(redisConnString);
            db = dbNum;
        }

        public RedisBase(ConfigurationOptions redisConnString, Int32 dbNum) {
            redis = ConnectionMultiplexer.Connect(redisConnString);
            db = dbNum;
        }
        #region -- Hash --

        /// 
        /// 根据key获取field
        /// 
        private String GetField(String key, String fieldId) 
        {
            String fieldFormat = "{0}_id:{1}";

            return String.Format(fieldFormat, key , fieldId);
        }

        /// 
        ///  批量删除
        /// 
        public Int32 HashDelete(String key, List delIds) {
            if (delIds == null || delIds.Count <= 0)
                return 1;

            var dataBase = redis.GetDatabase(db);

            Int32 count = delIds.Count;

            RedisValue[] delValues = new RedisValue[count];

            for (Int32 i = 0; i < count; i++) {
                delValues[i] = GetField(key, delIds[i].ToString());
            }

            return dataBase.HashDelete(key, delValues) >= 0 ? 1 : 0;
        }

        /// 
        /// 比较删除
        /// 
        /// 
        /// 
        /// 
        public Int32 HashCompareDel(String key, List comIds) {

            if (comIds == null || comIds.Count <= 0)
                return 1;

            var dataBase = redis.GetDatabase(db);

       
            //  如果不存在这个set
            if (!dataBase.KeyExists(key)) {
                //  直接设置为当前set
                return SetAdd(key, comIds);

            }
            else   //  存在时比较删除
            {
                String comSetKey = key + "_new";

                SetAdd(comSetKey, comIds);

                // 取出原来set里有,但是新set里没有的值
                RedisValue[] diffValue = dataBase.SetCombine(SetOperation.Difference, key, comSetKey);

                if (diffValue != null && diffValue.Length > 0) {
                    //  转化为hash的filed
                    for (Int32 i = 0; i < diffValue.Length; i++) {
                        diffValue[i] = GetField(key, diffValue[i]);
                    }

                    //  删除
                    if (dataBase.HashDelete(key, diffValue) > 0) {
                        dataBase.KeyRename(comSetKey, key);
                        return 1;
                    }
                    else {
                        return 0;
                    }
                }
                else  //  如果前后结果一致,没有需要删除的,删除比较Set
                {
                    dataBase.KeyDelete(comSetKey);
                    return 1;
                }
            }


        }

        /// 
        /// 设置集合
        /// 
        public Int32 SetAdd(String key, List listIds) {

            var dataBase = redis.GetDatabase(db);

            Int32 count = listIds.Count;

            RedisValue[] setValues = new RedisValue[count];

            for (Int32 i = 0; i < count; i++) {
                setValues[i] = listIds[i];
            }

            return dataBase.SetAdd(key, setValues) > 0 ? 1 : 0;

        }

        /// 
        /// 更新数据
        /// 
        public Int32 HashSet(String key, List listInstance, Func getModelId) {
            if (listInstance == null || listInstance.Count <= 0)
                return 1;

            var dataBase = redis.GetDatabase(db);

            Int32 count = listInstance.Count;

            HashEntry[] upValues = new HashEntry[count];

            for (Int32 i = 0; i < count; i++) {
                var item = listInstance[i];

                using (MemoryStream ms = new MemoryStream()) {
                    ProtoBuf.Serializer.Serialize(ms, item);

                    upValues[i] = new HashEntry(GetField(key, getModelId(item)), ms.ToArray());
                }
            }

            dataBase.HashSet(key, upValues);

            return 1;

        }

        /// 
        /// 分批更新
        /// 
        public Int32 BatchHashSet(String key, List listInstance, Func getModelId, Int32 batchCount) {
            if (listInstance == null || listInstance.Count <= 0)
                return 1;

            Int32 count = listInstance.Count;

            if (count <= batchCount)
                return this.HashSet(key, listInstance, getModelId);

            var dataBase = redis.GetDatabase(db);

            Int32 batch = count / batchCount;

            batch = count % batchCount == 0 ? batch : batch + 1;

            for (Int32 i = 0; i < batch; i++) {
                Int32 thisCount = (i == batch - 1) ? count % batchCount : batchCount;
                HashEntry[] upValues = new HashEntry[thisCount];

                for (Int32 j = 0; j < thisCount; j++) {
                    var item = listInstance[i * batchCount + j];

                    using (MemoryStream ms = new MemoryStream()) {
                        ProtoBuf.Serializer.Serialize(ms, item);

                        upValues[j] = new HashEntry(GetField(key, getModelId(item)), ms.ToArray());
                    }
                }

                dataBase.HashSet(key, upValues);

            }

            return 1;

        }

        /// 
        /// 获取列表
        /// 
        public List HashGet(String key, List listFieldId) {
            List listResult = new List();

            if (listFieldId == null || listFieldId.Count < 0) {
                return listResult;
            }

            var dataBase = redis.GetDatabase(db);

            Int32 count = listFieldId.Count;

            //  转化为Redis数据结构
            RedisValue[] filedValue = new RedisValue[count];
            for (Int32 i = 0; i < count; i++) {
                filedValue[i] = GetField(key, listFieldId[i].ToString());
            }

            // 取出结果集
            RedisValue[] arrResult = dataBase.HashGet(key, filedValue);

            // 将Redis结果转为化所需类型的列表
            if (arrResult != null && arrResult.Length > 0) {
                foreach (RedisValue item in arrResult) {
                    if (!item.IsNullOrEmpty) {
                        using (MemoryStream ms = new MemoryStream((byte[])item)) {
                            listResult.Add(ProtoBuf.Serializer.Deserialize(ms));
                        }
                    }
                }
            }
            return listResult;
        }

        /// 
        /// 获取单个结果
        /// 
        public T HashGet(String key, Int32 fieldId) {
            if (fieldId > 0) {
                var dataBase = redis.GetDatabase(db);

                // 取出结果
                RedisValue result = dataBase.HashGet(key, GetField(key, fieldId.ToString()));

                // 将Redis结果转为化所需类型的列表
                if (!result.IsNullOrEmpty) {
                    using (MemoryStream ms = new MemoryStream((byte[])result)) {
                        return ProtoBuf.Serializer.Deserialize(ms);
                    }
                }
            }
            return default(T);
        }

        
        #endregion


        #region -- RedisValue --
        public RedisValue Get(string key) {
            var dataBase = redis.GetDatabase(db);

            if (dataBase.KeyExists(key)) {
                return dataBase.StringGet(key);
            }
            return default(RedisValue);
        }

        public bool Set(string key, string value, int expireMinutes = 0) {
            var dataBase = redis.GetDatabase(db);
            if (expireMinutes > 0) {
                return dataBase.StringSet(key, value, TimeSpan.FromMinutes(expireMinutes));
            }
            else {
                return dataBase.StringSet(key, value);
            }
        }

        public bool Remove(string key) {
            var dataBase = redis.GetDatabase(db);
            return dataBase.KeyDelete(key);
        }
        #endregion

        #region -- Item --
        ///  
        /// 设置单体 
        ///  
        public void ItemSet(string key, T t, int expireMinutes = 0) {
            var dataBase = redis.GetDatabase(db);
            using (MemoryStream ms = new MemoryStream()) {
                ProtoBuf.Serializer.Serialize(ms, t);

                RedisValue upValue = ms.ToArray();
                dataBase.StringSet(key, upValue);
            }
        }

        ///  
        /// 获取单体 
        ///  
        public T ItemGet(string key) where T : class {
            var dataBase = redis.GetDatabase(db);

            if (dataBase.KeyExists(key)) {
                var value = dataBase.StringGet(key);
                using (MemoryStream ms = new MemoryStream((byte[])value)) {
                    return ProtoBuf.Serializer.Deserialize(ms);
                }
            }
            else {
                return default(T);
            }
        }
        #endregion

        public void Dispose() {
            if (redis != null)
                redis.Dispose();
        }
    }
}
namespace NetRedis {
    public class RedisUtils:RedisBase
    {
        #region 单例
        private static RedisUtils _instance = null;

        public static RedisUtils Instance
        {
            get
            {
                if(_instance!=null) {
                    return _instance;
                }
                else {
                    lock (_obj) 
                    {
                        if (_instance == null) {
                            _instance = new RedisUtils();
                            return _instance;
                        }
                        else {
                            return _instance;
                        }
                    }
                }
            }
        }
        #endregion

        private static int _defaultDataBase = 0;
        private static object _obj = new object();
        private static object _obj2 = new object();


        private static ConfigurationOptions _configurationOptions;
        private static ConfigurationOptions ConfigurationOptions
        {
            get
            {
                if (_configurationOptions != null) {
                    return _configurationOptions;
                }
                else {
                    lock (_obj2) {
                        if (_configurationOptions == null) {
                            _configurationOptions = GetConnection();
                            return _configurationOptions;
                        }
                        else {
                            return _configurationOptions;
                        }
                    }
                }
            }
        }

        private RedisUtils() : base(ConfigurationOptions, _defaultDataBase) {

        }
        //private RedisUtils(string connection,int dbNum) : base(connection, dbNum) {

        //}

        private static ConfigurationOptions GetConnection() {
            var redisSettingList = RedisSetting.GetRedisReadWriteHostsSettingList();
            var configurationOptions = new ConfigurationOptions {
                KeepAlive = 180,
                Password = redisSettingList[0].Password,
                AllowAdmin = true
            };

            redisSettingList.ForEach(p => {
                configurationOptions.EndPoints.Add(p.Hosts, p.Port);
            });
            return configurationOptions;
        }
    }
}

参考资料:

http://www.cnblogs.com/yangecnu/p/Introduct-Redis-in-DotNET.html

http://keenwon.com/1275.html

http://www.cnblogs.com/forcertain/p/4840803.html

https://github.com/fengzhbo/MySampleCode/issues/2


如果我的文章对你有帮助,就点一下推荐吧.(*^__^*)

Demo下载

上一篇:ELK 监控搭建;

下一篇:压力测试工具 Jmeter;

Top