阅读目录
前两天朋友问我,有没有使用过StackExchange.Redis,问我要个封装类,由于之前都是使用ServiceStack.Redis,由于ServiceStack.Redis v4版本后是收费版的,所以现在也很有公司都在使用StackExchange.Redis而抛弃ServiceStack.Redis了。其实个人觉得,两个驱动都不错,只是由于ServiceStack.Redis收费导致目前很多公司都是基于V3版本的使用,也有人说V3版本有很多Bug,没有维护和升级,不过至少目前我是没发现Bug。
不过ServiceStack.Redis同StackExchange.Redis比较,抛开收费的来说,确认比StackExchange.Redis 更有优势。StackExchange.Redis文档很少,更不要说国内的文档了,连github上面对应的介绍文档都是很片面,这点我真的觉得StackExchange.Redis的作者至少要完善下文档,很多都是要看源码的例子才有。网上对StackExchange.Redis的使用例子也比ServiceStack.Redis少得多,不是说没人用,只是我查来查去,大部分都是基于String类型的数据进行使用的封装类,对于List,SortedSet,Hash的封装操作都很少,基本都是东写一点,西写一点,很难找到完整的。在参考了一些文章和源码后,这里提供一个自己封装的类,基本提供对于各种类型的使用封装,提供给大家学习使用,如果有哪里写的不好的,大家也可以互相交流。
ConnectionMultiplexer 封装
首先是 ConnectionMultiplexer 的封装,ConnectionMultiplexer对象是StackExchange.Redis最中枢的对象。这个类的实例需要被整个应用程序域共享和重用的,所以不需要在每个操作中不停的创建该对象的实例,一般都是使用单例来创建和存放这个对象,这个在官网上也有说明。
1 /// <summary>
2 /// ConnectionMultiplexer对象管理帮助类
3 /// </summary>
4 public static class RedisConnectionHelp
5 {
6 //系统自定义Key前缀
7 public static readonly string SysCustomKey = ConfigurationManager.AppSettings["redisKey"] ?? "";
8
9 //"127.0.0.1:6379,allowadmin=true
10 private static readonly string RedisConnectionString = ConfigurationManager.ConnectionStrings["RedisExchangeHosts"].ConnectionString;
11
12 private static readonly object Locker = new object();
13 private static ConnectionMultiplexer _instance;
14 private static readonly ConcurrentDictionary<string, ConnectionMultiplexer> ConnectionCache = new ConcurrentDictionary<string, ConnectionMultiplexer>();
15
16 /// <summary>
17 /// 单例获取
18 /// </summary>
19 public static ConnectionMultiplexer Instance
20 {
21 get
22 {
23 if (_instance == null)
24 {
25 lock (Locker)
26 {
27 if (_instance == null || !_instance.IsConnected)
28 {
29 _instance = GetManager();
30 }
31 }
32 }
33 return _instance;
34 }
35 }
36
37 /// <summary>
38 /// 缓存获取
39 /// </summary>
40 /// <param name="connectionString"></param>
41 /// <returns></returns>
42 public static ConnectionMultiplexer GetConnectionMultiplexer(string connectionString)
43 {
44 if (!ConnectionCache.ContainsKey(connectionString))
45 {
46 ConnectionCache[connectionString] = GetManager(connectionString);
47 }
48 return ConnectionCache[connectionString];
49 }
50
51 private static ConnectionMultiplexer GetManager(string connectionString = null)
52 {
53 connectionString = connectionString ?? RedisConnectionString;
54 var connect = ConnectionMultiplexer.Connect(connectionString);
55
56 //注册如下事件
57 connect.ConnectionFailed += MuxerConnectionFailed;
58 connect.ConnectionRestored += MuxerConnectionRestored;
59 connect.ErrorMessage += MuxerErrorMessage;
60 connect.ConfigurationChanged += MuxerConfigurationChanged;
61 connect.HashSlotMoved += MuxerHashSlotMoved;
62 connect.InternalError += MuxerInternalError;
63
64 return connect;
65 }
66
67 #region 事件
68
69 /// <summary>
70 /// 配置更改时
71 /// </summary>
72 /// <param name="sender"></param>
73 /// <param name="e"></param>
74 private static void MuxerConfigurationChanged(object sender, EndPointEventArgs e)
75 {
76 Console.WriteLine("Configuration changed: " + e.EndPoint);
77 }
78
79 /// <summary>
80 /// 发生错误时
81 /// </summary>
82 /// <param name="sender"></param>
83 /// <param name="e"></param>
84 private static void MuxerErrorMessage(object sender, RedisErrorEventArgs e)
85 {
86 Console.WriteLine("ErrorMessage: " + e.Message);
87 }
88
89 /// <summary>
90 /// 重新建立连接之前的错误
91 /// </summary>
92 /// <param name="sender"></param>
93 /// <param name="e"></param>
94 private static void MuxerConnectionRestored(object sender, ConnectionFailedEventArgs e)
95 {
96 Console.WriteLine("ConnectionRestored: " + e.EndPoint);
97 }
98
99 /// <summary>
100 /// 连接失败 , 如果重新连接成功你将不会收到这个通知
101 /// </summary>
102 /// <param name="sender"></param>
103 /// <param name="e"></param>
104 private static void MuxerConnectionFailed(object sender, ConnectionFailedEventArgs e)
105 {
106 Console.WriteLine("重新连接:Endpoint failed: " + e.EndPoint + ", " + e.FailureType + (e.Exception == null ? "" : (", " + e.Exception.Message)));
107 }
108
109 /// <summary>
110 /// 更改集群
111 /// </summary>
112 /// <param name="sender"></param>
113 /// <param name="e"></param>
114 private static void MuxerHashSlotMoved(object sender, HashSlotMovedEventArgs e)
115 {
116 Console.WriteLine("HashSlotMoved:NewEndPoint" + e.NewEndPoint + ", OldEndPoint" + e.OldEndPoint);
117 }
118
119 /// <summary>
120 /// redis类库错误
121 /// </summary>
122 /// <param name="sender"></param>
123 /// <param name="e"></param>
124 private static void MuxerInternalError(object sender, InternalErrorEventArgs e)
125 {
126 Console.WriteLine("InternalError:Message" + e.Exception.Message);
127 }
128
129 #endregion 事件
130 }