全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

Redis缓存详解

下面来正式分享今天的文章吧:

。搭建Redis服务端,并用客户端连接

。封装缓存父类,定义Get,Set等常用方法

。定义RedisCache缓存类,执行Redis的Get,Set方法

。构造出缓存工厂调用方法

下面一步一个脚印的来分享:

。搭建Redis服务端,并用客户端连接

首先,咋们去这个地址下载安装文件https://github.com/dmajkic/redis/downloads,我这里的版本是:redis-2.4.5-win32-win64里面有32位和64位的执行文件,我这里服务器是64位的下面给出截图和用到部分程序的说明:

现在,咋们直接可以用鼠标双击redis-server.exe这个应用程序,这样就打开了redis服务窗体(您也可以下载一个windows服务承载器,把redis服务运行在windows的服务中,就不用担心每次关闭redis服务黑色窗体后无法访问redis了),运行起来是这样:

有红色框的信息就表示成功了,这里redis服务监听的端口默认是6379,要修改端口或者更多的配置信息请找到redis.conf配置文件,具体配置信息介绍可以来这里http://www.shouce.ren/api/view/a/6231

再来,打开客户端连接服务端,咋们退到64bit文件夹的目录中,鼠标移到64bit文件夹上并且安装Shift键,同时点击鼠标的右键,选中"在此处打开命令窗口"这样快速进入到了该文件夹的cmd命令窗口中(当然不同的操作系统不同,这里演示的是windows的操作;还有其他进入的方式这里不做介绍,因为个人感觉这是最快的);然后,在命令窗口中录入redis-cli.exe -h localhost -p 6379回车来访问服务端,效果图:

再来看下服务端窗体截图:

没错这样客户端就连接上服务端了,可以简单在客户端执行下set,get命令:

如果是客户端要访问远程的redis服务端,只需要把localhost换成可访问的ip就行了如果还需要密码等更多配置请去上面的那个地址链接;

 。封装缓存父类,定义Get,Set等常用方法

先来,上父类的代码:

public class BaseCache : IDisposable
 {
 protected string def_ip = string.Empty;
 protected int def_port = 0;
 protected string def_password = string.Empty;
 public BaseCache()
 {
 }
 public virtual void InitCache(string ip = "", int port = 0, string password = "")
 {
 }
 public virtual bool SetCache<T>(string key, T t, int timeOutMinute = 10) where T : class,new()
 {
  return false;
 }
 public virtual T GetCache<T>(string key) where T : class,new()
 {
  return default(T);
 }
 public virtual bool Remove(string key)
 {
  return false;
 }
 public virtual bool FlushAll()
 {
  return false;
 }
 public virtual bool Any(string key)
 {
  return false;
 }
 public virtual void Dispose(bool isfalse)
 {
  if (isfalse)
  {
  }
 }
 //手动释放
 public void Dispose()
 {
  this.Dispose(true);
  //不自动释放
  GC.SuppressFinalize(this);
 }
 }

 这里定义的方法没有太多的注释,更多的意思我想看方法名称就明白了,这个父类主要实现了IDisposable,实现的Dispose()中主要用来释放资源并且自定义了一个 public virtual void Dispose(bool isfalse)方法,这里面有一句是GC.SuppressFinalize(this);按照官网介绍的意思是阻塞自动释放资源,其他的没有什么了,继续看下面的

。定义RedisCache缓存类,执行Redis的Get,Set方法

首先,咋们分别定义类RedisCache,MemcachedCache(这里暂未实现对memcache缓存的操作),并且继承BaseCache,重写Set,Get方法如下代码:

