标签:基于 json ops 失败 action 使用 先进先出 ansi redis
1. Redis简要介绍
引用百度百科的话,就是:Redis(Remote Dictionary Server ),即远程字典服务,是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value NoSQL数据库,并提供多种语言的API。
Redis的主要使用场景:缓存、消息队列、频繁读写等,还有很多等等,这个可以随处搜到;Redis的优势就是读写数据性能高,支持数据类型丰富,所有操作都是原子性,成功或者不成功,现在还支持发布订阅等特性。
2. .Net Framework操作Redis
创建新项目等等其他的我就不截图了,我使用的是VS2019专业版, .Net Framework 4.7.2,都行,这个都支持,无非可能是类库更新导致有些最新功能你不能用。
看下项目的一个结构,当前选中的为启动项目,控制台应用程序,另外两个是用到的自定义类库,RedisHelp为自定义的Redis帮助类库,用到的Nuget包为StackExchange.Redis2.1.30,LogManager是一个写日志的帮助类;
① 配置文件配置,RedisTest项目展开,打开App.config,添加Redis服务的IP和端口,
② ConnectionMultiplexer封装
ConnectionMultiplexer对象是StackExchange.Redis最中枢的对象。这个类的实例需要被整个应用程序域共享和重用的,所以不需要在每个操作中不停的创建该对象的实例,一般都是使用单例来创建和存放这个对象,提高程序运行的效率,这个在官网上也有说明的。
1 ///
2 /// ConnectionMultiplexer对象管理帮助类
3 ///
4 public static class RedisConnectionHelp
5 {
6 #region 属性
7
8 ///
9 /// 系统自定义Key前缀
10 ///
11 public static readonly string SysCustomKey = ConfigurationManager.AppSettings["redisKey"] ?? "";
12
13 ///
14 /// Redis链接字符串
15 ///
16 private static readonly string RedisConnectionString = ConfigurationManager.ConnectionStrings["RedisExchangeHosts"].ConnectionString;
17
18 ///
19 /// 链接缓存池
20 ///
21 private static readonly ConcurrentDictionarystring, ConnectionMultiplexer> ConnectionCache = new ConcurrentDictionarystring, ConnectionMultiplexer>();
22
23 #endregion
24
25 #region 单例和构造
26
27 ///
28 /// 锁
29 ///
30 private static readonly object Locker = new object();
31
32 ///
33 /// 单例
34 ///
35 private static ConnectionMultiplexer _instance;
36
37
38 ///
39 /// 单例获取
40 ///
41 public static ConnectionMultiplexer Instance
42 {
43 get
44 {
45 if (_instance == null)
46 {
47 lock (Locker)
48 {
49 if (_instance == null || !_instance.IsConnected)
50 {
51 _instance = GetManager();
52 }
53 }
54 }
55 return _instance;
56 }
57 }
58
59 ///
60 /// 缓存获取
61 ///
62 ///
63 ///
64 public static ConnectionMultiplexer GetConnectionMultiplexer(string connectionString)
65 {
66 if (!ConnectionCache.ContainsKey(connectionString))
67 {
68 ConnectionCache[connectionString] = GetManager(connectionString);
69 }
70 return ConnectionCache[connectionString];
71 }
72
73 ///
74 /// 获取链接
75 ///
76 ///
77 ///
78 private static ConnectionMultiplexer GetManager(string connectionString = null)
79 {
80 connectionString = connectionString ?? RedisConnectionString;
81 var connect = ConnectionMultiplexer.Connect(connectionString);
82
83 //注册如下事件
84 connect.ConnectionFailed += MuxerConnectionFailed;
85 connect.ConnectionRestored += MuxerConnectionRestored;
86 connect.ErrorMessage += MuxerErrorMessage;
87 connect.ConfigurationChanged += MuxerConfigurationChanged;
88 connect.HashSlotMoved += MuxerHashSlotMoved;
89 connect.InternalError += MuxerInternalError;
90
91 return connect;
92 }
93
94 #endregion
95
96 #region 事件
97
98 ///
99 /// 配置更改时
100 ///
101 ///
102 ///
103 private static void MuxerConfigurationChanged(object sender, EndPointEventArgs e)
104 {
105 Console.WriteLine("Configuration changed: " + e.EndPoint);
106 }
107
108 ///
109 /// 发生错误时
110 ///
111 ///
112 ///
113 private static void MuxerErrorMessage(object sender, RedisErrorEventArgs e)
114 {
115 Console.WriteLine("ErrorMessage: " + e.Message);
116 }
117
118 ///
119 /// 重新建立连接之前的错误
120 ///
121 ///
122 ///
123 private static void MuxerConnectionRestored(object sender, ConnectionFailedEventArgs e)
124 {
125 Console.WriteLine("ConnectionRestored: " + e.EndPoint);
126 }
127
128 ///
129 /// 连接失败 , 如果重新连接成功你将不会收到这个通知
130 ///
131 ///
132 ///
133 private static void MuxerConnectionFailed(object sender, ConnectionFailedEventArgs e)
134 {
135 Console.WriteLine("重新连接:Endpoint failed: " + e.EndPoint + ", " + e.FailureType + (e.Exception == null ? "" : (", " + e.Exception.Message)));
136 }
137
138 ///
139 /// 更改集群
140 ///
141 ///
142 ///
143 private static void MuxerHashSlotMoved(object sender, HashSlotMovedEventArgs e)
144 {
145 Console.WriteLine("HashSlotMoved:NewEndPoint" + e.NewEndPoint + ", OldEndPoint" + e.OldEndPoint);
146 }
147
148 ///
149 /// redis类库错误
150 ///
151 ///
152 ///
153 private static void MuxerInternalError(object sender, InternalErrorEventArgs e)
154 {
155 Console.WriteLine("InternalError:Message" + e.Exception.Message);
156 }
157
158 #endregion 事件
159 }
View Code
③ RedisHelper通用操作类封装
1 ///
2 /// Redis操作类
3 ///
4 public class RedisHelper
5 {
6 #region 属性
7
8 ///
9 /// DB库
10 ///
11 private int DbNum { get; }
12
13 ///
14 /// Redis链接
15 ///
16 private readonly ConnectionMultiplexer _conn;
17
18 ///
19 /// 前缀
20 ///
21 public string CustomKey;
22
23 #endregion
24
25 #region 构造函数
26
27 ///
28 /// 默认构造
29 ///
30 /// DB索引
31 public RedisHelper(int dbNum = 0)
32 : this(dbNum, null)
33 {
34 }
35
36 ///
37 /// 构造
38 ///
39 ///
40 ///
41 public RedisHelper(int dbNum, string readWriteHosts)
42 {
43 DbNum = dbNum;
44 _conn =
45 string.IsNullOrWhiteSpace(readWriteHosts) ?
46 RedisConnectionHelp.Instance :
47 RedisConnectionHelp.GetConnectionMultiplexer(readWriteHosts);
48 }
49
50 #endregion 构造函数
51
52 #region String
53
54 #region 同步方法
55
56 ///
57 /// 保存单个key value
58 ///
59 /// Redis Key
60 /// 保存的值
61 /// 过期时间
62 ///
63 public bool StringSet(string key, string value, TimeSpan? expiry = default(TimeSpan?))
64 {
65 key = AddSysCustomKey(key);
66 return Do(db => db.StringSet(key, value, expiry));
67 }
68
69 ///
70 /// 保存多个key value
71 ///
72 /// 键值对
73 ///
74 public bool StringSet(List> keyValues)
75 {
76 List> newkeyValues =
77 keyValues.Select(p => new KeyValuePair(AddSysCustomKey(p.Key), p.Value)).ToList();
78 return Do(db => db.StringSet(newkeyValues.ToArray()));
79 }
80
81 ///
82 /// 保存一个对象
83 ///
84 ///
85 ///
86 ///
87 ///
88 ///
89 public bool StringSet(string key, T obj, TimeSpan? expiry = default(TimeSpan?))
90 {
91 key = AddSysCustomKey(key);
92 string json = ConvertJson(obj);
93 return Do(db => db.StringSet(key, json, expiry));
94 }
95
96 ///
97 /// 获取单个key的值
98 ///
99 /// Redis Key
100 ///
101 public string StringGet(string key)
102 {
103 key = AddSysCustomKey(key);
104 return Do(db => db.StringGet(key));
105 }
106
107 ///
108 /// 获取多个Key
109 ///
110 /// Redis Key集合
111 ///
112 public RedisValue[] StringGet(Liststring> listKey)
113 {
114 Liststring> newKeys = listKey.Select(AddSysCustomKey).ToList();
115 return Do(db => db.StringGet(ConvertRedisKeys(newKeys)));
116 }
117
118 ///
119 /// 获取一个key的对象
120 ///
121 ///
122 ///
123 ///
124 public T StringGet(string key)
125 {
126 key = AddSysCustomKey(key);
127 return Do(db => ConvertObj(db.StringGet(key)));
128 }
129
130 ///
131 /// 为数字增长val
132 ///
133 ///
134 /// 可以为负
135 /// 增长后的值
136 public double StringIncrement(string key, double val = 1)
137 {
138 key = AddSysCustomKey(key);
139 return Do(db => db.StringIncrement(key, val));
140 }
141
142 ///
143 /// 为数字减少val
144 ///
145 ///
146 /// 可以为负
147 /// 减少后的值
148 public double StringDecrement(string key, double val = 1)
149 {
150 key = AddSysCustomKey(key);
151 return Do(db => db.StringDecrement(key, val));
152 }
153
154 #endregion 同步方法
155
156 #region 异步方法
157
158 ///
159 /// 保存单个key value
160 ///
161 /// Redis Key
162 /// 保存的值
163 /// 过期时间
164 ///
165 public async Taskbool> StringSetAsync(string key, string value, TimeSpan? expiry = default(TimeSpan?))
166 {
167 key = AddSysCustomKey(key);
168 return await Do(db => db.StringSetAsync(key, value, expiry));
169 }
170
171 ///
172 /// 保存多个key value
173 ///
174 /// 键值对
175 ///
176 public async Taskbool> StringSetAsync(List> keyValues)
177 {
178 List> newkeyValues =
179 keyValues.Select(p => new KeyValuePair(AddSysCustomKey(p.Key), p.Value)).ToList();
180 return await Do(db => db.StringSetAsync(newkeyValues.ToArray()));
181 }
182
183 ///
184 /// 保存一个对象
185 ///
186 ///
187 ///
188 ///
189 ///
190 ///
191 public async Taskbool> StringSetAsync(string key, T obj, TimeSpan? expiry = default(TimeSpan?))
192 {
193 key = AddSysCustomKey(key);
194 string json = ConvertJson(obj);
195 return await Do(db => db.StringSetAsync(key, json, expiry));
196 }
197
198 ///
199 /// 获取单个key的值
200 ///
201 /// Redis Key
202 ///
203 public async Taskstring> StringGetAsync(string key)
204 {
205 key = AddSysCustomKey(key);
206 return await Do(db => db.StringGetAsync(key));
207 }
208
209 ///
210 /// 获取多个Key
211 ///
212 /// Redis Key集合
213 ///
214 public async Task StringGetAsync(Liststring> listKey)
215 {
216 Liststring> newKeys = listKey.Select(AddSysCustomKey).ToList();
217 return await Do(db => db.StringGetAsync(ConvertRedisKeys(newKeys)));
218 }
219
220 ///
221 /// 获取一个key的对象
222 ///
223 ///
224 ///
225 ///
226 public async Task StringGetAsync(string key)
227 {
228 key = AddSysCustomKey(key);
229 string result = await Do(db => db.StringGetAsync(key));
230 return ConvertObj(result);
231 }
232
233 ///
234 /// 为数字增长val
235 ///
236 ///
237 /// 可以为负
238 /// 增长后的值
239 public async Taskdouble> StringIncrementAsync(string key, double val = 1)
240 {
241 key = AddSysCustomKey(key);
242 return await Do(db => db.StringIncrementAsync(key, val));
243 }
244
245 ///
246 /// 为数字减少val
247 ///
248 ///
249 /// 可以为负
250 /// 减少后的值
251 public async Taskdouble> StringDecrementAsync(string key, double val = 1)
252 {
253 key = AddSysCustomKey(key);
254 return await Do(db => db.StringDecrementAsync(key, val));
255 }
256
257 #endregion 异步方法
258
259 #endregion String
260
261 #region Hash
262
263 #region 同步方法
264
265 ///
266 /// 判断某个数据是否已经被缓存
267 ///
268 ///
269 ///
270 ///
271 public bool HashExists(string key, string dataKey)
272 {
273 key = AddSysCustomKey(key);
274 return Do(db => db.HashExists(key, dataKey));
275 }
276
277 ///
278 /// 存储数据到hash表
279 ///
280 ///
281 ///
282 ///
283 ///
284 ///
285 public bool HashSet(string key, string dataKey, T t)
286 {
287 key = AddSysCustomKey(key);
288 return Do(db =>
289 {
290 string json = ConvertJson(t);
291 return db.HashSet(key, dataKey, json);
292 });
293 }
294
295 ///
296 /// 移除hash中的某值
297 ///
298 ///
299 ///
300 ///
301 public bool HashDelete(string key, string dataKey)
302 {
303 key = AddSysCustomKey(key);
304 return Do(db => db.HashDelete(key, dataKey));
305 }
306
307 ///
308 /// 移除hash中的多个值
309 ///
310 ///
311 ///
312 ///
313 public long HashDelete(string key, List dataKeys)
314 {
315 key = AddSysCustomKey(key);
316 return Do(db => db.HashDelete(key, dataKeys.ToArray()));
317 }
318
319 ///
320 /// 从hash表获取数据
321 ///
322 ///
323 ///
324 ///
325 ///
326 public T HashGet(string key, string dataKey)
327 {
328 key = AddSysCustomKey(key);
329 return Do(db =>
330 {
331 string value = db.HashGet(key, dataKey);
332 return ConvertObj(value);
333 });
334 }
335
336 ///
337 /// 从hash表获取数据
338 ///
339 ///
340 ///
341 ///
342 ///
343 public string HashGetString(string key, string dataKey)
344 {
345 key = AddSysCustomKey(key);
346 return Do(db =>
347 {
348 return db.HashGet(key, dataKey);
349 });
350 }
351
352 ///
353 /// 为数字增长val
354 ///
355 ///
356 ///
357 /// 可以为负
358 /// 增长后的值
359 public double HashIncrement(string key, string dataKey, double val = 1)
360 {
361 key = AddSysCustomKey(key);
362 return Do(db => db.HashIncrement(key, dataKey, val));
363 }
364
365 ///
366 /// 为数字减少val
367 ///
368 ///
369 ///
370 /// 可以为负
371 /// 减少后的值
372 public double HashDecrement(string key, string dataKey, double val = 1)
373 {
374 key = AddSysCustomKey(key);
375 return Do(db => db.HashDecrement(key, dataKey, val));
376 }
377
378 ///
379 /// 获取hashkey所有Redis key
380 ///
381 ///
382 ///
383 ///
384 public List HashKeys(string key)
385 {
386 key = AddSysCustomKey(key);
387 return Do(db =>
388 {
389 RedisValue[] values = db.HashKeys(key);
390 return&