標籤:des style blog http io color ar os 使用
返回目錄
本篇文章可以說是第六回 Microsoft.Practices.EnterpriseLibrary.Caching實現基於方法簽名的資料集緩衝(可控更新,WEB端資料緩衝)的續篇,事實上,有EnterpriseLibrary.Caching也只是實現緩衝持久化的一種方式,而Redis做為成熟的分布式儲存中介軟體來說,實現這個資料集緩衝功能顯得更加得心應手,也更加滿足大型網站的設計規則。(在多web伺服器時(web端實現負載平衡,反向 Proxy),EnterpriseLibrary.Caching顯得沒什麼作為,而這時,分布式緩衝就可以一顯身手了,它可以很輕鬆的將快取服務器部署到第三方伺服器上,解決了上面的問題)
一個標準,多種實現,物件導向的真諦:多態性,如果你問我介面有什麼用,那麼本篇文章可以告訴你答案:根據不同的場合,使用不同的持久化方式去儲存資料。
下面是緩衝標準介面ICacheProvider
/// <summary> /// 表示實現該介面的類型是能夠為應用程式提供緩衝機制的類型。 /// 這可以有多種實現機制 /// </summary> public interface ICacheProvider { #region Methods /// <summary> /// 向緩衝中添加一個對象。 /// </summary> /// <param name="key">緩衝的索引值,該值通常是使用緩衝機制的方法的名稱。</param> /// <param name="valKey">緩衝值的索引值,該值通常是由使用緩衝機制的方法的參數值所產生。</param> /// <param name="value">需要緩衝的對象。</param> void Add(string key, string valKey, object value); /// <summary> /// 向緩衝中更新一個對象。 /// </summary> /// <param name="key">緩衝的索引值,該值通常是使用緩衝機制的方法的名稱。</param> /// <param name="valKey">緩衝值的索引值,該值通常是由使用緩衝機制的方法的參數值所產生。</param> /// <param name="value">需要緩衝的對象。</param> void Put(string key, string valKey, object value); /// <summary> /// 從緩衝中讀取對象。 /// </summary> /// <param name="key">緩衝的索引值,該值通常是使用緩衝機制的方法的名稱。</param> /// <param name="valKey">緩衝值的索引值,該值通常是由使用緩衝機制的方法的參數值所產生。</param> /// <returns>被緩衝的對象。</returns> object Get(string key, string valKey); /// <summary> /// 從緩衝中移除對象。 /// </summary> /// <param name="key">緩衝的索引值,該值通常是使用緩衝機制的方法的名稱。</param> void Remove(string key); /// <summary> /// 擷取一個<see cref="Boolean"/>值,該值表示擁有指定索引值的緩衝是否存在。 /// </summary> /// <param name="key">指定的索引值。</param> /// <returns>如果緩衝存在,則返回true,否則返回false。</returns> bool Exists(string key); /// <summary> /// 擷取一個<see cref="Boolean"/>值,該值表示擁有指定索引值和緩衝值鍵的緩衝是否存在。 /// </summary> /// <param name="key">指定的索引值。</param> /// <param name="valKey">緩衝值鍵。</param> /// <returns>如果緩衝存在,則返回true,否則返回false。</returns> bool Exists(string key, string valKey); #endregion }
而這次我們使用Redis來作為實現持久化的方式,看一個RedisCacheProvider代碼,它為了相容性,將Dictionary<string, object>類型改為了Dictionary<string, byte[]>類型,這種設計避免了很多錯誤,因為我們知道,資料在發送時,它會被序列化,而相容性,
安全性,效能等最佳的方式就是二進位的方式,所以,我們使用它來對資料進行儲存。
/// <summary> ///使用redis方式進行緩衝持久化 /// </summary> internal class RedisCacheProvider : ICacheProvider, IDisposable { private readonly IRedisClient _cacheManager = Redis.Client.RedisManager.GetClient(); static byte[] Serialize(object data) { BinaryFormatter formatter = new BinaryFormatter(); MemoryStream rems = new MemoryStream(); formatter.Serialize(rems, data); return rems.GetBuffer(); } static object Deserialize(byte[] data) { BinaryFormatter formatter = new BinaryFormatter(); MemoryStream rems = new MemoryStream(data); data = null; return formatter.Deserialize(rems); } public void Add(string key, string valKey, object value) { byte[] byteValue = Serialize(value); using (var tbl = _cacheManager.GetTypedClient<Dictionary<string, byte[]>>()) { Dictionary<string, byte[]> dict = null; if (tbl.ContainsKey(key)) { dict = (Dictionary<string, byte[]>)tbl.Lists[key][0]; dict[valKey] = byteValue; } else { dict = new Dictionary<string, byte[]>(); dict.Add(valKey, byteValue); } Remove(key); tbl.Lists[key].Add(dict); } } public void Put(string key, string valKey, object value) { Add(key, valKey, value); } public object Get(string key, string valKey) { using (var tbl = _cacheManager.GetTypedClient<Dictionary<string, byte[]>>()) { if (tbl.ContainsKey(key)) { Dictionary<string, byte[]> dict = (Dictionary<string, byte[]>)tbl.Lists[key][0]; if (dict != null && dict.ContainsKey(valKey)) return Deserialize(dict[valKey]); else return null; } } return null; } public void Remove(string key) { using (var tbl = _cacheManager.GetTypedClient<Dictionary<string, byte[]>>()) { tbl.Lists[key].RemoveAll(); } } public bool Exists(string key) { using (var tbl = _cacheManager.GetTypedClient<Dictionary<string, byte[]>>()) { return tbl.ContainsKey(key); } } public bool Exists(string key, string valKey) { using (var tbl = _cacheManager.GetTypedClient<Dictionary<string, byte[]>>()) { return tbl.ContainsKey(key) && ((System.Collections.Generic.Dictionary<string, byte[]>)tbl.Lists[key][0]).ContainsKey(valKey); } } public void Dispose() { _cacheManager.Dispose(); } }
事實上,寫到這裡,我們的redis方法簽名儲存就完成了,配合上一篇文章,你可以設計出自己的緩衝系統了,在這裡再多說一句,本緩衝系統用到的設計模式類似於策略模式,它對於一個完善功能,可以多種實現的策略,而對外只公開一個標準的對象,其它具體
的,完整功能的實現都使用了internal作為修飾符,來對外界隱藏。
返回目錄
緩衝篇~第七回 Redis實現基於方法簽名的資料集緩衝(可控更新,分布式資料緩衝)