/// <summary>
 /// Redis缓存
 /// </summary>
 public class RedisCache : BaseCache
 {
 public RedisClient redis = null;
 public RedisCache()
 {
  //这里去读取默认配置文件数据
  def_ip = "172.0.0.1";
  def_port = 6379;
  def_password = "";
 }
 #region Redis缓存
 public override void InitCache(string ip = "", int port = 0, string password = "")
 {
  if (redis == null)
  {
  ip = string.IsNullOrEmpty(ip) ? def_ip : ip;
  port = port == 0 ? def_port : port;
  password = string.IsNullOrEmpty(password) ? def_password : password;
  redis = new RedisClient(ip, port, password);
  }
 }
 public override bool SetCache<T>(string key, T t, int timeOutMinute = 10)
 {
  var isfalse = false;
  try
  {
  if (string.IsNullOrEmpty(key)) { return isfalse; }
  InitCache();
  isfalse = redis.Set<T>(key, t, TimeSpan.FromMinutes(timeOutMinute));
  }
  catch (Exception ex)
  {
  }
  finally { this.Dispose(); }
  return isfalse;
 }
 public override T GetCache<T>(string key)
 {
  var t = default(T);
  try
  {
  if (string.IsNullOrEmpty(key)) { return t; }
  InitCache();
  t = redis.Get<T>(key);
  }
  catch (Exception ex)
  {
  }
  finally { this.Dispose(); }
  return t;
 }
 public override bool Remove(string key)
 {
  var isfalse = false;
  try
  {
  if (string.IsNullOrEmpty(key)) { return isfalse; }
  InitCache();
  isfalse = redis.Remove(key);
  }
  catch (Exception ex)
  {
  }
  finally { this.Dispose(); }
  return isfalse;
 }
 public override void Dispose(bool isfalse)
 {
  if (isfalse && redis != null)
  {
  redis.Dispose();
  redis = null;
  }
 }
 #endregion
 }
 /// <summary>
 /// Memcached缓存
 /// </summary>
 public class MemcachedCache : BaseCache
 {
 }

这里,用到的RedisClient类是来自nuget包引用的,这里nuget包是:

然后,来看下重写的InitCache方法,这里面有一些ip,port(端口),password(密码)参数,这里直接写入在cs文件中没有从配置文件读取,大家可以扩展下;这些参数通过RedisClient构造函数传递给底层Socket访问需要的信息,下面简单展示下RedisClient几个的构造函数:

public RedisClient();
 public RedisClient(RedisEndpoint config);
 public RedisClient(string host);
 public RedisClient(Uri uri);
 public RedisClient(string host, int port);
 public RedisClient(string host, int port, string password = null, long db = 0);

至于Get,Set方法最终都是使用RedisClient对象访问的,个人觉得需要注意的是Set方法里面的过期时间参数,目前还没有试验这种情况的效果:

?通过这几种方法设置过期时间后,快到过期时间的时候如果此时有使用这个缓存key那么过期时间是否会往后自动增加过期时间有效期,这里暂时没有试验(这里是由于前面项目中的.net core框架中的memecache缓存都有这种设置,想来redis应该也有吧)

这里,需要重写下public override void Dispose(bool isfalse)方法,因为调用完RedisClient后需要释放,我们通过Dispose统一来手动释放,而不是直接在调用的时候使用using()

。构造出缓存工厂调用方法

接下来,咋们需要定义一个缓存工厂,因为上面刚才定义了一个RedisCache和MemcachedCache明显这里会有多个不同缓存的方法调用,所用咋们来定义个工厂模式来调用对应的缓存;这里的工厂模式没有使用直接显示创建new RedisCache(),new MemcachedCache()对象的方法,而是使用了反射的原理,创建对应的缓存对象;

先来,定义个枚举,枚举里面的声明的名字要和咋们缓存类的名称相同,代码如下:

public enum CacheType
 {
 RedisCache,
 MemcachedCache
 }

再来,定义个工厂来CacheRepository(缓存工厂),并且定义方法Current如下代码:

public static BaseCache Current(CacheType cacheType = CacheType.RedisCache)
 {
 var nspace = typeof(BaseCache);
 var fullName = nspace.FullName;
 var nowspace = fullName.Substring(0, fullName.LastIndexOf('.') + 1);
 return Assembly.GetExecutingAssembly().CreateInstance(nowspace + cacheType.ToString(), true) as BaseCache;
 }

*:通过传递枚举参数,来确定反射CreateInstance()方法需要用到的typeName参数,从而来定义需要访问的那个缓存对象,这里要注意的是加上了一个命名空间nowspace,因为缓存类可能和工厂类不是同一个命名空间,但是通常会和缓存基类是同命名空间所以在方法最开始的时候截取获取了缓存类需要的命名空间(这里看自身项目来定吧);

*:Assembly.GetExecutingAssembly()这个是用来获取当前应用程序集的路径,这里就避免了咋们使用Assembly.Load()方法还需要传递程序集的路径地址了

好了满上上面要求后,咋们可以在测试页面调用代码如:CacheRepository.Current(CacheType.RedisCache).SetCache<MoFlightSearchResponse>(keyData, value);就如此简单,咋们使用redis-cli.exe客户端来看下缓存起来的数据:

怎么样,您们的是什么效果呢,下面给出整体代码

#region CacheRepository 缓存工厂(默认存储Session中)
 /// <summary>
 /// 缓存枚举
 /// </summary>
 public enum CacheType
 {
 BaseCache,
 RedisCache,
 MemcachedCache
 }
 /// <summary>
 /// 缓存工厂(默认存储Session中)
 /// </summary>
 public class CacheRepository
 {
 /// <summary>
 /// 缓存工厂(默认存储Session中, CacheKey = "SeesionKey")
 /// </summary>
 /// <param name="cacheType">缓存类型</param>
 /// <returns></returns>
 public static BaseCache Current(CacheType cacheType = CacheType.RedisCache)
 {
 var nspace = typeof(BaseCache);
 var fullName = nspace.FullName;
 var nowspace = fullName.Substring(0, fullName.LastIndexOf('.') + 1);

 return Assembly.GetExecutingAssembly().CreateInstance(nowspace + cacheType.ToString(), true) as BaseCache;
 }
 }
 /// <summary>
 /// 缓存基类(默认存储Session中)
 /// </summary>
 public class BaseCache : IDisposable
 {
 protected string def_ip = string.Empty;
 protected int def_port = 0;
 protected string def_password = string.Empty;
 protected string CacheKey = "SeesionKey";
 public BaseCache()
 {
 }
 /// <summary>
 /// 获取自定义SessionId值
 /// </summary>
 /// <param name="key">key:使用唯一的登陆账号</param>
 /// <returns>hash值的SessionId</returns>
 public virtual string GetSessionId(string key)
 {
 return Md5Extend.GetSidMd5Hash(key);
 }
 public virtual void InitCache(bool isReadAndWriter = true, string ip = "", int port = 0, string password = "")
 {
 }
 public virtual bool SetCache<T>(string key, T t, int timeOutMinute = 10, bool isSerilize = false) where T : class,new()
 {
 var isfalse = false;
 try
 {
 key = key ?? CacheKey;
 if (t == null) { return isfalse; }

 var session_json = JsonConvert.SerializeObject(t);
 HttpContext.Current.Session.Timeout = timeOutMinute;
 HttpContext.Current.Session.Add(key, session_json);
 isfalse = true;
 }
 catch (Exception ex)
 {
 throw new Exception(ex.Message);
 }
 return isfalse;
 }
 public virtual T GetCache<T>(string key = null, bool isSerilize = false) where T : class,new()
 {
 var t = default(T);
 try
 {
 key = key ?? CacheKey;
 var session = HttpContext.Current.Session[key];
 if (session == null) { return t; }

 t = JsonConvert.DeserializeObject<T>(session.ToString());
 }
 catch (Exception ex)
 {
 throw new Exception(ex.Message);
 }
 return t;
 }
 public virtual bool Remove(string key = null)
 {
 var isfalse = false;
 try
 {
 key = key ?? CacheKey;
 HttpContext.Current.Session.Remove(key);
 isfalse = true;
 }
 catch (Exception ex)
 {
 throw new Exception(ex.Message);
 }
 return isfalse;
 }
 /// <summary>
 /// 增加缓存时间
 /// </summary>
 /// <returns></returns>
 public virtual bool AddExpire(string key, int nTimeMinute = 10)
 {
 return true;
 }
 public virtual bool FlushAll()
 {
 return false;
 }
 public virtual bool Any(string key)
 {
 return false;
 }
 public virtual bool SetHashCache<T>(string hashId, string key, T t, int nTimeMinute = 10) where T : class,new()
 {
 return false;
 }
 public virtual List<string> GetHashKeys(string hashId)
 {
 return null;
 }
 public virtual List<string> GetHashValues(string hashId)
 {
 return null;
 }
 public virtual T GetHashValue<T>(string hashId, string key) where T : class,new()
 {
 var t = default(T);
 return t;
 }
 public virtual bool RemoveHashByKey(string hashId, string key)
 {
 return false;
 }
 public virtual void Dispose(bool isfalse)
 {
 if (isfalse)
 {
 }
 }
 //手动释放
 public void Dispose()
 {
 this.Dispose(true);
 //不自动释放
 GC.SuppressFinalize(this);
 }
 }
 /// <summary>
 /// Redis缓存
 /// </summary>
 public class RedisCache : BaseCache
 {
 public IRedisClient redis = null;
 public RedisCache()
 {
 //这里去读取默认配置文件数据
 def_ip = "127.0.0.1";
 def_port = 6379;
 def_password = "";
 }
 #region Redis缓存
 public static object _lockCache = new object();
 public override void InitCache(bool isReadAndWriter = true, string ip = "", int port = 0, string password = "")
 {
 if (redis == null)
 {
 ip = string.IsNullOrEmpty(ip) ? def_ip : ip;
 port = port == 0 ? def_port : port;
 password = string.IsNullOrEmpty(password) ? def_password : password;
 //单个redis服务
 //redis = new RedisClient(ip, port, password);
 //集群服务 如果密码,格式如:pwd@ip:port
 var readAndWritePorts = new List<string> { "shenniubuxing3@127.0.0.1:6379" };
 var onlyReadPorts = new List<string> {
  "shenniubuxing3@127.0.0.1:6378",
  "shenniubuxing3@127.0.0.1:6377"
 };
 var redisPool = new PooledRedisClientManager(
  readAndWritePorts,
  onlyReadPorts,
  new RedisClientManagerConfig
  {
  AutoStart = true,
  //最大读取链接
  MaxReadPoolSize = 20,
  //最大写入链接
  MaxWritePoolSize = 10
  })
 {
  //每个链接超时时间
  ConnectTimeout = 20,
  //连接池超时时间
  PoolTimeout = 60
 };
 lock (_lockCache)
 {
  redis = isReadAndWriter ? redisPool.GetClient() : redisPool.GetReadOnlyClient();
 }
 }
 }
 public override bool AddExpire(string key, int nTimeMinute = 10)
 {
 var isfalse = false;
 try
 {
 if (string.IsNullOrEmpty(key)) { return isfalse; }
 InitCache();
 //isfalse = redis.ExpireEntryIn(key, TimeSpan.FromMinutes(nTimeMinute));
 isfalse = redis.ExpireEntryAt(key, DateTime.Now.AddMinutes(nTimeMinute));
 }
 catch (Exception ex)
 {
 }
 finally { this.Dispose(); }
 return isfalse;
 }
 public override bool SetCache<T>(string key, T t, int timeOutMinute = 10, bool isSerilize = false)
 {
 var isfalse = false;
 try
 {
 if (string.IsNullOrEmpty(key)) { return isfalse; }
 InitCache();
 if (isSerilize)
 {
  var data = JsonConvert.SerializeObject(t);
  var bb = System.Text.Encoding.UTF8.GetBytes(data);
  isfalse = redis.Set<byte[]>(key, bb, TimeSpan.FromMinutes(timeOutMinute));
 }
 else { isfalse = redis.Set<T>(key, t, TimeSpan.FromMinutes(timeOutMinute)); }
 }
 catch (Exception ex)
 {
 }
 finally { this.Dispose(); }
 return isfalse;
 }
 public override T GetCache<T>(string key, bool isSerilize = false)
 {
 var t = default(T);
 try
 {
 if (string.IsNullOrEmpty(key)) { return t; }
 InitCache(false);
 if (isSerilize)
 {
  var bb = redis.Get<byte[]>(key);
  if (bb.Length <= 0) { return t; }
  var data = System.Text.Encoding.UTF8.GetString(bb);
  t = JsonConvert.DeserializeObject<T>(data);
 }
 else { t = redis.Get<T>(key); }
 }
 catch (Exception ex)
 {
 }
 finally { this.Dispose(); }
 return t;
 }
 public override bool Remove(string key)
 {
 var isfalse = false;
 try
 {
 if (string.IsNullOrEmpty(key)) { return isfalse; }
 InitCache();
 isfalse = redis.Remove(key);
 }
 catch (Exception ex)
 {
 }
 finally { this.Dispose(); }
 return isfalse;
 }
 public override bool SetHashCache<T>(string hashId, string key, T t, int nTimeMinute = 10)
 {
 var isfalse = false;
 try
 {
 if (string.IsNullOrEmpty(hashId) || string.IsNullOrEmpty(key) || t == null) { return isfalse; }
 InitCache();
 var result = JsonConvert.SerializeObject(t);
 if (string.IsNullOrEmpty(result)) { return isfalse; }
 isfalse = redis.SetEntryInHash(hashId, key, result);
 if (isfalse) { AddExpire(key, nTimeMinute); }
 }
 catch (Exception ex)
 {
 }
 finally { this.Dispose(); }
 return isfalse;
 }
 public override List<string> GetHashKeys(string hashId)
 {
 var hashKeys = new List<string>();
 try
 {
 if (string.IsNullOrEmpty(hashId)) { return hashKeys; }
 InitCache();
 hashKeys = redis.GetHashKeys(hashId);
 }
 catch (Exception ex)
 {
 }
 finally { this.Dispose(); }
 return hashKeys;
 }
 public override List<string> GetHashValues(string hashId)
 {
 var hashValues = new List<string>();
 try
 {
 if (string.IsNullOrEmpty(hashId)) { return hashValues; }

 InitCache();
 hashValues = redis.GetHashValues(hashId);
 }
 catch (Exception ex)
 {
 }
 finally { this.Dispose(); }
 return hashValues;
 }
 public override T GetHashValue<T>(string hashId, string key)
 {
 var t = default(T);
 try
 {
 if (string.IsNullOrEmpty(hashId) || string.IsNullOrEmpty(key)) { return t; }
 InitCache();
 var result = redis.GetValueFromHash(hashId, key);
 if (string.IsNullOrEmpty(result)) { return t; }
 t = JsonConvert.DeserializeObject<T>(result);
 }
 catch (Exception ex)
 {
 }
 finally { this.Dispose(); }
 return t;
 }
 public override bool RemoveHashByKey(string hashId, string key)
 {
 var isfalse = false;
 try
 {
 if (string.IsNullOrEmpty(hashId) || string.IsNullOrEmpty(key)) { return isfalse; }
 InitCache();
 isfalse = redis.RemoveEntryFromHash(hashId, key);
 }
 catch (Exception ex)
 {
 }
 finally { this.Dispose(); }
 return isfalse;
 }
 public override void Dispose(bool isfalse)
 {
 if (isfalse && redis != null)
 {
 redis.Dispose();
 redis = null;
 }
 }
 #endregion
 }
 /// <summary>
 /// Memcached缓存
 /// </summary>
 public class MemcachedCache : BaseCache
 {
 }
 #endregion

 这次分享的Redis缓存从搭建到使用希望给您们有帮助,还请多多支持点赞,谢谢。

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持!


