溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Redis緩存的示例分析

發(fā)布時(shí)間:2021-08-17 11:02:24 來源:億速云 閱讀:99 作者:小新 欄目:開發(fā)技術(shù)

這篇文章將為大家詳細(xì)講解有關(guān)Redis緩存的示例分析,小編覺得挺實(shí)用的,因此分享給大家做個(gè)參考,希望大家閱讀完這篇文章后可以有所收獲。

首先,咋們?nèi)ミ@個(gè)地址下載安裝文件https://github.com/dmajkic/redis/downloads,我這里的版本是:redis-2.4.5-win32-win64里面有32位和64位的執(zhí)行文件,我這里服務(wù)器是64位的下面給出截圖和用到部分程序的說明:

Redis緩存的示例分析

現(xiàn)在,咋們直接可以用鼠標(biāo)雙擊redis-server.exe這個(gè)應(yīng)用程序,這樣就打開了redis服務(wù)窗體(您也可以下載一個(gè)windows服務(wù)承載器,把redis服務(wù)運(yùn)行在windows的服務(wù)中,就不用擔(dān)心每次關(guān)閉redis服務(wù)黑色窗體后無法訪問redis了),運(yùn)行起來是這樣:

Redis緩存的示例分析

有紅色框的信息就表示成功了,這里redis服務(wù)監(jiān)聽的端口默認(rèn)是6379,要修改端口或者更多的配置信息請(qǐng)找到redis.conf配置文件,具體配置信息介紹可以來這里http://www.shouce.ren/api/view/a/6231

再來,打開客戶端連接服務(wù)端,咋們退到64bit文件夾的目錄中,鼠標(biāo)移到64bit文件夾上并且安裝Shift鍵,同時(shí)點(diǎn)擊鼠標(biāo)的右鍵,選中"在此處打開命令窗口"這樣快速進(jìn)入到了該文件夾的cmd命令窗口中(當(dāng)然不同的操作系統(tǒng)不同,這里演示的是windows的操作;還有其他進(jìn)入的方式這里不做介紹,因?yàn)閭€(gè)人感覺這是最快的);然后,在命令窗口中錄入redis-cli.exe -h localhost -p 6379回車來訪問服務(wù)端,效果圖:

Redis緩存的示例分析

再來看下服務(wù)端窗體截圖:

Redis緩存的示例分析

沒錯(cuò)這樣客戶端就連接上服務(wù)端了,可以簡(jiǎn)單在客戶端執(zhí)行下set,get命令:

Redis緩存的示例分析

如果是客戶端要訪問遠(yuǎn)程的redis服務(wù)端,只需要把localhost換成可訪問的ip就行了如果還需要密碼等更多配置請(qǐng)去上面的那個(gè)地址鏈接;

 。封裝緩存父類,定義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)
  {
  }
 }
 //手動(dòng)釋放
 public void Dispose()
 {
  this.Dispose(true);
  //不自動(dòng)釋放
  GC.SuppressFinalize(this);
 }
 }

 這里定義的方法沒有太多的注釋,更多的意思我想看方法名稱就明白了,這個(gè)父類主要實(shí)現(xiàn)了IDisposable,實(shí)現(xiàn)的Dispose()中主要用來釋放資源并且自定義了一個(gè) public virtual void Dispose(bool isfalse)方法,這里面有一句是GC.SuppressFinalize(this);按照官網(wǎng)介紹的意思是阻塞自動(dòng)釋放資源,其他的沒有什么了,繼續(xù)看下面的

。定義RedisCache緩存類,執(zhí)行Redis的Get,Set方法

首先,咋們分別定義類RedisCache,MemcachedCache(這里暫未實(shí)現(xiàn)對(duì)memcache緩存的操作),并且繼承BaseCache,重寫Set,Get方法如下代碼:

