用过 Ruby on Rails 以后,从里面学到了很多很不错的应用,如《在 Asp.net 中实现类似 Rails 的 Flash[:notice] 的功能》,这里我实现缓存标签(也可以叫缓存命名空间)。
我们经常会遇到需要批量删除某一类的缓存,如 posts/p/1,posts/p/2,posts/p/3 这几个 CacheKey 都是属于文章列表的,我们想通过 posts 来删除所有页的缓存,这个就是简单的 Get Set Delete 这类的功能操作的了。
在 Ruby on Rails 里面,缓存可以用 posts/p/* (正则的方式) 来删除一系列的缓存,我这里没有做那么复杂,只是简单的实现给 Caches 加标签,分类,在按照分类来删除一些列缓存。
我这里是模仿的 Django 的一个实现,看这个地址《Setting and deleting cache in Django with tags》,这个的实现方式我整理了一下,做到了 Pulog 里面,代码在这里。
看看我在.NET 里面的实现
Caches 类源代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
| /*
* Cache 接口,实现 tag 功能,key 前缀
* Logs,Memcached 在这里没有公开,只是一些具体的实现,你可以根据已经情况实现一下
* Logs.Debug 表示写 debug 日志
* Memcached 里面的 Get,Set,Remove 也需要自已实现
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
public class Caches
{
private static string GenerateKey(string key)
{
return "project_name/" + key;
}
///
/// 取缓存
///
///
///
public static object Get(string key)
{
key = GenerateKey(key);
object obj = Memcached.Get(key);
if (obj != null)
{
Logs.Debug("Cache hit " + key);
}
return obj;
}
///
/// 存缓存
///
///
///
public static void Set(string key, object value)
{
key = GenerateKey(key);
Memcached.Caches.Set(key, value);
Logs.Debug("Cache set " + key);
}
///
/// 存缓存,带 Tag,用于做类似命名空间的管理
///
///
///
///
public static void Set(string key, object value, string[] tags)
{
if (tags.Length == 0)
{
Set(key, value);
}
for (int i = 0; i < tags.Count(); i++)
{
tags[i] = "tags/" + tags[i];
}
List<string> tagList = new List<string>();
foreach (string tag in tags)
{
object tagObj = Get(tag);
if (tagObj != null)
{
tagList = (List<string>)tagObj;
}
tagList.Add(key);
Set(tag, tagList);
}
Set(key, value);
}
///
/// 删缓存
///
///
public static void Remove(string key)
{
key = GenerateKey(key);
Memcached.Remove(key);
Logs.Debug("Cache remove " + key);
}
///
/// 根据 Tag 删除缓存
///
///
public static void RemoveByTags(string[] tags)
{
for (int i = 0; i < tags.Count(); i++)
{
tags[i] = "tags/" + tags[i];
}
List<string> tagList = new List<string>();
foreach (string tag in tags)
{
object tagsObj = Get(tag);
if (tagsObj != null)
{
tagList = (List<string>)tagsObj;
foreach (string key in tagList)
{
Remove(key);
}
}
Remove(tag);
}
}
}
|
使用的时候
1
2
3
4
5
6
7
8
9
10
11
| //写缓存
Caches.Set("posts/p/1",posts,new string[]{ "posts" }); //第 1 页 写缓存
Caches.Set("posts/p/2",posts,new string[]{ "posts" }); //第 2 页 写缓存
Caches.Set("posts/p/3",posts,new string[]{ "posts" }); //第 3 页 写缓存
//取
Caches.Get("posts/p/1"); //取 第 1 页
//删除所有页
Caches.RemoveByTags(new string[]{"posts"});
|
这个 Tag 也就类似博客系统的 Tag 功能,给 Cache 设定 1 个或多个 Tag,删除的时候就可以根据 Tag 删除 Tag 下面所有 CacheKey 的缓存。