# Redis  # 缓存  # Redis缓存常用4种策略原理详解  # redis缓存的简单操作(get、put)  # Redis缓存工具封装实现  # 解析Redis的缓存类型  # 的是  # 客户端  # 服务端  # 配置文件  # 再来  # 自定义  # 还需要  # 重写  # 这里面  # 先来  # 应用程序  # 您们  # 都是  # 这是  # 几个  # 都有  # 还没有  # 也有  # 会有  # 好了 


相关文章: 如何将凡科建站内容保存为本地文件?  免费制作海报的网站,哪位做平面的朋友告诉我用什么软件做海报比较好?ps还是cd还是ai这几个软件我都会些我是做网页的?  制作网站建设的公司有哪些,网站建设比较好的公司都有哪些?  广州网站设计制作一条龙,广州巨网网络科技有限公司是干什么的?  如何挑选最适合建站的高性能VPS主机?  如何快速辨别茅台真假?关键步骤解析  整蛊网站制作软件,手机不停的收到各种网站的验证码短信,是手机病毒还是人为恶搞?有这种手机病毒吗?  猪八戒网站制作视频,开发一个猪八戒网站,大约需要多少?或者自己请程序员,需要什么程序员,多少程序员能完成?  建站主机如何选?高性价比方案全解析  宝塔建站无法访问?如何排查配置与端口问题?  如何通过.red域名打造高辨识度品牌网站?  简历在线制作网站免费,免费下载个人简历的网站是哪些?  建站主机选虚拟主机还是云服务器更好?  建站之星导航配置指南:自助建站与SEO优化全解析  陕西网站制作公司有哪些,陕西凌云电器有限公司官网?  如何在Windows环境下新建FTP站点并设置权限?  深圳 网站制作,深圳招聘网站哪个比较好一点啊?  实惠建站价格推荐:2025年高性价比自助建站套餐解析  建站10G流量真的够用吗?如何应对访问高峰?  网站制作怎么样才能赚钱,用自己的电脑做服务器架设网站有什么利弊,能赚钱吗?  如何快速生成凡客建站的专业级图册?  建站主机助手选型指南:2025年热门推荐与高效部署技巧  正规网站制作公司有哪些,目前国内哪家网页网站制作设计公司比较专业靠谱?口碑好?  武汉外贸网站制作公司,现在武汉外贸前景怎么样啊?  网站微信制作软件,如何制作微信链接?  如何用PHP快速搭建高效网站?分步指南  模具网站制作流程,如何找模具客户?  网站制作多少钱一个,建一个论坛网站大约需要多少钱?  娃派WAP自助建站:免费模板+移动优化,快速打造专业网站  定制建站价位费用解析与套餐推荐全攻略  已有域名和空间,如何快速搭建网站?  建站org新手必看:2024最新搭建流程与模板选择技巧  红河网站制作公司,红河事业单位身份证如何上传?  如何通过服务器快速搭建网站?完整步骤解析  网站制作的方法有哪些,如何将自己制作的网站发布到网上?  C#如何使用XPathNavigator高效查询XML  网站制作公司,橙子建站是合法的吗?  网站建设设计制作营销公司南阳,如何策划设计和建设网站?  广州建站公司哪家好?十大优质服务商推荐  微网站制作教程,不会写代码,不会编程,怎么样建自己的网站?  SQL查询语句优化的实用方法总结  西安市网站制作公司,哪个相亲网站比较好?西安比较好的相亲网站?  魔方云NAT建站如何实现端口转发?  香港服务器网站生成指南:免费资源整合与高速稳定配置方案  制作ppt免费网站有哪些,有哪些比较好的ppt模板下载网站?  怎么制作一个起泡网,水泡粪全漏粪育肥舍冬季氨气超过25ppm,可以有哪些措施降低舍内氨气水平?  ppt制作免费网站有哪些,ppt模板免费下载网站?  购物网站制作费用多少,开办网上购物网站,需要办理哪些手续?  建站之星后台密码如何安全设置与找回?  广州网站制作的公司,现在专门做网站的公司有没有哪几家是比较好的,性价比高,模板也多的? 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。