/// <summary>
 /// Redis緩存
 /// </summary>
 public class RedisCache : BaseCache
 {
 public RedisClient redis = null;
 public RedisCache()
 {
  //這里去讀取默認(rèn)配置文件數(shù)據(jù)
  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包是:

Redis緩存的示例分析

然后,來看下重寫的InitCache方法,這里面有一些ip,port(端口),password(密碼)參數(shù),這里直接寫入在cs文件中沒有從配置文件讀取,大家可以擴(kuò)展下;這些參數(shù)通過RedisClient構(gòu)造函數(shù)傳遞給底層Socket訪問需要的信息,下面簡(jiǎn)單展示下RedisClient幾個(gè)的構(gòu)造函數(shù):

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對(duì)象訪問的,個(gè)人覺得需要注意的是Set方法里面的過期時(shí)間參數(shù),目前還沒有試驗(yàn)這種情況的效果:

?通過這幾種方法設(shè)置過期時(shí)間后,快到過期時(shí)間的時(shí)候如果此時(shí)有使用這個(gè)緩存key那么過期時(shí)間是否會(huì)往后自動(dòng)增加過期時(shí)間有效期,這里暫時(shí)沒有試驗(yàn)(這里是由于前面項(xiàng)目中的.net core框架中的memecache緩存都有這種設(shè)置,想來redis應(yīng)該也有吧)

這里,需要重寫下public override void Dispose(bool isfalse)方法,因?yàn)檎{(diào)用完RedisClient后需要釋放,我們通過Dispose統(tǒng)一來手動(dòng)釋放,而不是直接在調(diào)用的時(shí)候使用using()

。構(gòu)造出緩存工廠調(diào)用方法

接下來,咋們需要定義一個(gè)緩存工廠,因?yàn)樯厦鎰偛哦x了一個(gè)RedisCache和MemcachedCache明顯這里會(huì)有多個(gè)不同緩存的方法調(diào)用,所用咋們來定義個(gè)工廠模式來調(diào)用對(duì)應(yīng)的緩存;這里的工廠模式?jīng)]有使用直接顯示創(chuàng)建new RedisCache(),new MemcachedCache()對(duì)象的方法,而是使用了反射的原理,創(chuàng)建對(duì)應(yīng)的緩存對(duì)象;

先來,定義個(gè)枚舉,枚舉里面的聲明的名字要和咋們緩存類的名稱相同,代碼如下:

public enum CacheType
 {
 RedisCache,
 MemcachedCache
 }

再來,定義個(gè)工廠來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;
 }

*:通過傳遞枚舉參數(shù),來確定反射CreateInstance()方法需要用到的typeName參數(shù),從而來定義需要訪問的那個(gè)緩存對(duì)象,這里要注意的是加上了一個(gè)命名空間nowspace,因?yàn)榫彺骖惪赡芎凸S類不是同一個(gè)命名空間,但是通常會(huì)和緩存基類是同命名空間所以在方法最開始的時(shí)候截取獲取了緩存類需要的命名空間(這里看自身項(xiàng)目來定吧);

*:Assembly.GetExecutingAssembly()這個(gè)是用來獲取當(dāng)前應(yīng)用程序集的路徑,這里就避免了咋們使用Assembly.Load()方法還需要傳遞程序集的路徑地址了

好了滿上上面要求后,咋們可以在測(cè)試頁面調(diào)用代碼如:CacheRepository.Current(CacheType.RedisCache).SetCache<MoFlightSearchResponse>(keyData, value);就如此簡(jiǎn)單,咋們使用redis-cli.exe客戶端來看下緩存起來的數(shù)據(jù):

Redis緩存的示例分析

怎么樣,您們的是什么效果呢,下面給出整體代碼

#region CacheRepository 緩存工廠(默認(rèn)存儲(chǔ)Session中)
 /// <summary>
 /// 緩存枚舉
 /// </summary>
 public enum CacheType
 {
 BaseCache,
 RedisCache,
 MemcachedCache
 }
 /// <summary>
 /// 緩存工廠(默認(rèn)存儲(chǔ)Session中)
 /// </summary>
 public class CacheRepository
 {
 /// <summary>
 /// 緩存工廠(默認(rèn)存儲(chǔ)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>
 /// 緩存基類(默認(rèn)存儲(chǔ)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:使用唯一的登陸賬號(hào)</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>
 /// 增加緩存時(shí)間
 /// </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)
 {
 }
 }
 //手動(dòng)釋放
 public void Dispose()
 {
 this.Dispose(true);
 //不自動(dòng)釋放
 GC.SuppressFinalize(this);
 }
 }
 /// <summary>
 /// Redis緩存
 /// </summary>
 public class RedisCache : BaseCache
 {
 public IRedisClient redis = null;
 public RedisCache()
 {
 //這里去讀取默認(rèn)配置文件數(shù)據(jù)
 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;
 //單個(gè)redis服務(wù)
 //redis = new RedisClient(ip, port, password);
 //集群服務(wù) 如果密碼,格式如: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
  })
 {
  //每個(gè)鏈接超時(shí)時(shí)間
  ConnectTimeout = 20,
  //連接池超時(shí)時(shí)間
  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

關(guān)于“Redis緩存的示例分析”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,使各位可以學(xué)到更多知識(shí),如果覺得文章不錯(cuò),請(qǐng)把它分享出去讓更多的人看到。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI