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

  • 相关阅读:
    年末反思
    Flink运行时架构
    Phoenix 启动报错:Error: ERROR 726 (43M10): Inconsistent namespace mapping properties. Cannot initiate connection as SYSTEM:CATALOG is found but client does not have phoenix.schema.
    Clickhouse学习
    Flink简单认识
    IDEA无法pull代码到本地,Can't Update No tracked branch configured for branch master or the branch doesn't exist.
    第1章 计算机系统漫游
    简单的 Shell 脚本入门教程
    开源≠免费 常见开源协议介绍
    MySQL 视图
  • 原文地址:https://www.cnblogs.com/weixing/p/5166817.html
Copyright © 2011-2022 走看看