zoukankan      html  css  js  c++  java
  • Redis缓存相关

    Redis缓存服务搭建及实现数据读写

    RedisHelper帮助类

    /// <summary>
    /// Redis 帮助类文件
    /// </summary>
    public class RedisHelper : IDisposable {
        /// <summary>
        /// 针对Log4net的实例
        /// </summary>
        private static readonly ILog Logger = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
    
        /// <summary>
        /// The seconds time out.
        /// 默认缓存过期时间单位秒
        /// </summary>
        private int secondsTimeOut = 24 * 60 * 60;
    
        /// <summary>
        /// 给某个键对应的数据设置过期时间
        /// </summary>
        /// <param name="key"></param>
        /// <param name="seconds">过期时间</param>
        public void Expire(string key, int seconds) {
            try {
                this.redis.Expire(key, seconds);
            } catch(Exception ex) {
                var message = string.Format("设置过期时间出错");
                Logger.Error(message, ex);
            }
        }
    
        /// <summary>
        /// 释放资源
        /// </summary>
        public void Dispose() {
            if(this.redis != null) {
                this.redis.Dispose();
                this.redis = null;
            }
    
            GC.Collect();
        }
    
        private IEnumerable<string> SplitString(string strSource, string split) {
            return strSource.Split(split.ToArray());
        }
    
        /// <summary>
        /// 设置单个实体
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key">缓存建</param>
        /// <param name="t">缓存值</param>
        /// <param name="timeout">过期时间,单位秒,-1:不过期,0:默认过期时间:一天</param>
        public bool Set<T>(string key, T t, int timeout = -1) {
            try {
                if(timeout >= 0) {
                    if(timeout > 0) {
                        this.secondsTimeOut = timeout;
                    }
    
                    var dtTimeOut = DateTime.Now.AddSeconds(this.secondsTimeOut);
                    return this.redis.Set(key, t, dtTimeOut);
                }
    
                return this.redis.Set(key, t);
            } catch(Exception ex) {
                string message = string.Format("设置Redis缓存出错");
                Logger.Error(message, ex);
            }
        }
    
        /// <summary>
        ///     获取单个实体
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="key">键值</param>
        public T Get<T>(string key) {
            try {
                return this.redis.Get<T>(key);
            } catch(Exception ex) {
                string message = string.Format("获取Redis缓存出错");
                Logger.Error(message, ex);
            }
        }
    
        /// <summary>
        ///     删除
        /// </summary>
        /// <param name="key">键值</param>
        public bool Remove(string key) {
            try {
                return this.redis.Remove(key);
            } catch(Exception ex) {
                string message = string.Format("删除Redis缓存出错");
                Logger.Error(message, ex);
            }
        }
    
        /// <summary>
        /// 删除所有
        /// </summary>
        public void RemoveAll() {
            var keyList = this.redis.GetAllKeys();
            this.redis.RemoveAll(keyList);
        }
    
        /// <summary>
        /// 获取Redis的所有key
        /// </summary>
        public List<string> ListKey() {
            return this.redis.GetAllKeys();
        }
    
        /// <summary>
        ///     添加一个对象
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="key"></param>
        /// <param name="t"></param>
        /// <param name="timeout">过期时间(单位为秒) -1:不过期,0:默认过期时间 一天</param>
        public bool Add<T>(string key, T t, int timeout = -1) {
            try {
                if(timeout >= 0) {
                    if(timeout > 0) {
                        this.secondsTimeOut = timeout;
                    }
    
                    this.redis.Expire(key, this.secondsTimeOut);
                }
    
                return this.redis.Add(key, t);
            } catch(Exception ex) {
                string message = string.Format("添加Redis缓存出错");
                Logger.Error(message, ex);
            }
        }
    
        /// <summary>
        /// 根据IEnumerable数据添加链表
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="key"></param>
        /// <param name="values"></param>
        /// <param name="timeout">过期时间 -1:不过期,0:默认过期时间:一天</param>
        public void AddList<T>(string key, IEnumerable<T> values, int timeout = -1) {
            try {
                IRedisTypedClient<T> iredisClient = this.redis.As<T>();
                IRedisList<T> redisList = iredisClient.Lists[key];
                redisList.AddRange(values);
                if(timeout > 0) {
                    if(timeout > 0) {
                        this.secondsTimeOut = timeout;
                    }
    
                    this.redis.Expire(key, this.secondsTimeOut);
                }
    
                iredisClient.Save();
            } catch(Exception ex) {
                string message = string.Format("添加链表出错");
                Logger.Error(message, ex);
            }
        }
    
        /// <summary>
        /// 添加单个实体到链表中
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="key"></param>
        /// <param name="Item"></param>
        /// <param name="timeout">过期时间 -1:不过期,0:默认过期时间:一天</param>
        public void AddEntityToList<T>(string key, T Item, int timeout = -1) {
            try {
                IRedisTypedClient<T> iredisClient = redis.As<T>();
                IRedisList<T> redisList = iredisClient.Lists[key];
                redisList.Add(Item);
                iredisClient.Save();
                if(timeout >= 0) {
                    if(timeout > 0) {
                        this.secondsTimeOut = timeout;
                    }
    
                    this.redis.Expire(key, this.secondsTimeOut);
                }
            } catch(Exception ex) {
                string message = string.Format("添加单个的实体到链表中出错");
                Logger.Error(message, ex);
            }
        }
    
        /// <summary>
        /// 获取链表
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="key"></param>
        public IEnumerable<T> GetList<T>(string key) {
            try {
                IRedisTypedClient<T> iredisClient = redis.As<T>();
                return iredisClient.Lists[key];
            } catch(Exception ex) {
                string message = string.Format("获取链表出错");
                Logger.Error(message, ex);
            }
        }
    
        /// <summary>
        /// 在链表中删除单个实体
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="key"></param>
        public void RemoveEntityFromList<T>(string key, T t) {
            try {
                IRedisTypedClient<T> iredisClient = this.redis.As<T>();
                IRedisList<T> redisList = iredisClient.Lists[key];
                redisList.RemoveValue(t);
                iredisClient.Save();
            } catch(Exception ex) {
                string message = string.Format("删除链表中的单个实体出错");
                Logger.Error(message, ex);
            }
        }
    
        /// <summary>
        /// 根据key移除整个链表
        /// </summary>
        /// <param name="key"></param>
        public void RemoveAllList<T>(string key) {
            try {
                IRedisTypedClient<T> iredisClient = this.redis.As<T>();
                IRedisList<T> redisList = iredisClient.Lists[key];
                redisList.RemoveAll();
                iredisClient.Save();
            } catch(Exception ex) {
                string message = string.Format("删除链表集合");
                Logger.Error(message, ex);
            }
        }
    }本文出自GitHub开源网站
    View Code

     =================================

    asp.net mvc 用Redis实现分布式集群共享Session

    1、这两天研究Redis搞分布式session问题,网上找的资料都是用ServiceStack.Redis来实现的,但是在做性能测试的时候 发现最新的v4版本有限制每小时候最多请求6000次,因为官网开始商业化要收费了,好坑爹的说,还好我前期弄了个性能测试列子,不然上线以后出问题那就 麻烦了。后面找了个NServiceKit.Redis(好像就是ServiceStack.Redis的v3版本)来替代v4的收费版。

    2、解决方案是 Redis+cookie方式实现记录用户登录状态

         cookie:存放用户的ID,这个ID是经过加密的,并且后台可以通过密钥解密。

         Redis:key/value 方式存储,key存放比如:user_1。  value存放用户实体对象。

    3、先安装一个Redis,windows的版本在本地进行测试,后期上线更换linux系统的Redis替换一下ip就可以了。

    4、添加一个Session管理类

    public class SessionHelper
        {
            private const int secondsTimeOut = 60 * 20;  //默认过期时间20分钟  单位秒
    
    
            public RedisHelper Redis = new RedisHelper(false);
            public LoginUserInfo this[string key]
            {
                get
                {
                    string webCookie = WebHelper.GetCookie(key);
                    if (webCookie == "")
                    {
                        return null;
                    }
                    key = key + "_" + SecureHelper.AESDecrypt(webCookie);
    
                    //距离过期时间还有多少秒
                    long l = Redis.TTL(key);
                    if (l >= 0)
                    {
                        Redis.Expire(key, secondsTimeOut);
                    }
                    
                    return Redis.Get<LoginUserInfo>(key);
                }
                set
                {
                    SetSession(key, value);
                }
            }
            public void SetSession(string key, LoginUserInfo value)
            {
                if (string.IsNullOrWhiteSpace(key))
                {
                    throw new Exception("Key is Null or Epmty");
                }
                WebHelper.SetCookie(key, SecureHelper.AESEncrypt(value.ID.ToString()));
                key = key + "_" + value.ID;
                Redis.Set<LoginUserInfo>(key, value, secondsTimeOut);
            }
    
            /// <summary>
            /// 移除Session
            /// </summary>
            /// <param name="key"></param>
            /// <returns></returns>
            public bool Remove(string key)
            {
                var rs = Redis.Remove(key + "_" + SecureHelper.AESDecrypt(WebHelper.GetCookie(key)));
                WebHelper.DeleteCookie(key);
                return rs;
            }
                 
        }
    SessionHelper

    5、Redis操作类

    public class RedisHelper : IDisposable
        {
           private RedisClient Redis = new RedisClient("127.0.0.1", 6379);
            //缓存池
            PooledRedisClientManager prcm = new PooledRedisClientManager();
    
            //默认缓存过期时间单位秒
            public int secondsTimeOut = 20 * 60;
    
            /// <summary>
            /// 缓冲池
            /// </summary>
            /// <param name="readWriteHosts"></param>
            /// <param name="readOnlyHosts"></param>
            /// <returns></returns>
            public static PooledRedisClientManager CreateManager(string[] readWriteHosts, string[] readOnlyHosts)
            {
                return new PooledRedisClientManager(readWriteHosts, readOnlyHosts,
                    new RedisClientManagerConfig
                    {
                        MaxWritePoolSize = readWriteHosts.Length * 5,
                        MaxReadPoolSize = readOnlyHosts.Length * 5,
                        AutoStart = true,
                    }); 
            }
            /// <summary>
            /// 构造函数
            /// </summary>
            /// <param name="OpenPooledRedis">是否开启缓冲池</param>
            public RedisHelper(bool OpenPooledRedis = false)
            {
    
                if (OpenPooledRedis)
                {
                    prcm = CreateManager(new string[] { "127.0.0.1:6379" }, new string[] { "127.0.0.1:6379" });
                    Redis = prcm.GetClient() as RedisClient;
                }
            }
            /// <summary>
            /// 距离过期时间还有多少秒
            /// </summary>
            /// <param name="key"></param>
            /// <returns></returns>
            public long TTL(string key)
            {
                return Redis.Ttl(key);
            }
            /// <summary>
            /// 设置过期时间
            /// </summary>
            /// <param name="key"></param>
            /// <param name="timeout"></param>
            public void Expire(string key,int timeout = 0)
            {
                if (timeout >= 0)
                {
                    if (timeout > 0)
                    {
                        secondsTimeOut = timeout;
                    }
                    Redis.Expire(key, secondsTimeOut);
                }
            }
    
            #region Key/Value存储
            /// <summary>
            /// 设置缓存
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="key">缓存建</param>
            /// <param name="t">缓存值</param>
            /// <param name="timeout">过期时间,单位秒,-1:不过期,0:默认过期时间</param>
            /// <returns></returns>
            public bool Set<T>(string key, T t, int timeout = 0)
            {
                Redis.Set<T>(key, t);
                if (timeout >= 0)
                {
                    if (timeout > 0)
                    {
                        secondsTimeOut = timeout;
                    }
                    Redis.Expire(key, secondsTimeOut);
                }
                return true;
                
            }
            /// <summary>
            /// 获取
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="key"></param>
            /// <returns></returns>
            public T Get<T>(string key)
            {
                return Redis.Get<T>(key);
            }
            /// <summary>
            /// 删除
            /// </summary>
            /// <param name="key"></param>
            /// <returns></returns>
            public bool Remove(string key)
            {
                return Redis.Remove(key);
            }
            #endregion
    
            //释放资源
            public void Dispose()
            {
                if (Redis != null)
                {
                    Redis.Dispose();
                    Redis = null;
                }
                GC.Collect();
    
            }
        }
    RedisHelper

    用C#封装的ServiceStack.redis操作类

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using ServiceStack.Redis;
    namespace TestRedis
    {
        class RedisHelper:IDisposable
        {
            /*copyright@2013 All Rights Reserved
             * Author:Mars
             * Date:2013.08.27
             * QQ:258248340
             * servicestack.redis为github中的开源项目
             * redis是一个典型的k/v型数据库
             * redis共支持五种类型的数据 string,list,hash,set,sortedset
             * 
             * string是最简单的字符串类型
             * 
             * list是字符串列表,其内部是用双向链表实现的,因此在获取/设置数据时可以支持正负索引
             * 也可以将其当做堆栈结构使用
             * 
             * hash类型是一种字典结构,也是最接近RDBMS的数据类型,其存储了字段和字段值的映射,但字段值只能是
             * 字符串类型,散列类型适合存储对象,建议使用对象类别和ID构成键名,使用字段表示对象属性,字
             * 段值存储属性值,例如:car:2 price 500 ,car:2  color black,用redis命令设置散列时,命令格式
             * 如下:HSET key field value,即key,字段名,字段值
             * 
             * set是一种集合类型,redis中可以对集合进行交集,并集和互斥运算
             *           
             * sorted set是在集合的基础上为每个元素关联了一个“分数”,我们能够
             * 获得分数最高的前N个元素,获得指定分数范围内的元素,元素是不同的,但是"分数"可以是相同的
             * set是用散列表和跳跃表实现的,获取数据的速度平均为o(log(N))
             * 
             * 需要注意的是,redis所有数据类型都不支持嵌套
             * redis中一般不区分插入和更新操作,只是命令的返回值不同
             * 在插入key时,如果不存在,将会自动创建
             * 
             * 在实际生产环境中,由于多线程并发的关系,建议使用连接池,本类只是用于测试简单的数据类型
             */
    
            /*
             * 以下方法为基本的设置数据和取数据
             */
            private static RedisClient redisCli = null;
            /// <summary>
            /// 建立redis长连接
            /// </summary>
            /// 将此处的IP换为自己的redis实例IP,如果设有密码,第三个参数为密码,string 类型
            public static void CreateClient(string hostIP,int port,string keyword)
            {
                if (redisCli == null)
                {
                    redisCli = new RedisClient(hostIP, port, keyword);
                }
     
            }
            public static void CreateClient(string hostIP, int port)
            {
                if (redisCli == null)
                {
                    redisCli = new RedisClient(hostIP, port);
                 }
     
            }
            //private static RedisClient redisCli = new RedisClient("192.168.101.165", 6379, "123456");
            /// <summary>
            /// 获取key,返回string格式
            /// </summary>
            /// <param name="key"></param>
            /// <returns></returns>
            public static string getValueString(string key)
            {
            
                    string value = redisCli.GetValue(key);
                    return value;
               
              
            }
            /// <summary>
            /// 获取key,返回byte[]格式
            /// </summary>
            /// <param name="key"></param>
            /// <returns></returns>
            public static byte[] getValueByte(string key)
            {
                byte[] value = redisCli.Get(key);
                return value;
            }
            /// <summary>
            /// 获得某个hash型key下的所有字段
            /// </summary>
            /// <param name="hashId"></param>
            /// <returns></returns>
            public static List<string> GetHashFields(string hashId)
            {
                List<string> hashFields = redisCli.GetHashKeys(hashId);
                return hashFields;
            }
            /// <summary>
            /// 获得某个hash型key下的所有值
            /// </summary>
            /// <param name="hashId"></param>
            /// <returns></returns>
            public static List<string> GetHashValues(string hashId)
            {
                List<string> hashValues = redisCli.GetHashKeys(hashId);
                return hashValues;
            }
            /// <summary>
            /// 获得hash型key某个字段的值
            /// </summary>
            /// <param name="key"></param>
            /// <param name="field"></param>
            public static string GetHashField(string key, string field)
            {
                string value = redisCli.GetValueFromHash(key, field);
                return value;
            }
            /// <summary>
            /// 设置hash型key某个字段的值
            /// </summary>
            /// <param name="key"></param>
            /// <param name="field"></param>
            /// <param name="value"></param>
            public static void SetHashField(string key, string field, string value)
            {
                redisCli.SetEntryInHash(key, field, value);
            }
            /// <summary>
            ///使某个字段增加
            /// </summary>
            /// <param name="key"></param>
            /// <param name="field"></param>
            /// <returns></returns>
            public static void SetHashIncr(string key, string field, long incre)
            {
                redisCli.IncrementValueInHash(key, field, incre);
    
            }
            /// <summary>
            /// 向list类型数据添加成员,向列表底部(右侧)添加
            /// </summary>
            /// <param name="Item"></param>
            /// <param name="list"></param>
            public static void AddItemToListRight(string list, string item)
            {
                redisCli.AddItemToList(list, item);
            }
            /// <summary>
            /// 向list类型数据添加成员,向列表顶部(左侧)添加
            /// </summary>
            /// <param name="list"></param>
            /// <param name="item"></param>
            public static void AddItemToListLeft(string list, string item)
            {
                redisCli.LPush(list, Encoding.Default.GetBytes(item));
            }
            /// <summary>
            /// 从list类型数据读取所有成员
            /// </summary>
            public static List<string> GetAllItems(string list)
            {
                List<string> listMembers = redisCli.GetAllItemsFromList(list);
                return listMembers;
            }
            /// <summary>
            /// 从list类型数据指定索引处获取数据,支持正索引和负索引
            /// </summary>
            /// <param name="list"></param>
            /// <returns></returns>
            public static string GetItemFromList(string list, int index)
            {
                string item = redisCli.GetItemFromList(list, index);
                return item;
            }
            /// <summary>
            /// 向列表底部(右侧)批量添加数据
            /// </summary>
            /// <param name="list"></param>
            /// <param name="values"></param>
            public static void GetRangeToList(string list, List<string> values)
            {
                redisCli.AddRangeToList(list, values);
            }
            /// <summary>
            /// 向集合中添加数据
            /// </summary>
            /// <param name="item"></param>
            /// <param name="set"></param>
            public static void GetItemToSet(string item, string set)
            {
                redisCli.AddItemToSet(item, set);
            }
            /// <summary>
            /// 获得集合中所有数据
            /// </summary>
            /// <param name="set"></param>
            /// <returns></returns>
            public static HashSet<string> GetAllItemsFromSet(string set)
            {
                HashSet<string> items = redisCli.GetAllItemsFromSet(set);
                return items;
            }
            /// <summary>
            /// 获取fromSet集合和其他集合不同的数据
            /// </summary>
            /// <param name="fromSet"></param>
            /// <param name="toSet"></param>
            /// <returns></returns>
            public static HashSet<string> GetSetDiff(string fromSet, params string[] toSet)
            {
                HashSet<string> diff = redisCli.GetDifferencesFromSet(fromSet, toSet);
                return diff;
            }
            /// <summary>
            /// 获得所有集合的并集
            /// </summary>
            /// <param name="set"></param>
            /// <returns></returns>
            public static HashSet<string> GetSetUnion(params string[] set)
            {
                HashSet<string> union = redisCli.GetUnionFromSets(set);
                return union;
            }
            /// <summary>
            /// 获得所有集合的交集
            /// </summary>
            /// <param name="set"></param>
            /// <returns></returns>
            public static HashSet<string> GetSetInter(params string[] set)
            {
                HashSet<string> inter = redisCli.GetIntersectFromSets(set);
                return inter;
            }
            /// <summary>
            /// 向有序集合中添加元素
            /// </summary>
            /// <param name="set"></param>
            /// <param name="value"></param>
            /// <param name="score"></param>
            public static void AddItemToSortedSet(string set,string value,long score)
            {
                redisCli.AddItemToSortedSet(set,value,score);
            }
            /// <summary>
            /// 获得某个值在有序集合中的排名,按分数的降序排列
            /// </summary>
            /// <param name="set"></param>
            /// <param name="value"></param>
            /// <returns></returns>
            public static int GetItemIndexInSortedSetDesc(string set, string value)
            {
                int index = redisCli.GetItemIndexInSortedSetDesc(set, value);
                return index;
            }
            /// <summary>
            /// 获得某个值在有序集合中的排名,按分数的升序排列
            /// </summary>
            /// <param name="set"></param>
            /// <param name="value"></param>
            /// <returns></returns>
            public static int GetItemIndexInSortedSet(string set, string value)
            {
                int index = redisCli.GetItemIndexInSortedSet(set, value);
                return index;
            }
            /// <summary>
            /// 获得有序集合中某个值得分数
            /// </summary>
            /// <param name="set"></param>
            /// <param name="value"></param>
            /// <returns></returns>
            public static double GetItemScoreInSortedSet(string set, string value)
            {
                double score = redisCli.GetItemScoreInSortedSet(set, value);
                return score;
            }
            /// <summary>
            /// 获得有序集合中,某个排名范围的所有值
            /// </summary>
            /// <param name="set"></param>
            /// <param name="beginRank"></param>
            /// <param name="endRank"></param>
            /// <returns></returns>
            public static List<string> GetRangeFromSortedSet(string set,int beginRank, int endRank)
            {
                List<string> valueList=redisCli.GetRangeFromSortedSet(set,beginRank,endRank);
                return valueList;
            }
            /// <summary>
            /// 获得有序集合中,某个分数范围内的所有值,升序
            /// </summary>
            /// <param name="set"></param>
            /// <param name="beginScore"></param>
            /// <param name="endScore"></param>
            /// <returns></returns>
            public static List<string> GetRangeFromSortedSet(string set, double beginScore, double endScore)
            {
                List<string> valueList = redisCli.GetRangeFromSortedSetByHighestScore(set, beginScore, endScore);
                return valueList;
            }
            /// <summary>
            /// 获得有序集合中,某个分数范围内的所有值,降序
            /// </summary>
            /// <param name="set"></param>
            /// <param name="beginScore"></param>
            /// <param name="endScore"></param>
            /// <returns></returns>
            public static List<string> GetRangeFromSortedSetDesc(string set, double beginScore, double endScore)
            {
                List<string> vlaueList=redisCli.GetRangeFromSortedSetByLowestScore(set,beginScore,endScore);
                return vlaueList;
            }
            public void Dispose()
            {
                redisCli.Dispose();
            }
     
        }
    }
    RedisHelper

    ==========================================

    Redis主从服务部署

    Redis服务器及应用

    基于Redis缓存的Session共享(附源码)

    基于redis实现分布式Session

  • 相关阅读:
    JS魔法堂:阻止元素被选中
    JS魔法堂之实战:纯前端的图片预览
    CentOS6.5菜鸟之旅:纯转载Linux目录结构
    Vim杂记:Sublime的配色方案
    Vim杂记:markdown插件
    CentOS6.5菜鸟之旅:中文编辑器忍痛放弃Sublime
    JS魔法堂:Data URI Scheme介绍
    CentOS6.5菜鸟之旅:安装ATI显卡驱动
    JS魔法堂:获取当前脚本文件的绝对路径
    腊八蒜
  • 原文地址:https://www.cnblogs.com/weixing/p/5166817.html
Copyright © 2011-2022 走看看