.NET 缓存的设计
关于缓存的设计
1、什么情况下用缓存
缓存是提高应用程序性能的最好方法之一。运用缓存可以优化数据查询,避免不必要的网络数据回传,和避免执行不必要的完全相同的数据处理逻辑。在实现缓存的时候我们要确定什么时候装入缓存数据。用异步装入缓存或用批处理方式来避免出现客户端数据延迟。
一般来说在一定时间内请求了相同的业务逻辑而没有变更的话,可以采用缓存来设计。数据请求频繁的的请求不适合采用缓存,如论坛的回复,但是论坛的主题是可以采用缓存设计的。
2、缓存设计的步骤
确定缓存数据结构:即设计中哪些数据用到了缓存,设计这些数据的缓存结构
确定缓存什么数据
确定缓存过期规则和清理
确定如何装入缓存数据
3、示例 Community Server的缓存类
1using System;
2using System.Collections;
3using System.Text.RegularExpressions;
4using System.Web;
5using System.Web.Caching;
6
7namespace Larry.Cache
8{
9 /// <summary>
10 /// 缓存类 Community Server的缓存类
11 /// </summary>
12 public class BaseCache
13 {
14 /// <summary>
15 /// CacheDependency 说明
16 /// 如果您向 Cache 中添加某个具有依赖项的项,当依赖项更改时,
17 /// 该项将自动从 Cache 中删除。例如,假设您向 Cache 中添加某项,
18 /// 并使其依赖于文件名数组。当该数组中的某个文件更改时,
19 /// 与该数组关联的项将从缓存中删除。
20 /// [C#]
21 /// Insert the cache item.
22 /// CacheDependency dep = new CacheDependency(fileName, dt);
23 /// cache.Insert("key", "value", dep);
24 /// </summary>
25 public static readonly int DayFactor = 17280;
26 public static readonly int HourFactor = 720;
27 public static readonly int MinuteFactor = 12;
28 public static readonly double SecondFactor = 0.2;
29
30 private static readonly System.Web.Caching.Cache _cache;
31
32 private static int Factor = 1440;
33
34 /// <summary>
35 /// 单件模式
36 /// </summary>
37 static BaseCache()
38 {
39 HttpContext context = HttpContext.Current;
40 if (context != null)
41 {
42 _cache = context.Cache;
43 }
44 else
45 {
46 _cache = HttpRuntime.Cache;
47 }
48 }
49
50 /// <summary>
51 /// 一次性清除所有缓存
52 /// </summary>
53 public static void Clear()
54 {
55 IDictionaryEnumerator CacheEnum = _cache.GetEnumerator();
56 ArrayList al = new ArrayList();
57 while (CacheEnum.MoveNext()) //逐个清除
58 {
59 al.Add(CacheEnum.Key);
60 }
61
62 foreach (string key in al)
63 {
64 _cache.Remove(key);
65 }
66
67 }
68
69
70
71 public static void RemoveByPattern(string pattern)
72 {
73 IDictionaryEnumerator CacheEnum = _cache.GetEnumerator();
74 Regex regex = new Regex(pattern, RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.Compiled);
75 while (CacheEnum.MoveNext())
76 {
77 if (regex.IsMatch(CacheEnum.Key.ToString()))
78 _cache.Remove(CacheEnum.Key.ToString());
79 }
80 }
81
82 /// <summary>
83 /// 清除特定的缓存
84 /// </summary>
85 /// <param name="key"></param>
86 public static void Remove(string key)
87 {
88 _cache.Remove(key);
89 }
90
91 /// <summary>
92 /// 缓存OBJECT.
93 /// </summary>
94 /// <param name="key"></param>
95 /// <param name="obj"></param>
96 public static void Insert(string key, object obj)
97 {
98 Insert(key, obj, null, 1);
99 }
100
101 /// <summary>
102 /// 缓存obj 并建立依赖项
103 /// </summary>
104 /// <param name="key"></param>
105 /// <param name="obj"></param>
106 /// <param name="dep"></param>
107 public static void Insert(string key, object obj, CacheDependency dep)
108 {
109 Insert(key, obj, dep, MinuteFactor * 3);
110 }
111
112 /// <summary>
113 /// 按秒缓存对象
114 /// </summary>
115 /// <param name="key"></param>
116 /// <param name="obj"></param>
117 /// <param name="seconds"></param>
118 public static void Insert(string key, object obj, int seconds)
119 {
120 Insert(key, obj, null, seconds);
121 }
122
123 /// <summary>
124 /// 按秒缓存对象 并存储优先级
125 /// </summary>
126 /// <param name="key"></param>
127 /// <param name="obj"></param>
128 /// <param name="seconds"></param>
129 /// <param name="priority"></param>
130 public static void Insert(string key, object obj, int seconds, CacheItemPriority priority)
131 {
132 Insert(key, obj, null, seconds, priority);
133 }
134
135 /// <summary>
136 /// 按秒缓存对象 并建立依赖项
137 /// </summary>
138 /// <param name="key"></param>
139 /// <param name="obj"></param>
140 /// <param name="dep"></param>
141 /// <param name="seconds"></param>
142 public static void Insert(string key, object obj, CacheDependency dep, int seconds)
143 {
144 Insert(key, obj, dep, seconds, CacheItemPriority.Normal);
145 }
146
147 /// <summary>
148 /// 按秒缓存对象 并建立具有优先级的依赖项
149 /// </summary>
150 /// <param name="key"></param>
151 /// <param name="obj"></param>
152 /// <param name="dep"></param>
153 /// <param name="seconds"></param>
154 /// <param name="priority"></param>
155 public static void Insert(string key, object obj, CacheDependency dep, int seconds, CacheItemPriority priority)
156 {
157 if (obj != null)
158 {
159 _cache.Insert(key, obj, dep, DateTime.Now.AddSeconds(Factor * seconds), TimeSpan.Zero, priority, null);
160 }
161
162 }
163
164
165 public static void MicroInsert(string key, object obj, int secondFactor)
166 {
167 if (obj != null)
168 {
169 _cache.Insert(key, obj, null, DateTime.Now.AddSeconds(Factor * secondFactor), TimeSpan.Zero);
170 }
171 }
172
173 /// <summary>
174 /// 最大时间缓存
175 /// </summary>
176 /// <param name="key"></param>
177 /// <param name="obj"></param>
178 public static void Max(string key, object obj)
179 {
180 Max(key, obj, null);
181 }
182
183 /// <summary>
184 /// 具有依赖项的最大时间缓存
185 /// </summary>
186 /// <param name="key"></param>
187 /// <param name="obj"></param>
188 /// <param name="dep"></param>
189 public static void Max(string key, object obj, CacheDependency dep)
190 {
191 if (obj != null)
192 {
193 _cache.Insert(key, obj, dep, DateTime.MaxValue, TimeSpan.Zero, CacheItemPriority.AboveNormal, null);
194 }
195 }
196
197 /// <summary>
198 /// Insert an item into the cache for the Maximum allowed time
199 /// </summary>
200 /// <param name="key"></param>
201 /// <param name="obj"></param>
202 public static void Permanent(string key, object obj)
203 {
204 Permanent(key, obj, null);
205 }
206
207 public static void Permanent(string key, object obj, CacheDependency dep)
208 {
209 if (obj != null)
210 {
211 _cache.Insert(key, obj, dep, DateTime.MaxValue, TimeSpan.Zero, CacheItemPriority.NotRemovable, null);
212 }
213 }
214
215 public static object Get(string key)
216 {
217 return _cache[key];
218 }
219
220 /// <summary>
221 /// Return int of seconds * SecondFactor
222 /// </summary>
223 public static int SecondFactorCalculate(int seconds)
224 {
225 // Insert method below takes integer seconds, so we have to round any fractional values
226 return Convert.ToInt32(Math.Round((double)seconds * SecondFactor));
227 }
228 }
229}
230
其实这个类就是一个单件模式的设计 和缓存的公共操作方法,其中CacheDependency表示建立缓存依赖项,CacheItemPriority表示缓存的优先级。S使用如下
1public static CardShop.Model.Systems GetConfig()
2 {
3 const string cacheKey = "WebConfig";
4 CardShop.Model.Systems sampleCacheTable = Larry.Cache.BaseCache.Get(cacheKey) as CardShop.Model.Systems;
5 if (sampleCacheTable == null)
6 {
7 OprationCheck.Message("第一次加载使用缓存");
8 sampleCacheTable = model;
9 Larry.Cache.BaseCache.Insert(cacheKey, sampleCacheTable, 24 * Larry.Cache.BaseCache.MinuteFactor);
10 }
11 else
12 {
13 OprationCheck.Message("已经加载了缓存不需要再加载");
14 }
15 return sampleCacheTable;
16 }
2 {
3 const string cacheKey = "WebConfig";
4 CardShop.Model.Systems sampleCacheTable = Larry.Cache.BaseCache.Get(cacheKey) as CardShop.Model.Systems;
5 if (sampleCacheTable == null)
6 {
7 OprationCheck.Message("第一次加载使用缓存");
8 sampleCacheTable = model;
9 Larry.Cache.BaseCache.Insert(cacheKey, sampleCacheTable, 24 * Larry.Cache.BaseCache.MinuteFactor);
10 }
11 else
12 {
13 OprationCheck.Message("已经加载了缓存不需要再加载");
14 }
15 return sampleCacheTable;
16 }